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;
}