diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/pdf/pdf-object.c | 653 |
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) |