int readExtents()

in hfs/rawfile.c [406:477]


int readExtents(RawFile* rawFile) {
	uint32_t blocksLeft;
	HFSPlusForkData* forkData;
	uint32_t currentBlock;

	Extent* extent;
	Extent* lastExtent;

	HFSPlusExtentDescriptor* descriptor;
	int currentExtent;
	HFSPlusExtentKey extentKey;
	int exact;

	extentKey.keyLength = sizeof(HFSPlusExtentKey) - sizeof(extentKey.keyLength);
	extentKey.forkType = 0;
	extentKey.fileID = rawFile->id;

	forkData = rawFile->forkData;
	blocksLeft = forkData->totalBlocks;
	currentExtent = 0;
	currentBlock = 0;
	descriptor = (HFSPlusExtentDescriptor*) forkData->extents;

	lastExtent = NULL;

	while(blocksLeft > 0) {
		extent = (Extent*) malloc(sizeof(Extent));

		if(currentExtent == 8) {
			if(rawFile->volume->extentsTree == NULL) {
				hfs_panic("no extents overflow file loaded yet!");
				return FALSE;
			}

			if(descriptor != ((HFSPlusExtentDescriptor*) forkData->extents)) {
				free(descriptor);
			}

			extentKey.startBlock = currentBlock;
			descriptor = (HFSPlusExtentDescriptor*) search(rawFile->volume->extentsTree, (BTKey*)(&extentKey), &exact, NULL, NULL);
			if(descriptor == NULL || exact == FALSE) {
				hfs_panic("inconsistent extents information!");
				return FALSE;
			} else {
				currentExtent = 0;
				continue;
			}
		}

		extent->startBlock = descriptor[currentExtent].startBlock;
		extent->blockCount = descriptor[currentExtent].blockCount;
		extent->next = NULL;

		currentBlock += extent->blockCount;
		blocksLeft -= extent->blockCount;
		currentExtent++;

		if(lastExtent == NULL) {
			rawFile->extents = extent;
		} else {
			lastExtent->next = extent;
		}

		lastExtent = extent;
	}

	if(descriptor != ((HFSPlusExtentDescriptor*) forkData->extents)) {
		free(descriptor);
	}

	return TRUE;
}