shithub: pdffs

Download patch

ref: 7848f6493fbae545088432575e801baad8ea879d
parent: 5949d53a09a809482abc6fc4e4db6e8c8266afd0
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Aug 11 14:12:45 EDT 2023

add "xref" eval (prints xref table); add "#<offset>" eval (prints an object at the offset within the file)

--- a/eval.c
+++ b/eval.c
@@ -63,6 +63,30 @@
 }
 
 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 @@
 			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){
--- a/main.c
+++ b/main.c
@@ -140,10 +140,18 @@
 			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]);
 		}
--- a/pdf.h
+++ b/pdf.h
@@ -219,6 +219,12 @@
 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.