/* * NAME: hfs->read() * DESCRIPTION: read from an open file */ unsigned long hfs_read(hfsfile *file, void *buf, unsigned long len) { unsigned long *lglen, count; byte *ptr = buf; f_getptrs(file, NULL, &lglen, NULL); if (file->pos + len > *lglen) len = *lglen - file->pos; count = len; while (count) { unsigned long bnum, offs, chunk; bnum = file->pos >> HFS_BLOCKSZ_BITS; offs = file->pos & (HFS_BLOCKSZ - 1); chunk = HFS_BLOCKSZ - offs; if (chunk > count) chunk = count; if (offs == 0 && chunk == HFS_BLOCKSZ) { if (f_getblock(file, bnum, (block *) ptr) == -1) goto fail; } else { block b; if (f_getblock(file, bnum, &b) == -1) goto fail; memcpy(ptr, b + offs, chunk); } ptr += chunk; file->pos += chunk; count -= chunk; } return len; fail: return -1; }
/* * NAME: hfs->read() * DESCRIPTION: read from an open file */ long hfs_read(hfsfile *file, void *buf, unsigned long len) { unsigned long *lglen, count; unsigned char *ptr = buf; f_getptrs(file, &lglen, 0, 0); if (file->pos + len > *lglen) len = *lglen - file->pos; count = len; while (count) { block b; unsigned long bnum, offs, chunk; bnum = file->pos / HFS_BLOCKSZ; offs = file->pos % HFS_BLOCKSZ; chunk = HFS_BLOCKSZ - offs; if (chunk > count) chunk = count; if (f_getblock(file, bnum, &b) < 0) return -1; memcpy(ptr, b + offs, chunk); ptr += chunk; file->pos += chunk; count -= chunk; } return len; }
/* * NAME: hfs->write() * DESCRIPTION: write to an open file */ unsigned long hfs_write(hfsfile *file, const void *buf, unsigned long len) { unsigned long *lglen, *pylen, count; const byte *ptr = buf; if (file->vol->flags & HFS_VOL_READONLY) ERROR(EROFS, 0); f_getptrs(file, 0, &lglen, &pylen); count = len; /* set flag to update (at least) the modification time */ if (count) { file->cat.u.fil.filMdDat = d_mtime(time(0)); file->flags |= HFS_FILE_UPDATE_CATREC; } while (count) { unsigned long bnum, offs, chunk; bnum = file->pos >> HFS_BLOCKSZ_BITS; offs = file->pos & (HFS_BLOCKSZ - 1); chunk = HFS_BLOCKSZ - offs; if (chunk > count) chunk = count; if (file->pos + chunk > *pylen) { if (bt_space(&file->vol->ext, 1) == -1 || f_alloc(file) == -1) goto fail; } if (offs == 0 && chunk == HFS_BLOCKSZ) { if (f_putblock(file, bnum, (block *) ptr) == -1) goto fail; } else { block b; if (f_getblock(file, bnum, &b) == -1) goto fail; memcpy(b + offs, ptr, chunk); if (f_putblock(file, bnum, &b) == -1) goto fail; } ptr += chunk; file->pos += chunk; count -= chunk; if (file->pos > *lglen) *lglen = file->pos; } return len; fail: return -1; }
/* * NAME: hfs->write() * DESCRIPTION: write to an open file */ long hfs_write(hfsfile *file, void *buf, unsigned long len) { unsigned long *lglen, *pylen, count; unsigned char *ptr = buf; if (file->vol->flags & HFS_READONLY) { ERROR(EROFS, 0); return -1; } f_getptrs(file, &lglen, &pylen, 0); count = len; /* set flag to update (at least) the modification time */ if (count) { file->cat.u.fil.filMdDat = d_tomtime(/*time*/(0)); file->flags |= HFS_UPDATE_CATREC; } while (count) { block b; unsigned long bnum, offs, chunk; bnum = file->pos / HFS_BLOCKSZ; offs = file->pos % HFS_BLOCKSZ; chunk = HFS_BLOCKSZ - offs; if (chunk > count) chunk = count; if (file->pos + chunk > *pylen) { if (bt_space(&file->vol->ext, 1) < 0 || f_alloc(file) < 0) return -1; } if (offs > 0 || chunk < HFS_BLOCKSZ) { if (f_getblock(file, bnum, &b) < 0) return -1; } memcpy(b + offs, ptr, chunk); ptr += chunk; if (f_putblock(file, bnum, &b) < 0) return -1; file->pos += chunk; count -= chunk; if (file->pos > *lglen) *lglen = file->pos; } return len; }