ref: df075d407417a84a3dacf44044fd0907b295f39e
parent: 1d93500ddcda77cd265d492c6c9094c0f5c7488f
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Sat Aug 29 19:15:19 EDT 2020
make pdfeval update the pointer; add a dumb ref counter to objects
--- a/dict.c
+++ b/dict.c
@@ -70,12 +70,12 @@
{
int i;
- o = pdfeval(o);
+ pdfeval(&o);
if((o->type != Ostream && o->type != Odict) || name == nil)
return &null;
for(i = 0; i < o->dict.nkv && strcmp(name, o->dict.kv[i].key) != 0; i++);
- return pdfeval(i < o->dict.nkv ? o->dict.kv[i].value : &null);
+ return pdfeval(i < o->dict.nkv ? &o->dict.kv[i].value : nil);
}
vlong
--- a/eval.c
+++ b/eval.c
@@ -4,14 +4,15 @@
#include "pdf.h"
Object *
-pdfeval(Object *o)
+pdfeval(Object **oo)
{
- Object *d;
+ Object *d, *o;
Xref *x;
int i;
- if(o == nil)
+ if(oo == nil || *oo == nil)
return &null;
+ o = *oo;
if(o->type != Oindir)
return o;
@@ -28,7 +29,7 @@
}
if((d = pdfobj(o->pdf, o->pdf->bio)) == nil)
return &null;
-
+ *oo = d;
pdfobjfree(o);
return d;
--- a/name.c
+++ b/name.c
@@ -55,11 +55,10 @@
s[sz++] = c;
}
- if((o = malloc(sizeof(*o) + sz + 1)) != nil){
- memmove(o->name, s, sz);
- o->name[sz] = 0;
+ if((o = malloc(sizeof(*o))) != nil){
+ o->name = s;
+ s[sz] = 0;
o->type = Oname;
- free(s);
return o;
}
--- a/object.c
+++ b/object.c
@@ -194,7 +194,7 @@
{
int i;
- if(o == nil)
+ if(o == nil || --o->ref >= 0)
return;
switch(o->type){
@@ -201,12 +201,15 @@
case Onull:
return;
- case Obool:
- case Onum:
case Ostr:
case Oname:
+ free(o->str);
break;
+ case Obool:
+ case Onum:
+ break;
+
case Oarray:
for(i = 0; i < o->array.ne; i++)
pdfobjfree(o->array.e[i]);
@@ -227,4 +230,11 @@
}
free(o);
+}
+
+Object *
+pdfref(Object *o)
+{
+ o->ref++;
+ return o;
}
--- a/pdf.c
+++ b/pdf.c
@@ -85,17 +85,10 @@
goto err;
}
- pdf->root = dictget(o, "Root");
- pdf->info = dictget(o, "Info");
+ pdf->root = pdfref(dictget(o, "Root"));
+ pdf->info = pdfref(dictget(o, "Info"));
pdfobjfree(o);
- o = nil;
- /* root is required, info is optional */
- if(pdf->root == nil){
- werrstr("no root");
- goto err;
- }
-
return 0;
err:
pdfobjfree(o);
@@ -203,8 +196,12 @@
pdf->root = dictget(o, "Root");
pdf->info = dictget(o, "Info");
}
- fprint(2, "root %T\n", pdf->root);
- fprint(2, "info %T\n", pdf->info);
+
+ /* root is required, info is optional */
+ if(pdf->root == nil){
+ werrstr("no root");
+ goto err;
+ }
return pdf;
err:
--- a/pdf.h
+++ b/pdf.h
@@ -30,15 +30,16 @@
struct Object {
int type;
+ int ref;
Pdf *pdf;
union {
int bool;
double num;
struct {
+ char *str;
int len;
- char str[1];
};
- char name[1];
+ char *name;
struct {
u32int id;
@@ -102,7 +103,9 @@
* not recursive, ie values of a dictionary won't be resolved
* automatically.
*/
-Object *pdfeval(Object *o);
+Object *pdfeval(Object **o);
+
+Object *pdfref(Object *o);
int isws(int c);
int isdelim(int c);
--- a/stream.c
+++ b/stream.c
@@ -23,7 +23,7 @@
int i, nflts;
s = nil;
- if(pdfeval(o)->type != Ostream) /* FIXME open a string object as a stream as well? */
+ if(pdfeval(&o)->type != Ostream) /* FIXME open a string object as a stream as well? */
return nil;
bufinit(&b, nil, 0);
@@ -35,7 +35,7 @@
/* see if there are any filters */
if((of = dictget(o, "Filter")) != nil){
- if(pdfeval(of)->type == Oname){ /* one filter */
+ if(pdfeval(&of)->type == Oname){ /* one filter */
flts = &of;
nflts = 1;
}else if(of->type == Oarray){ /* array of filters */
--- a/string.c
+++ b/string.c
@@ -37,11 +37,12 @@
o = nil;
if(dec16((uchar*)s, n, s+1, len) != n){
werrstr("invalid hex");
- }else if((o = malloc(sizeof(*o) + n + 1)) != nil){
- memmove(o->str, s, n);
- o->str[n] = 0;
+ }else if((o = malloc(sizeof(*o))) != nil){
+ o->str = s;
+ s[n] = 0;
o->len = n;
o->type = Ostr;
+ return o;
}
free(s);
@@ -133,12 +134,11 @@
goto err;
}
- if(c >= 0 && (o = malloc(sizeof(*o) + sz + 1)) != nil){
- memmove(o->str, s, sz);
- o->str[sz] = 0;
+ if(c >= 0 && (o = malloc(sizeof(*o))) != nil){
+ s[sz] = 0;
+ o->str = s;
o->len = sz;
o->type = Ostr;
- free(s);
return o;
}