ref: 207f8c591b3e831f4a35185b99482cfb34fccf4b
dir: /test.c/
#include <u.h> #include <libc.h> #include <bio.h> typedef struct Ctx Ctx; typedef struct Range Range; struct Ctx { Biobuf *f; Range *r; u8int *buf; int bufsz; int off; }; struct Range { int start; int len; int prevoff; Range *par; }; int ctxpushrange(Ctx *ctx, int off, int len) { Range *r; int x; r = nil; if(ctx->r != nil){ if(off+len > ctx->r->len){ werrstr("range overflow by %d bytes", off+len - ctx->r->len); goto err; } off += ctx->r->start; } if((r = malloc(sizeof(*r))) == nil){ werrstr("no memory"); goto err; } r->par = ctx->r; r->start = off; r->len = len; r->prevoff = ctx->off; if((x = Bseek(ctx->f, off, 0)) != off){ werrstr("seek offset: need %d, got %d", off, x); goto err; } ctx->off = off; ctx->r = r; return 0; err: free(r); werrstr("ctxpushrange: %r"); return -1; } int ctxpoprange(Ctx *ctx) { Range *r; int x; r = ctx->r; if(r == nil){ werrstr("pop without push"); goto err; } if((x = Bseek(ctx->f, r->prevoff, 0)) != r->prevoff){ werrstr("seek offset: need %d, got %d", r->prevoff, x); goto err; } ctx->off = r->prevoff; ctx->r = r->par; free(r); return 0; err: werrstr("ctxpoprange: %r"); return -1; } u8int * ctxreadn(Ctx *ctx, int n) { Range *r; u8int *b; int x; r = ctx->r; if(r != nil && ctx->off+n > r->start+r->len){ werrstr("short read: need %d at %d, have %d at %d", n, ctx->off, r->len, r->start); goto err; } if(n > ctx->bufsz){ if((b = realloc(ctx->buf, n)) == nil){ werrstr("no memory"); goto err; } ctx->buf = b; ctx->bufsz = n; } if((x = Bread(ctx->f, ctx->buf, n)) != n){ werrstr("short read: need %d, got %d; off %d", n, x, ctx->off); goto err; } ctx->off += n; return ctx->buf; err: werrstr("ctxreadn: %r"); return nil; } int ctxarray(Ctx *ctx, void **arr_, void *fun_, int elsz, int num) { int i; int (*fun)(Ctx*, void*); u8int *arr; if((arr = calloc(num, elsz)) == nil){ werrstr("no memory"); goto err; } fun = fun_; for(i = 0; i < num; i++){ if(fun(ctx, arr + i*elsz) < 0) goto err; } *arr_ = arr; return 0; err: free(arr); werrstr("ctxarray: %r"); return -1; } #include "out.h" void main(int argc, char **argv) { TableDirectory td; Biobuf *out; Ctx ctx; int i; otfinit(); out = Bfdopen(1, OWRITE); for(i = 1; i < argc; i++){ Bprint(out, "%s\n", argv[i]); if((ctx.f = Bopen(argv[i], OREAD)) == nil){ fprint(2, "%r\n"); }else if(read_TableDirectory(&ctx, &td) != 0){ fprint(2, "%s: %r\n", argv[i]); } else { print_TableDirectory(out, 0, &td); } if(ctx.f != nil) Bterm(ctx.f); } Bterm(out); exits(nil); }