~ft/pdffs

7848f6493fbae545088432575e801baad8ea879d — Sigrid Solveig Haflínudóttir 8 months ago 5949d53
add "xref" eval (prints xref table); add "#<offset>" eval (prints an object at the offset within the file)
3 files changed, 44 insertions(+), 6 deletions(-)

M eval.c
M main.c
M pdf.h
M eval.c => eval.c +27 -3
@@ 63,6 63,30 @@ err:
}

Object *
pdfevaloff(Object *o, int off)
{
	Object *d;

	if(o == nil)
		return &null;
	if(o->type != Oindir)
		return o;
	if(o->indir.o != nil)
		return o->indir.o;

	if(Sseek(o->pdf->s, off, 0) != off){
		werrstr("evaloff: seek failed");
		return &null;
	}
	if((d = pdfobj(o->pdf, o->pdf->s, 0)) == nil){
		werrstr("evaloff: %r [at %p]", (void*)off);
		return &null;
	}
	o->indir.o = d;
	return d;
}

Object *
pdfeval(Object *o)
{
	Object *d;


@@ 82,18 106,18 @@ pdfeval(Object *o)
			break;
	}
	if(i >= o->pdf->nxref){
		werrstr("no object id %d in xref", o->indir.id);
		werrstr("eval: no object id %d in xref", o->indir.id);
		return &null;
	}
	if(x->objstm > 0){
		if((d = evalobjstm(o->pdf, x)) == &null)
			werrstr("ObjStm: %r");
			werrstr("eval: ObjStm: %r");
		o->indir.o = d;
		return d;
	}

	if(Sseek(o->pdf->s, x->off, 0) != x->off){
		werrstr("xref seek failed");
		werrstr("eval: xref seek failed");
		return &null;
	}
	if((d = pdfobj(o->pdf, o->pdf->s, 0)) == nil){

M main.c => main.c +11 -3
@@ 140,10 140,18 @@ threadmain(int argc, char **argv)
			o.pdf = pdf;
			o.type = Oindir;
			o.indir.id = atoi(argv[i]+1);
			if((v = pdfeval(&o)) == nil){
				v = &null;
			if((v = pdfeval(&o)) == &null)
				break;
			}
		}else if(argv[i][0] == '#' && isdigit(argv[i][1])){
			memset(&o, 0, sizeof(o));
			o.ref = 1;
			o.pdf = pdf;
			o.type = Oindir;
			if((v = pdfevaloff(&o, atoi(argv[i]+1))) == &null)
				break;
		}else if(i == 1 && strcmp(argv[i], "xref") == 0){
			for(n = 0; n < pdf->nxref; n++)
				print("%08d %⊗\n", n, pdf->xref[n]);
		}else{
			v = dictget(v, argv[i]);
		}

M pdf.h => pdf.h +6 -0
@@ 219,6 219,12 @@ enum {
void pdfobjfree(Object *o);

/*
 * Return an object from the offset within the file or &null if
 * can't. Object must be marked indirect.
 */
Object *pdfevaloff(Object *o, int off);

/*
 * Return a resolved object or &null if can't. Operation is
 * not recursive, ie values of a dictionary won't be resolved
 * automatically.