void Marker_Mark(Heap *heap, Stack *stack) { while (!Stack_IsEmpty(stack)) { Object *object = Stack_Pop(stack); if (object->rtti->rt.id == __object_array_id) { // remove header and rtti from size size_t size = Object_Size(&object->header) - OBJECT_HEADER_SIZE - WORD_SIZE; size_t nbWords = size / WORD_SIZE; for (int i = 0; i < nbWords; i++) { word_t *field = object->fields[i]; Object *fieldObject = Object_FromMutatorAddress(field); if (heap_isObjectInHeap(heap, fieldObject) && !Object_IsMarked(&fieldObject->header)) { Marker_markObject(heap, stack, fieldObject); } } } else { int64_t *ptr_map = object->rtti->refMapStruct; int i = 0; while (ptr_map[i] != LAST_FIELD_OFFSET) { word_t *field = object->fields[ptr_map[i]]; Object *fieldObject = Object_FromMutatorAddress(field); if (heap_isObjectInHeap(heap, fieldObject) && !Object_IsMarked(&fieldObject->header)) { Marker_markObject(heap, stack, fieldObject); } ++i; } } } StackOverflowHandler_CheckForOverflow(); }
err_type archive_addFile(const char *archiveName, const char *fileName, const uint8_t compression) //!!!онкмше хлемю!!! { FILE *arch, *oldArch; err_type result = ERR_NO; struct stat objInfo; Stack *dirs = NULL; char *tempArchName = NULL; char buffer[_MAX_PATH]; FileName_FS outFileName; File_Header dirHead; if ((archiveName == NULL) || (fileName == NULL)) return ERR_PARAM_INVALID; if ((result = _checkDirAccess(archiveName)) != ERR_NO) return result; _getFileDir(archiveName, buffer); if ((tempArchName = _tempnam(buffer, "sth")) == NULL) return ERR_WRITE_FAILED; if ((arch = fopen(tempArchName, "wb")) == NULL) { free(tempArchName); return ERR_WRITE_FAILED; } if ((oldArch = fopen(archiveName, "rb")) != NULL) { _splitpath(fileName, NULL, NULL, outFileName.shortName.fName, outFileName.shortName.ext); _makepath(buffer, NULL, NULL, outFileName.shortName.fName, outFileName.shortName.ext); result = _copyArchWithoutFile(arch, oldArch, buffer); fclose(oldArch); } else { result = arch_writeMarkerBlock(arch); } if (result != ERR_NO) goto finalization; /*if ((_fseeki64(arch, 0, SEEK_END)) != 0) { result = ERR_WRITE_FAILED; goto finalization; }*/ if ((dirs = Stack_Create()) == NULL) { result = ERR_NOMEM; goto finalization; } if ((result = _getStat(fileName, &objInfo)) != ERR_NO) goto finalization; _splitpath(fileName, outFileName.fullName.drive, outFileName.fullName.dir, outFileName.fullName.fName, outFileName.fullName.ext); _splitpath(fileName, NULL, NULL, outFileName.shortName.fName, outFileName.shortName.ext); outFileName.shortName.drive[0] = 0; outFileName.shortName.dir[0] = 0; if ((objInfo.st_mode & S_IFREG) != 0) { result = _addFile(arch, &outFileName, &objInfo, compression); } else if ((objInfo.st_mode & S_IFDIR) != 0) { if ((result = Stack_Push(dirs, &outFileName)) != ERR_NO) goto finalization; } else { result = ERR_UNKNOWN_FILETYPE; goto finalization; } while (!Stack_IsEmpty(dirs)) { WIN32_FIND_DATAA fileFindData; HANDLE hFind = INVALID_HANDLE_VALUE; Stack_Pop(dirs, &outFileName); _makepath(buffer, outFileName.fullName.drive, outFileName.fullName.dir, outFileName.fullName.fName, outFileName.fullName.ext); if ((result = _getStat(buffer, &objInfo)) != ERR_NO) goto finalization; objInfo.st_size = 0; _makepath(buffer, outFileName.shortName.drive, outFileName.shortName.dir, outFileName.shortName.fName, outFileName.shortName.ext); if ((result = _File_Header_fill(buffer, compression, &dirHead, &objInfo)) != ERR_NO) goto finalization; if ((result = File_Header_fwrite(arch, &dirHead)) != ERR_NO) goto finalization; _makepath(buffer, outFileName.fullName.drive, outFileName.fullName.dir, outFileName.fullName.fName, outFileName.fullName.ext); strcat(buffer, "\\*"); if ((hFind = FindFirstFileA(buffer, &fileFindData)) == INVALID_HANDLE_VALUE) { result = ERR_UNKNOWN; goto finalization; } if (FindNextFileA(hFind, &fileFindData) == 0) { continue; } if (strcmp(fileFindData.cFileName, "..") == 0) if (FindNextFileA(hFind, &fileFindData) == 0) continue; strcat(strcat(strcat(outFileName.fullName.dir, outFileName.fullName.fName), outFileName.fullName.ext), "\\"); strcat(strcat(strcat(outFileName.shortName.dir, outFileName.shortName.fName), outFileName.shortName.ext), "\\"); do { _splitpath(fileFindData.cFileName, NULL, NULL, outFileName.fullName.fName, outFileName.fullName.ext); _splitpath(fileFindData.cFileName, NULL, NULL, outFileName.shortName.fName, outFileName.shortName.ext); _makepath(buffer, outFileName.fullName.drive, outFileName.fullName.dir, outFileName.fullName.fName, outFileName.fullName.ext); if ((result = _getStat(buffer, &objInfo)) != ERR_NO) break; if ((objInfo.st_mode & S_IFREG) != 0) { if ((result = _addFile(arch, &outFileName, &objInfo, compression)) != ERR_NO) break; } else if ((objInfo.st_mode & S_IFDIR) != 0) { if ((result = Stack_Push(dirs, &outFileName)) != ERR_NO) break; } else { result = ERR_UNKNOWN_FILETYPE; break; } } while (FindNextFileA(hFind, &fileFindData) != 0); FindClose(hFind); if (result != ERR_NO) goto finalization; } finalization: fclose(arch); if (result == ERR_NO) { remove(archiveName); rename(tempArchName, archiveName); } else { remove(tempArchName); } free(tempArchName); Stack_Destroy(dirs); return result; }