示例#1
0
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();
}
示例#2
0
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;
}