summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/pdf/pdf-object.c653
1 files changed, 361 insertions, 292 deletions
diff --git a/source/pdf/pdf-object.c b/source/pdf/pdf-object.c
index ecdb1ebb..5711cbaa 100644
--- a/source/pdf/pdf-object.c
+++ b/source/pdf/pdf-object.c
@@ -32,36 +32,69 @@ enum
struct pdf_obj_s
{
- int refs;
+ short refs;
unsigned char kind;
unsigned char flags;
- pdf_document *doc; /* KEEP */
- int parent_num;
+};
+
+typedef struct pdf_obj_num_s
+{
+ pdf_obj super;
union
{
int i;
float f;
- struct {
- unsigned short len;
- char buf[1];
- } s;
- char n[1];
- struct {
- int len;
- int cap;
- pdf_obj **items;
- } a;
- struct {
- int len;
- int cap;
- struct keyval *items;
- } d;
- struct {
- int num;
- int gen;
- } r;
} u;
-};
+} pdf_obj_num;
+
+typedef struct pdf_obj_string_s
+{
+ pdf_obj super;
+ unsigned short len;
+ char buf[1];
+} pdf_obj_string;
+
+typedef struct pdf_obj_name_s
+{
+ pdf_obj super;
+ char n[1];
+} pdf_obj_name;
+
+typedef struct pdf_obj_array_s
+{
+ pdf_obj super;
+ pdf_document *doc;
+ int parent_num;
+ int len;
+ int cap;
+ pdf_obj **items;
+} pdf_obj_array;
+
+typedef struct pdf_obj_dict_s
+{
+ pdf_obj super;
+ pdf_document *doc;
+ int parent_num;
+ int len;
+ int cap;
+ struct keyval *items;
+} pdf_obj_dict;
+
+typedef struct pdf_obj_ref_s
+{
+ pdf_obj super;
+ pdf_document *doc; /* Only needed for arrays, dicts and indirects */
+ int num;
+ int gen;
+} pdf_obj_ref;
+
+#define NAME(obj) ((pdf_obj_name *)(obj))
+#define NUM(obj) ((pdf_obj_num *)(obj))
+#define STRING(obj) ((pdf_obj_string *)(obj))
+#define DICT(obj) ((pdf_obj_dict *)(obj))
+#define ARRAY(obj) ((pdf_obj_array *)(obj))
+#define REF(obj) ((pdf_obj_ref *)(obj))
+
pdf_obj *
pdf_new_null(fz_context *ctx, pdf_document *doc)
@@ -78,45 +111,39 @@ pdf_new_bool(fz_context *ctx, pdf_document *doc, int b)
pdf_obj *
pdf_new_int(fz_context *ctx, pdf_document *doc, int i)
{
- pdf_obj *obj;
- obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(int)");
- obj->doc = doc;
- obj->refs = 1;
- obj->kind = PDF_INT;
- obj->flags = 0;
- obj->parent_num = 0;
+ pdf_obj_num *obj;
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj_num)), "pdf_obj(int)");
+ obj->super.refs = 1;
+ obj->super.kind = PDF_INT;
+ obj->super.flags = 0;
obj->u.i = i;
- return obj;
+ return &obj->super;
}
pdf_obj *
pdf_new_real(fz_context *ctx, pdf_document *doc, float f)
{
- pdf_obj *obj;
- obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(real)");
- obj->doc = doc;
- obj->refs = 1;
- obj->kind = PDF_REAL;
- obj->flags = 0;
- obj->parent_num = 0;
+ pdf_obj_num *obj;
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj_num)), "pdf_obj(real)");
+ obj->super.refs = 1;
+ obj->super.kind = PDF_REAL;
+ obj->super.flags = 0;
obj->u.f = f;
- return obj;
+ return &obj->super;
}
pdf_obj *
pdf_new_string(fz_context *ctx, pdf_document *doc, const char *str, int len)
{
- pdf_obj *obj;
- obj = Memento_label(fz_malloc(ctx, offsetof(pdf_obj, u.s.buf) + len + 1), "pdf_obj(string)");
- obj->doc = doc;
- obj->refs = 1;
- obj->kind = PDF_STRING;
- obj->flags = 0;
- obj->parent_num = 0;
- obj->u.s.len = len;
- memcpy(obj->u.s.buf, str, len);
- obj->u.s.buf[len] = '\0';
- return obj;
+ pdf_obj_string *obj;
+ obj = Memento_label(fz_malloc(ctx, offsetof(pdf_obj_string, buf) + len + 1), "pdf_obj(string)");
+ obj->super.refs = 1;
+ obj->super.kind = PDF_STRING;
+ obj->super.flags = 0;
+ obj->len = len;
+ memcpy(obj->buf, str, len);
+ obj->buf[len] = '\0';
+ return &obj->super;
}
static int
@@ -128,36 +155,33 @@ namecmp(const void *key, const void *name)
pdf_obj *
pdf_new_name(fz_context *ctx, pdf_document *doc, const char *str)
{
- pdf_obj *obj;
+ pdf_obj_name *obj;
char **stdname;
stdname = bsearch(str, &PDF_NAMES[1], PDF_OBJ_ENUM_NAME__LIMIT-1, sizeof(char *), namecmp);
if (stdname != NULL)
return (pdf_obj *)(intptr_t)(stdname - &PDF_NAMES[0]);
- obj = Memento_label(fz_malloc(ctx, offsetof(pdf_obj, u.n) + strlen(str) + 1), "pdf_obj(name)");
- obj->doc = doc;
- obj->refs = 1;
- obj->kind = PDF_NAME;
- obj->flags = 0;
- obj->parent_num = 0;
- strcpy(obj->u.n, str);
- return obj;
+ obj = Memento_label(fz_malloc(ctx, offsetof(pdf_obj_name, n) + strlen(str) + 1), "pdf_obj(name)");
+ obj->super.refs = 1;
+ obj->super.kind = PDF_NAME;
+ obj->super.flags = 0;
+ strcpy(obj->n, str);
+ return &obj->super;
}
pdf_obj *
pdf_new_indirect(fz_context *ctx, pdf_document *doc, int num, int gen)
{
- pdf_obj *obj;
- obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(indirect)");
+ pdf_obj_ref *obj;
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj_ref)), "pdf_obj(indirect)");
+ obj->super.refs = 1;
+ obj->super.kind = PDF_INDIRECT;
+ obj->super.flags = 0;
obj->doc = doc;
- obj->refs = 1;
- obj->kind = PDF_INDIRECT;
- obj->flags = 0;
- obj->parent_num = 0;
- obj->u.r.num = num;
- obj->u.r.gen = gen;
- return obj;
+ obj->num = num;
+ obj->gen = gen;
+ return &obj->super;
}
pdf_obj *
@@ -245,9 +269,9 @@ int pdf_to_int(fz_context *ctx, pdf_obj *obj)
if (obj < PDF_OBJ__LIMIT)
return 0;
if (obj->kind == PDF_INT)
- return obj->u.i;
+ return NUM(obj)->u.i;
if (obj->kind == PDF_REAL)
- return (int)(obj->u.f + 0.5f); /* No roundf in MSVC */
+ return (int)(NUM(obj)->u.f + 0.5f); /* No roundf in MSVC */
return 0;
}
@@ -257,9 +281,9 @@ float pdf_to_real(fz_context *ctx, pdf_obj *obj)
if (obj < PDF_OBJ__LIMIT)
return 0;
if (obj->kind == PDF_REAL)
- return obj->u.f;
+ return NUM(obj)->u.f;
if (obj->kind == PDF_INT)
- return obj->u.i;
+ return NUM(obj)->u.i;
return 0;
}
@@ -272,7 +296,7 @@ char *pdf_to_name(fz_context *ctx, pdf_obj *obj)
return PDF_NAMES[(intptr_t)obj];
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_NAME)
return "";
- return obj->u.n;
+ return NAME(obj)->n;
}
char *pdf_to_str_buf(fz_context *ctx, pdf_obj *obj)
@@ -280,7 +304,7 @@ char *pdf_to_str_buf(fz_context *ctx, pdf_obj *obj)
RESOLVE(obj);
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_STRING)
return "";
- return obj->u.s.buf;
+ return STRING(obj)->buf;
}
int pdf_to_str_len(fz_context *ctx, pdf_obj *obj)
@@ -288,14 +312,14 @@ int pdf_to_str_len(fz_context *ctx, pdf_obj *obj)
RESOLVE(obj);
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_STRING)
return 0;
- return obj->u.s.len;
+ return STRING(obj)->len;
}
void pdf_set_int(fz_context *ctx, pdf_obj *obj, int i)
{
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_INT)
return;
- obj->u.i = i;
+ NUM(obj)->u.i = i;
}
/* for use by pdf_crypt_obj_imp to decrypt AES string in place */
@@ -304,9 +328,9 @@ void pdf_set_str_len(fz_context *ctx, pdf_obj *obj, int newlen)
RESOLVE(obj);
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_STRING)
return; /* This should never happen */
- if (newlen > obj->u.s.len)
+ if (newlen > STRING(obj)->len)
return; /* This should never happen */
- obj->u.s.len = newlen;
+ STRING(obj)->len = newlen;
}
pdf_obj *pdf_to_dict(fz_context *ctx, pdf_obj *obj)
@@ -319,21 +343,21 @@ int pdf_to_num(fz_context *ctx, pdf_obj *obj)
{
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_INDIRECT)
return 0;
- return obj->u.r.num;
+ return REF(obj)->num;
}
int pdf_to_gen(fz_context *ctx, pdf_obj *obj)
{
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_INDIRECT)
return 0;
- return obj->u.r.gen;
+ return REF(obj)->gen;
}
pdf_document *pdf_get_indirect_document(fz_context *ctx, pdf_obj *obj)
{
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_INDIRECT)
return NULL;
- return obj->doc;
+ return REF(obj)->doc;
}
int pdf_objcmp_resolve(fz_context *ctx, pdf_obj *a, pdf_obj *b)
@@ -361,14 +385,14 @@ pdf_objcmp(fz_context *ctx, pdf_obj *a, pdf_obj *b)
if (b->kind != PDF_NAME)
return 1;
- return strcmp(b->u.n, PDF_NAMES[(intptr_t)a]);
+ return strcmp(NAME(b)->n, PDF_NAMES[(intptr_t)a]);
}
if (b < PDF_OBJ_NAME__LIMIT)
{
if (a->kind != PDF_NAME)
return 1;
- return strcmp(a->u.n, PDF_NAMES[(intptr_t)b]);
+ return strcmp(NAME(a)->n, PDF_NAMES[(intptr_t)b]);
}
if (a < PDF_OBJ__LIMIT || b < PDF_OBJ__LIMIT)
@@ -380,54 +404,54 @@ pdf_objcmp(fz_context *ctx, pdf_obj *a, pdf_obj *b)
switch (a->kind)
{
case PDF_INT:
- return a->u.i - b->u.i;
+ return NUM(a)->u.i - NUM(b)->u.i;
case PDF_REAL:
- if (a->u.f < b->u.f)
+ if (NUM(a)->u.f < NUM(b)->u.f)
return -1;
- if (a->u.f > b->u.f)
+ if (NUM(a)->u.f > NUM(b)->u.f)
return 1;
return 0;
case PDF_STRING:
- if (a->u.s.len < b->u.s.len)
+ if (STRING(a)->len < STRING(b)->len)
{
- if (memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len) <= 0)
+ if (memcmp(STRING(a)->buf, STRING(b)->buf, STRING(a)->len) <= 0)
return -1;
return 1;
}
- if (a->u.s.len > b->u.s.len)
+ if (STRING(a)->len > STRING(b)->len)
{
- if (memcmp(a->u.s.buf, b->u.s.buf, b->u.s.len) >= 0)
+ if (memcmp(STRING(a)->buf, STRING(b)->buf, STRING(b)->len) >= 0)
return 1;
return -1;
}
- return memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len);
+ return memcmp(STRING(a)->buf, STRING(b)->buf, STRING(a)->len);
case PDF_NAME:
- return strcmp(a->u.n, b->u.n);
+ return strcmp(NAME(a)->n, NAME(b)->n);
case PDF_INDIRECT:
- if (a->u.r.num == b->u.r.num)
- return a->u.r.gen - b->u.r.gen;
- return a->u.r.num - b->u.r.num;
+ if (REF(a)->num == REF(b)->num)
+ return REF(a)->gen - REF(b)->gen;
+ return REF(a)->num - REF(b)->num;
case PDF_ARRAY:
- if (a->u.a.len != b->u.a.len)
- return a->u.a.len - b->u.a.len;
- for (i = 0; i < a->u.a.len; i++)
- if (pdf_objcmp(ctx, a->u.a.items[i], b->u.a.items[i]))
+ if (ARRAY(a)->len != ARRAY(b)->len)
+ return ARRAY(a)->len - ARRAY(b)->len;
+ for (i = 0; i < ARRAY(a)->len; i++)
+ if (pdf_objcmp(ctx, ARRAY(a)->items[i], ARRAY(b)->items[i]))
return 1;
return 0;
case PDF_DICT:
- if (a->u.d.len != b->u.d.len)
- return a->u.d.len - b->u.d.len;
- for (i = 0; i < a->u.d.len; i++)
+ if (DICT(a)->len != DICT(b)->len)
+ return DICT(a)->len - DICT(b)->len;
+ for (i = 0; i < DICT(a)->len; i++)
{
- if (pdf_objcmp(ctx, a->u.d.items[i].k, b->u.d.items[i].k))
+ if (pdf_objcmp(ctx, DICT(a)->items[i].k, DICT(b)->items[i].k))
return 1;
- if (pdf_objcmp(ctx, a->u.d.items[i].v, b->u.d.items[i].v))
+ if (pdf_objcmp(ctx, DICT(a)->items[i].v, DICT(b)->items[i].v))
return 1;
}
return 0;
@@ -464,70 +488,67 @@ pdf_objkindstr(pdf_obj *obj)
pdf_obj *
pdf_new_array(fz_context *ctx, pdf_document *doc, int initialcap)
{
- pdf_obj *obj;
+ pdf_obj_array *obj;
int i;
- obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(array)");
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj_array)), "pdf_obj(array)");
+ obj->super.refs = 1;
+ obj->super.kind = PDF_ARRAY;
+ obj->super.flags = 0;
obj->doc = doc;
- obj->refs = 1;
- obj->kind = PDF_ARRAY;
- obj->flags = 0;
obj->parent_num = 0;
- obj->u.a.len = 0;
- obj->u.a.cap = initialcap > 1 ? initialcap : 6;
+ obj->len = 0;
+ obj->cap = initialcap > 1 ? initialcap : 6;
fz_try(ctx)
{
- obj->u.a.items = Memento_label(fz_malloc_array(ctx, obj->u.a.cap, sizeof(pdf_obj*)), "pdf_obj(array items)");
+ obj->items = Memento_label(fz_malloc_array(ctx, obj->cap, sizeof(pdf_obj*)), "pdf_obj(array items)");
}
fz_catch(ctx)
{
fz_free(ctx, obj);
fz_rethrow(ctx);
}
- for (i = 0; i < obj->u.a.cap; i++)
- obj->u.a.items[i] = NULL;
+ for (i = 0; i < obj->cap; i++)
+ obj->items[i] = NULL;
- return obj;
+ return &obj->super;
}
static void
-pdf_array_grow(fz_context *ctx, pdf_obj *obj)
+pdf_array_grow(fz_context *ctx, pdf_obj_array *obj)
{
int i;
- int new_cap = (obj->u.a.cap * 3) / 2;
+ int new_cap = (obj->cap * 3) / 2;
- obj->u.a.items = fz_resize_array(ctx, obj->u.a.items, new_cap, sizeof(pdf_obj*));
- obj->u.a.cap = new_cap;
+ obj->items = fz_resize_array(ctx, obj->items, new_cap, sizeof(pdf_obj*));
+ obj->cap = new_cap;
- for (i = obj->u.a.len ; i < obj->u.a.cap; i++)
- obj->u.a.items[i] = NULL;
+ for (i = obj->len ; i < obj->cap; i++)
+ obj->items[i] = NULL;
}
pdf_obj *
pdf_copy_array(fz_context *ctx, pdf_obj *obj)
{
- RESOLVE(obj);
- if (obj)
- {
- pdf_document *doc = obj->doc;
+ pdf_document *doc;
+ pdf_obj *arr;
+ int i;
+ int n;
- pdf_obj *arr;
- int i;
- int n;
+ RESOLVE(obj);
+ if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_ARRAY)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "assert: not an array (%s)", pdf_objkindstr(obj));
- if (obj->kind != PDF_ARRAY)
- fz_warn(ctx, "assert: not an array (%s)", pdf_objkindstr(obj));
+ doc = ARRAY(obj)->doc;
- arr = pdf_new_array(ctx, doc, pdf_array_len(ctx, obj));
- n = pdf_array_len(ctx, obj);
- for (i = 0; i < n; i++)
- pdf_array_push(ctx, arr, pdf_array_get(ctx, obj, i));
+ n = pdf_array_len(ctx, obj);
+ arr = pdf_new_array(ctx, doc, n);
+ for (i = 0; i < n; i++)
+ pdf_array_push(ctx, arr, pdf_array_get(ctx, obj, i));
- return arr;
- }
- return NULL; /* Can't warn :( */
+ return arr;
}
int
@@ -536,7 +557,7 @@ pdf_array_len(fz_context *ctx, pdf_obj *obj)
RESOLVE(obj);
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_ARRAY)
return 0;
- return obj->u.a.len;
+ return ARRAY(obj)->len;
}
pdf_obj *
@@ -545,20 +566,41 @@ pdf_array_get(fz_context *ctx, pdf_obj *obj, int i)
RESOLVE(obj);
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_ARRAY)
return NULL;
- if (i < 0 || i >= obj->u.a.len)
+ if (i < 0 || i >= ARRAY(obj)->len)
return NULL;
- return obj->u.a.items[i];
+ return ARRAY(obj)->items[i];
}
static void object_altered(fz_context *ctx, pdf_obj *obj, pdf_obj *val)
{
- pdf_document *doc = obj->doc;
+ pdf_document *doc;
+ int parent;
/*
+ obj should be a dict or an array. We don't care about
+ any other types, as they aren't 'containers'.
+ */
+ if (obj < PDF_OBJ__LIMIT)
+ return;
+
+ switch (obj->kind)
+ {
+ case PDF_DICT:
+ doc = DICT(obj)->doc;
+ parent = DICT(obj)->parent_num;
+ break;
+ case PDF_ARRAY:
+ doc = ARRAY(obj)->doc;
+ parent = ARRAY(obj)->parent_num;
+ break;
+ default:
+ return;
+ }
+ /*
parent_num = 0 while an object is being parsed from the file.
No further action is necessary.
*/
- if (obj->parent_num == 0 || doc->freeze_updates)
+ if (parent == 0 || doc->freeze_updates)
return;
/*
@@ -566,8 +608,8 @@ static void object_altered(fz_context *ctx, pdf_obj *obj, pdf_obj *val)
has been moved to the incremental xref section and the newly linked
object needs to record the parent_num
*/
- pdf_xref_ensure_incremental_object(ctx, doc, obj->parent_num);
- pdf_set_obj_parent(ctx, val, obj->parent_num);
+ pdf_xref_ensure_incremental_object(ctx, doc, parent);
+ pdf_set_obj_parent(ctx, val, parent);
}
void
@@ -580,12 +622,12 @@ pdf_array_put(fz_context *ctx, pdf_obj *obj, int i, pdf_obj *item)
fz_warn(ctx, "assert: not an array (%s)", pdf_objkindstr(obj));
else if (i < 0)
fz_warn(ctx, "assert: index %d < 0", i);
- else if (i >= obj->u.a.len)
- fz_warn(ctx, "assert: index %d > length %d", i, obj->u.a.len);
+ else if (i >= ARRAY(obj)->len)
+ fz_warn(ctx, "assert: index %d > length %d", i, ARRAY(obj)->len);
else
{
- pdf_drop_obj(ctx, obj->u.a.items[i]);
- obj->u.a.items[i] = pdf_keep_obj(ctx, item);
+ pdf_drop_obj(ctx, ARRAY(obj)->items[i]);
+ ARRAY(obj)->items[i] = pdf_keep_obj(ctx, item);
}
object_altered(ctx, obj, item);
@@ -610,10 +652,10 @@ pdf_array_push(fz_context *ctx, pdf_obj *obj, pdf_obj *item)
fz_warn(ctx, "assert: not an array (%s)", pdf_objkindstr(obj));
else
{
- if (obj->u.a.len + 1 > obj->u.a.cap)
- pdf_array_grow(ctx, obj);
- obj->u.a.items[obj->u.a.len] = pdf_keep_obj(ctx, item);
- obj->u.a.len++;
+ if (ARRAY(obj)->len + 1 > ARRAY(obj)->cap)
+ pdf_array_grow(ctx, ARRAY(obj));
+ ARRAY(obj)->items[ARRAY(obj)->len] = pdf_keep_obj(ctx, item);
+ ARRAY(obj)->len++;
}
object_altered(ctx, obj, item);
@@ -646,13 +688,13 @@ pdf_array_insert(fz_context *ctx, pdf_obj *obj, pdf_obj *item, int i)
fz_warn(ctx, "assert: not an array (%s)", pdf_objkindstr(obj));
else
{
- if (i < 0 || i > obj->u.a.len)
- fz_throw(ctx, FZ_ERROR_GENERIC, "attempt to insert object %d in array of length %d", i, obj->u.a.len);
- if (obj->u.a.len + 1 > obj->u.a.cap)
- pdf_array_grow(ctx, obj);
- memmove(obj->u.a.items + i + 1, obj->u.a.items + i, (obj->u.a.len - i) * sizeof(pdf_obj*));
- obj->u.a.items[i] = pdf_keep_obj(ctx, item);
- obj->u.a.len++;
+ if (i < 0 || i > ARRAY(obj)->len)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "attempt to insert object %d in array of length %d", i, ARRAY(obj)->len);
+ if (ARRAY(obj)->len + 1 > ARRAY(obj)->cap)
+ pdf_array_grow(ctx, ARRAY(obj));
+ memmove(ARRAY(obj)->items + i + 1, ARRAY(obj)->items + i, (ARRAY(obj)->len - i) * sizeof(pdf_obj*));
+ ARRAY(obj)->items[i] = pdf_keep_obj(ctx, item);
+ ARRAY(obj)->len++;
}
object_altered(ctx, obj, item);
@@ -685,10 +727,10 @@ pdf_array_delete(fz_context *ctx, pdf_obj *obj, int i)
fz_warn(ctx, "assert: not an array (%s)", pdf_objkindstr(obj));
else
{
- pdf_drop_obj(ctx, obj->u.a.items[i]);
- obj->u.a.items[i] = 0;
- obj->u.a.len--;
- memmove(obj->u.a.items + i, obj->u.a.items + i + 1, (obj->u.a.len - i) * sizeof(pdf_obj*));
+ pdf_drop_obj(ctx, ARRAY(obj)->items[i]);
+ ARRAY(obj)->items[i] = 0;
+ ARRAY(obj)->len--;
+ memmove(ARRAY(obj)->items + i, ARRAY(obj)->items + i + 1, (ARRAY(obj)->len - i) * sizeof(pdf_obj*));
}
}
return; /* Can't warn :( */
@@ -813,14 +855,14 @@ static int keyvalcmp(const void *ap, const void *bp)
if (a->k < PDF_OBJ_NAME__LIMIT)
an = PDF_NAMES[(intptr_t)a->k];
else if (a->k >= PDF_OBJ__LIMIT && a->k->kind == PDF_NAME)
- an = a->k->u.n;
+ an = NAME(a->k)->n;
else
return 0;
if (b->k < PDF_OBJ_NAME__LIMIT)
bn = PDF_NAMES[(intptr_t)b->k];
else if (b->k >= PDF_OBJ__LIMIT && b->k->kind == PDF_NAME)
- bn = b->k->u.n;
+ bn = NAME(b->k)->n;
else
return 0;
@@ -830,50 +872,50 @@ static int keyvalcmp(const void *ap, const void *bp)
pdf_obj *
pdf_new_dict(fz_context *ctx, pdf_document *doc, int initialcap)
{
- pdf_obj *obj;
+ pdf_obj_dict *obj;
int i;
- obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(dict)");
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj_dict)), "pdf_obj(dict)");
+ obj->super.refs = 1;
+ obj->super.kind = PDF_DICT;
+ obj->super.flags = 0;
obj->doc = doc;
- obj->refs = 1;
- obj->kind = PDF_DICT;
- obj->flags = 0;
obj->parent_num = 0;
- obj->u.d.len = 0;
- obj->u.d.cap = initialcap > 1 ? initialcap : 10;
+ obj->len = 0;
+ obj->cap = initialcap > 1 ? initialcap : 10;
fz_try(ctx)
{
- obj->u.d.items = Memento_label(fz_malloc_array(ctx, obj->u.d.cap, sizeof(struct keyval)), "pdf_obj(dict items)");
+ DICT(obj)->items = Memento_label(fz_malloc_array(ctx, DICT(obj)->cap, sizeof(struct keyval)), "pdf_obj(dict items)");
}
fz_catch(ctx)
{
fz_free(ctx, obj);
fz_rethrow(ctx);
}
- for (i = 0; i < obj->u.d.cap; i++)
+ for (i = 0; i < DICT(obj)->cap; i++)
{
- obj->u.d.items[i].k = NULL;
- obj->u.d.items[i].v = NULL;
+ DICT(obj)->items[i].k = NULL;
+ DICT(obj)->items[i].v = NULL;
}
- return obj;
+ return &obj->super;
}
static void
pdf_dict_grow(fz_context *ctx, pdf_obj *obj)
{
int i;
- int new_cap = (obj->u.d.cap * 3) / 2;
+ int new_cap = (DICT(obj)->cap * 3) / 2;
- obj->u.d.items = fz_resize_array(ctx, obj->u.d.items, new_cap, sizeof(struct keyval));
- obj->u.d.cap = new_cap;
+ DICT(obj)->items = fz_resize_array(ctx, DICT(obj)->items, new_cap, sizeof(struct keyval));
+ DICT(obj)->cap = new_cap;
- for (i = obj->u.d.len; i < obj->u.d.cap; i++)
+ for (i = DICT(obj)->len; i < DICT(obj)->cap; i++)
{
- obj->u.d.items[i].k = NULL;
- obj->u.d.items[i].v = NULL;
+ DICT(obj)->items[i].k = NULL;
+ DICT(obj)->items[i].v = NULL;
}
}
@@ -886,7 +928,7 @@ pdf_copy_dict(fz_context *ctx, pdf_obj *obj)
RESOLVE(obj);
if (obj >= PDF_OBJ__LIMIT)
{
- pdf_document *doc = obj->doc;
+ pdf_document *doc = DICT(obj)->doc;
if (obj->kind != PDF_DICT)
fz_warn(ctx, "assert: not a dict (%s)", pdf_objkindstr(obj));
@@ -907,7 +949,7 @@ pdf_dict_len(fz_context *ctx, pdf_obj *obj)
RESOLVE(obj);
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_DICT)
return 0;
- return obj->u.d.len;
+ return DICT(obj)->len;
}
pdf_obj *
@@ -916,9 +958,9 @@ pdf_dict_get_key(fz_context *ctx, pdf_obj *obj, int i)
RESOLVE(obj);
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_DICT)
return NULL;
- if (i < 0 || i >= obj->u.d.len)
+ if (i < 0 || i >= DICT(obj)->len)
return NULL;
- return obj->u.d.items[i].k;
+ return DICT(obj)->items[i].k;
}
pdf_obj *
@@ -927,9 +969,9 @@ pdf_dict_get_val(fz_context *ctx, pdf_obj *obj, int i)
RESOLVE(obj);
if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_DICT)
return NULL;
- if (i < 0 || i >= obj->u.d.len)
+ if (i < 0 || i >= DICT(obj)->len)
return NULL;
- return obj->u.d.items[i].v;
+ return DICT(obj)->items[i].v;
}
void
@@ -941,25 +983,25 @@ pdf_dict_put_val_drop(fz_context *ctx, pdf_obj *obj, int i, pdf_obj *new_obj)
pdf_drop_obj(ctx, new_obj);
return;
}
- if (i < 0 || i >= obj->u.d.len)
+ if (i < 0 || i >= DICT(obj)->len)
{
/* FIXME: Should probably extend the dict here */
pdf_drop_obj(ctx, new_obj);
return;
}
- pdf_drop_obj(ctx, obj->u.d.items[i].v);
- obj->u.d.items[i].v = new_obj;
+ pdf_drop_obj(ctx, DICT(obj)->items[i].v);
+ DICT(obj)->items[i].v = new_obj;
}
static int
pdf_dict_finds(fz_context *ctx, pdf_obj *obj, const char *key, int *location)
{
- if ((obj->flags & PDF_FLAGS_SORTED) && obj->u.d.len > 0)
+ if ((obj->flags & PDF_FLAGS_SORTED) && DICT(obj)->len > 0)
{
int l = 0;
- int r = obj->u.d.len - 1;
+ int r = DICT(obj)->len - 1;
- if (strcmp(pdf_to_name(ctx, obj->u.d.items[r].k), key) < 0)
+ if (strcmp(pdf_to_name(ctx, DICT(obj)->items[r].k), key) < 0)
{
if (location)
*location = r + 1;
@@ -969,7 +1011,7 @@ pdf_dict_finds(fz_context *ctx, pdf_obj *obj, const char *key, int *location)
while (l <= r)
{
int m = (l + r) >> 1;
- int c = -strcmp(pdf_to_name(ctx, obj->u.d.items[m].k), key);
+ int c = -strcmp(pdf_to_name(ctx, DICT(obj)->items[m].k), key);
if (c < 0)
r = m - 1;
else if (c > 0)
@@ -985,13 +1027,13 @@ pdf_dict_finds(fz_context *ctx, pdf_obj *obj, const char *key, int *location)
else
{
int i;
- for (i = 0; i < obj->u.d.len; i++)
- if (strcmp(pdf_to_name(ctx, obj->u.d.items[i].k), key) == 0)
+ for (i = 0; i < DICT(obj)->len; i++)
+ if (strcmp(pdf_to_name(ctx, DICT(obj)->items[i].k), key) == 0)
return i;
if (location)
- *location = obj->u.d.len;
+ *location = DICT(obj)->len;
}
return -1;
@@ -1000,13 +1042,13 @@ pdf_dict_finds(fz_context *ctx, pdf_obj *obj, const char *key, int *location)
static int
pdf_dict_find(fz_context *ctx, pdf_obj *obj, pdf_obj *key, int *location)
{
- if ((obj->flags & PDF_FLAGS_SORTED) && obj->u.d.len > 0)
+ if ((obj->flags & PDF_FLAGS_SORTED) && DICT(obj)->len > 0)
{
int l = 0;
- int r = obj->u.d.len - 1;
- pdf_obj *k = obj->u.d.items[r].k;
+ int r = DICT(obj)->len - 1;
+ pdf_obj *k = DICT(obj)->items[r].k;
- if (k == key || (k >= PDF_OBJ__LIMIT && strcmp(k->u.n, PDF_NAMES[(intptr_t)key]) < 0))
+ if (k == key || (k >= PDF_OBJ__LIMIT && strcmp(NAME(k)->n, PDF_NAMES[(intptr_t)key]) < 0))
{
if (location)
*location = r + 1;
@@ -1018,8 +1060,8 @@ pdf_dict_find(fz_context *ctx, pdf_obj *obj, pdf_obj *key, int *location)
int m = (l + r) >> 1;
int c;
- k = obj->u.d.items[m].k;
- c = (k < PDF_OBJ__LIMIT ? key-k : -strcmp(k->u.n, PDF_NAMES[(intptr_t)key]));
+ k = DICT(obj)->items[m].k;
+ c = (k < PDF_OBJ__LIMIT ? key-k : -strcmp(NAME(k)->n, PDF_NAMES[(intptr_t)key]));
if (c < 0)
r = m - 1;
else if (c > 0)
@@ -1034,9 +1076,9 @@ pdf_dict_find(fz_context *ctx, pdf_obj *obj, pdf_obj *key, int *location)
else
{
int i;
- for (i = 0; i < obj->u.d.len; i++)
+ for (i = 0; i < DICT(obj)->len; i++)
{
- pdf_obj *k = obj->u.d.items[i].k;
+ pdf_obj *k = DICT(obj)->items[i].k;
if (k < PDF_OBJ__LIMIT)
{
if (k == key)
@@ -1044,13 +1086,13 @@ pdf_dict_find(fz_context *ctx, pdf_obj *obj, pdf_obj *key, int *location)
}
else
{
- if (!strcmp(PDF_NAMES[(intptr_t)key], k->u.n))
+ if (!strcmp(PDF_NAMES[(intptr_t)key], NAME(k)->n))
return i;
}
}
if (location)
- *location = obj->u.d.len;
+ *location = DICT(obj)->len;
}
return -1;
@@ -1067,7 +1109,7 @@ pdf_dict_gets(fz_context *ctx, pdf_obj *obj, const char *key)
i = pdf_dict_finds(ctx, obj, key, NULL);
if (i >= 0)
- return obj->u.d.items[i].v;
+ return DICT(obj)->items[i].v;
return NULL;
}
@@ -1144,7 +1186,7 @@ pdf_dict_get(fz_context *ctx, pdf_obj *obj, pdf_obj *key)
i = pdf_dict_find(ctx, obj, key, NULL);
if (i >= 0)
- return obj->u.d.items[i].v;
+ return DICT(obj)->items[i].v;
return NULL;
}
@@ -1199,33 +1241,33 @@ pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
return;
}
- if (obj->u.d.len > 100 && !(obj->flags & PDF_FLAGS_SORTED))
+ if (DICT(obj)->len > 100 && !(obj->flags & PDF_FLAGS_SORTED))
pdf_sort_dict(ctx, obj);
i = pdf_dict_finds(ctx, obj, s, &location);
- if (i >= 0 && i < obj->u.d.len)
+ if (i >= 0 && i < DICT(obj)->len)
{
- if (obj->u.d.items[i].v != val)
+ if (DICT(obj)->items[i].v != val)
{
- pdf_obj *d = obj->u.d.items[i].v;
- obj->u.d.items[i].v = pdf_keep_obj(ctx, val);
+ pdf_obj *d = DICT(obj)->items[i].v;
+ DICT(obj)->items[i].v = pdf_keep_obj(ctx, val);
pdf_drop_obj(ctx, d);
}
}
else
{
- if (obj->u.d.len + 1 > obj->u.d.cap)
+ if (DICT(obj)->len + 1 > DICT(obj)->cap)
pdf_dict_grow(ctx, obj);
i = location;
- if ((obj->flags & PDF_FLAGS_SORTED) && obj->u.d.len > 0)
- memmove(&obj->u.d.items[i + 1],
- &obj->u.d.items[i],
- (obj->u.d.len - i) * sizeof(struct keyval));
-
- obj->u.d.items[i].k = pdf_keep_obj(ctx, key);
- obj->u.d.items[i].v = pdf_keep_obj(ctx, val);
- obj->u.d.len ++;
+ if ((obj->flags & PDF_FLAGS_SORTED) && DICT(obj)->len > 0)
+ memmove(&DICT(obj)->items[i + 1],
+ &DICT(obj)->items[i],
+ (DICT(obj)->len - i) * sizeof(struct keyval));
+
+ DICT(obj)->items[i].k = pdf_keep_obj(ctx, key);
+ DICT(obj)->items[i].v = pdf_keep_obj(ctx, val);
+ DICT(obj)->len ++;
}
object_altered(ctx, obj, val);
@@ -1247,8 +1289,15 @@ pdf_dict_put_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
void
pdf_dict_puts(fz_context *ctx, pdf_obj *obj, const char *key, pdf_obj *val)
{
- pdf_document *doc = obj->doc;
- pdf_obj *keyobj = pdf_new_name(ctx, doc, key);
+ pdf_document *doc;
+ pdf_obj *keyobj;
+
+ RESOLVE(obj);
+ if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_DICT)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "not a dictionary (%s)", pdf_objkindstr(obj));
+
+ doc = DICT(obj)->doc;
+ keyobj = pdf_new_name(ctx, doc, key);
fz_try(ctx)
pdf_dict_put(ctx, obj, keyobj, val);
@@ -1261,16 +1310,20 @@ pdf_dict_puts(fz_context *ctx, pdf_obj *obj, const char *key, pdf_obj *val)
void
pdf_dict_puts_drop(fz_context *ctx, pdf_obj *obj, const char *key, pdf_obj *val)
{
- pdf_document *doc = obj->doc;
- pdf_obj *keyobj = NULL;
+ pdf_document *doc;
+ pdf_obj *keyobj;
+
+ RESOLVE(obj);
+ if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_DICT)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "not a dictionary (%s)", pdf_objkindstr(obj));
+
+ doc = DICT(obj)->doc;
+ keyobj = pdf_new_name(ctx, doc, key);
fz_var(keyobj);
fz_try(ctx)
- {
- keyobj = pdf_new_name(ctx, doc, key);
pdf_dict_put(ctx, obj, keyobj, val);
- }
fz_always(ctx)
{
pdf_drop_obj(ctx, keyobj);
@@ -1285,59 +1338,60 @@ pdf_dict_puts_drop(fz_context *ctx, pdf_obj *obj, const char *key, pdf_obj *val)
void
pdf_dict_putp(fz_context *ctx, pdf_obj *obj, const char *keys, pdf_obj *val)
{
+ pdf_document *doc;
+ char buf[256];
+ char *k, *e;
+ pdf_obj *cobj = NULL;
+
RESOLVE(obj);
- if (obj >= PDF_OBJ__LIMIT)
- {
- pdf_document *doc = obj->doc;
+ if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_DICT)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "not a dictionary (%s)", pdf_objkindstr(obj));
- char buf[256];
- char *k, *e;
- pdf_obj *cobj = NULL;
+ doc = DICT(obj)->doc;
- if (strlen(keys)+1 > 256)
- fz_throw(ctx, FZ_ERROR_GENERIC, "buffer overflow in pdf_dict_putp");
+ if (strlen(keys)+1 > 256)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "buffer overflow in pdf_dict_putp");
- strcpy(buf, keys);
+ strcpy(buf, keys);
- e = buf;
- while (*e)
- {
- k = e;
- while (*e != '/' && *e != '\0')
- e++;
+ e = buf;
+ while (*e)
+ {
+ k = e;
+ while (*e != '/' && *e != '\0')
+ e++;
- if (*e == '/')
- {
- *e = '\0';
- e++;
- }
+ if (*e == '/')
+ {
+ *e = '\0';
+ e++;
+ }
- if (*e)
+ if (*e)
+ {
+ /* Not the last key in the key path. Create subdict if not already there. */
+ cobj = pdf_dict_gets(ctx, obj, k);
+ if (cobj == NULL)
{
- /* Not the last key in the key path. Create subdict if not already there. */
- cobj = pdf_dict_gets(ctx, obj, k);
- if (cobj == NULL)
- {
- cobj = pdf_new_dict(ctx, doc, 1);
- fz_try(ctx)
- pdf_dict_puts(ctx, obj, k, cobj);
- fz_always(ctx)
- pdf_drop_obj(ctx, cobj);
- fz_catch(ctx)
- fz_rethrow(ctx);
- }
- /* Move to subdict */
- obj = cobj;
+ cobj = pdf_new_dict(ctx, doc, 1);
+ fz_try(ctx)
+ pdf_dict_puts(ctx, obj, k, cobj);
+ fz_always(ctx)
+ pdf_drop_obj(ctx, cobj);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
}
+ /* Move to subdict */
+ obj = cobj;
+ }
+ else
+ {
+ /* Last key. Use it to store the value */
+ /* Use val = NULL to request delete */
+ if (val)
+ pdf_dict_puts(ctx, obj, k, val);
else
- {
- /* Last key. Use it to store the value */
- /* Use val = NULL to request delete */
- if (val)
- pdf_dict_puts(ctx, obj, k, val);
- else
- pdf_dict_dels(ctx, obj, k);
- }
+ pdf_dict_dels(ctx, obj, k);
}
}
}
@@ -1359,6 +1413,13 @@ pdf_dict_vputl(fz_context *ctx, pdf_obj *obj, pdf_obj *val, va_list keys)
pdf_obj *key;
pdf_obj *next_key;
pdf_obj *next_obj;
+ pdf_document *doc;
+
+ RESOLVE(obj);
+ if (obj < PDF_OBJ__LIMIT || obj->kind != PDF_DICT)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "not a dictionary (%s)", pdf_objkindstr(obj));
+
+ doc = DICT(obj)->doc;
key = va_arg(keys, pdf_obj *);
if (key == NULL)
@@ -1380,7 +1441,7 @@ new_obj:
/* We have to create entries */
do
{
- next_obj = pdf_new_dict(ctx, obj->doc, 1);
+ next_obj = pdf_new_dict(ctx, doc, 1);
pdf_dict_put_drop(ctx, obj, key, next_obj);
obj = next_obj;
key = next_key;
@@ -1435,11 +1496,11 @@ pdf_dict_dels(fz_context *ctx, pdf_obj *obj, const char *key)
int i = pdf_dict_finds(ctx, obj, key, NULL);
if (i >= 0)
{
- pdf_drop_obj(ctx, obj->u.d.items[i].k);
- pdf_drop_obj(ctx, obj->u.d.items[i].v);
+ pdf_drop_obj(ctx, DICT(obj)->items[i].k);
+ pdf_drop_obj(ctx, DICT(obj)->items[i].v);
obj->flags &= ~PDF_FLAGS_SORTED;
- obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1];
- obj->u.d.len --;
+ DICT(obj)->items[i] = DICT(obj)->items[DICT(obj)->len-1];
+ DICT(obj)->len --;
}
}
@@ -1458,7 +1519,7 @@ pdf_dict_del(fz_context *ctx, pdf_obj *obj, pdf_obj *key)
if (key < PDF_OBJ__LIMIT)
pdf_dict_dels(ctx, obj, PDF_NAMES[(intptr_t)key]);
else if (key->kind == PDF_NAME)
- pdf_dict_dels(ctx, obj, key->u.n);
+ pdf_dict_dels(ctx, obj, NAME(obj)->n);
/* else Can't warn */
}
@@ -1470,7 +1531,7 @@ pdf_sort_dict(fz_context *ctx, pdf_obj *obj)
return;
if (!(obj->flags & PDF_FLAGS_SORTED))
{
- qsort(obj->u.d.items, obj->u.d.len, sizeof(struct keyval), keyvalcmp);
+ qsort(DICT(obj)->items, DICT(obj)->len, sizeof(struct keyval), keyvalcmp);
obj->flags |= PDF_FLAGS_SORTED;
}
}
@@ -1557,10 +1618,10 @@ pdf_drop_array(fz_context *ctx, pdf_obj *obj)
{
int i;
- for (i = 0; i < obj->u.a.len; i++)
- pdf_drop_obj(ctx, obj->u.a.items[i]);
+ for (i = 0; i < DICT(obj)->len; i++)
+ pdf_drop_obj(ctx, ARRAY(obj)->items[i]);
- fz_free(ctx, obj->u.a.items);
+ fz_free(ctx, DICT(obj)->items);
fz_free(ctx, obj);
}
@@ -1569,12 +1630,12 @@ pdf_drop_dict(fz_context *ctx, pdf_obj *obj)
{
int i;
- for (i = 0; i < obj->u.d.len; i++) {
- pdf_drop_obj(ctx, obj->u.d.items[i].k);
- pdf_drop_obj(ctx, obj->u.d.items[i].v);
+ for (i = 0; i < DICT(obj)->len; i++) {
+ pdf_drop_obj(ctx, DICT(obj)->items[i].k);
+ pdf_drop_obj(ctx, DICT(obj)->items[i].v);
}
- fz_free(ctx, obj->u.d.items);
+ fz_free(ctx, DICT(obj)->items);
fz_free(ctx, obj);
}
@@ -1602,16 +1663,16 @@ pdf_set_obj_parent(fz_context *ctx, pdf_obj *obj, int num)
if (obj < PDF_OBJ__LIMIT)
return;
- obj->parent_num = num;
-
switch(obj->kind)
{
case PDF_ARRAY:
+ ARRAY(obj)->parent_num = num;
n = pdf_array_len(ctx, obj);
for (i = 0; i < n; i++)
pdf_set_obj_parent(ctx, pdf_array_get(ctx, obj, i), num);
break;
case PDF_DICT:
+ DICT(obj)->parent_num = num;
n = pdf_dict_len(ctx, obj);
for (i = 0; i < n; i++)
pdf_set_obj_parent(ctx, pdf_dict_get_val(ctx, obj, i), num);
@@ -1624,7 +1685,15 @@ int pdf_obj_parent_num(fz_context *ctx, pdf_obj *obj)
if (obj < PDF_OBJ__LIMIT)
return 0;
- return obj->parent_num;
+ switch(obj->kind)
+ {
+ case PDF_ARRAY:
+ return ARRAY(obj)->parent_num;
+ case PDF_DICT:
+ return DICT(obj)->parent_num;
+ default:
+ return 0;
+ }
}
pdf_obj *pdf_new_obj_from_str(fz_context *ctx, pdf_document *doc, const char *src)