static int compressedRead()

in hfs/hfscompress.c [39:85]


static int compressedRead(io_func* io, off_t location, size_t size, void *buffer) {
	HFSPlusCompressed* data = (HFSPlusCompressed*) io->data;
	size_t toRead;

	while(size > 0) {
		if(data->cached && location >= data->cachedStart && location < data->cachedEnd) {
			if((data->cachedEnd - location) < size)
				toRead = data->cachedEnd - location;
			else
				toRead = size;

			memcpy(buffer, data->cached + (location - data->cachedStart), toRead);

			size -= toRead;
			location += toRead;
			buffer = ((uint8_t*) buffer) + toRead;
		}

		if(size == 0)
			break;

		// Try to cache
		uLongf actualSize;
		uint32_t block = location / 0x10000;
		uint8_t* compressed = (uint8_t*) malloc(data->blocks->blocks[block].size);
		if(!READ(data->io, data->rsrcHead.headerSize + sizeof(uint32_t) + data->blocks->blocks[block].offset, data->blocks->blocks[block].size, compressed)) {
			hfs_panic("error reading");
		}

		if(data->cached)
			free(data->cached);

		data->cached = (uint8_t*) malloc(0x10000);
		actualSize = 0x10000;
		if(compressed[0] == 0xff) {
			actualSize = data->blocks->blocks[block].size - 1;
			memcpy(data->cached, compressed + 1, actualSize);
		} else {
			uncompress(data->cached, &actualSize, compressed, data->blocks->blocks[block].size);
		}
		data->cachedStart = block * 0x10000;
		data->cachedEnd = data->cachedStart + actualSize;
		free(compressed);
	}

	return TRUE;
}