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