static off_t bzf_seek(struct open_file *f, off_t offset, int where) { struct bz_file *bzf = (struct bz_file *)f->f_fsdata; off_t target; char discard[16]; switch (where) { case SEEK_SET: target = offset; break; case SEEK_CUR: target = offset + bzf->bzf_bzstream.total_out_lo32; break; default: target = -1; } /* Can we get there from here? */ if (target < bzf->bzf_bzstream.total_out_lo32) { errno = EOFFSET; return -1; } /* skip forwards if required */ while (target > bzf->bzf_bzstream.total_out_lo32) { if (bzf_read(f, discard, min(sizeof(discard), target - bzf->bzf_bzstream.total_out_lo32), NULL) == -1) return(-1); } /* This is where we are (be honest if we overshot) */ return (bzf->bzf_bzstream.total_out_lo32); }
/* Small test case, open and decompress test.bz2 */ int main() { struct open_file f; char buf[1024]; size_t resid; int err; memset(&f, '\0', sizeof(f)); f.f_flags = F_READ; err = bzf_open("test", &f); if (err != 0) exit(1); do { err = bzf_read(&f, buf, sizeof(buf), &resid); } while (err == 0 && resid != sizeof(buf)); if (err != 0) exit(2); exit(0); }