/* ( buf len -- actlen ) */ static void hfsp_files_read( hfsp_info_t *mi ) { int count = POP(); char *buf = (char *)cell2pointer(POP()); hfsp_file_t *t = mi->hfspfile; volume *vol = t->rec.tree->vol; UInt32 blksize = vol->blksize; hfsp_cat_file *file = &t->rec.record.u.file; blockiter iter; char buf2[blksize]; int act_count, curpos=0; blockiter_init( &iter, vol, &file->data_fork, HFSP_EXTENT_DATA, file->id ); while( curpos + blksize < t->pos ) { if( blockiter_next( &iter ) ) { RET ( -1 ); return; } curpos += blksize; } act_count = 0; while( act_count < count ){ UInt32 block = blockiter_curr(&iter); int max = blksize, add = 0, size; if( volume_readinbuf( vol, buf2, block ) ) break; if( curpos < t->pos ){ add += t->pos - curpos; max -= t->pos - curpos; } size = (count-act_count > max)? max : count-act_count; memcpy( (char *)buf + act_count, &buf2[add], size ); curpos += blksize; act_count += size; if( blockiter_next( &iter ) ) break; } t->pos += act_count; RET ( act_count ); }
/* read multiple blocks into given memory. * * returns given pinter or NULL on failure. */ void* volume_readfromfork(volume* vol, void* buf, hfsp_fork_raw* f, UInt32 block, UInt32 count, UInt8 forktype, UInt32 fileId) { blockiter iter; char *cbuf = buf; blockiter_init(&iter, vol, f, forktype, fileId); if( blockiter_skip(&iter, block)) return NULL; while( count > 0) { --count; if( volume_readinbuf(vol, cbuf, blockiter_curr(&iter))) return NULL; cbuf += vol->blksize; if( count > 0 && blockiter_next(&iter)) return NULL; } return buf; }
/* ( addr -- size ) */ static void hfsp_files_load( hfsp_info_t *mi ) { char *buf = (char *)cell2pointer(POP()); hfsp_file_t *t = mi->hfspfile; volume *vol = t->rec.tree->vol; UInt32 blksize = vol->blksize; hfsp_cat_file *file = &t->rec.record.u.file; int total = file->data_fork.total_size; blockiter iter; char buf2[blksize]; int act_count; blockiter_init( &iter, vol, &file->data_fork, HFSP_EXTENT_DATA, file->id ); act_count = 0; while( act_count < total ){ UInt32 block = blockiter_curr(&iter); int max = blksize, size; if( volume_readinbuf( vol, buf2, block ) ) break; size = (total-act_count > max)? max : total-act_count; memcpy( (char *)buf + act_count, &buf2, size ); act_count += size; if( blockiter_next( &iter ) ) break; } RET ( act_count ); }