diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2018-04-16 12:00:28 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2018-04-25 12:16:36 +0200 |
commit | 706ed587b875fab178fbfc2b60e1a49527e89b80 (patch) | |
tree | fb6d50795458b52a3d78febf4ce4ffc675d727e8 /source/pdf/pdf-object.c | |
parent | 51b8205a513e86c62121a927a067632c1a933839 (diff) | |
download | mupdf-706ed587b875fab178fbfc2b60e1a49527e89b80.tar.xz |
Tweak ordering of constant pdf_obj enums to make PDF_NULL == NULL.
Diffstat (limited to 'source/pdf/pdf-object.c')
-rw-r--r-- | source/pdf/pdf-object.c | 261 |
1 files changed, 116 insertions, 145 deletions
diff --git a/source/pdf/pdf-object.c b/source/pdf/pdf-object.c index 0d43e056..0efd667e 100644 --- a/source/pdf/pdf-object.c +++ b/source/pdf/pdf-object.c @@ -8,7 +8,7 @@ #define PDF_MAKE_NAME(STRING,NAME) STRING, static const char *PDF_NAME_LIST[] = { - "", /* dummy */ + "", "", "", /* dummy slots for null, true, and false */ #include "mupdf/pdf/name-table.h" }; #undef PDF_MAKE_NAME @@ -159,21 +159,23 @@ pdf_new_string(fz_context *ctx, pdf_document *doc, const char *str, size_t len) return &obj->super; } -static int -namecmp(const void *key, const void *name) -{ - return strcmp((char *)key, *(char **)name); -} - pdf_obj * pdf_new_name(fz_context *ctx, pdf_document *doc, const char *str) { pdf_obj_name *obj; - const char **stdname; - - stdname = bsearch(str, &PDF_NAME_LIST[1], PDF_ENUM_LIMIT_NAME-1, sizeof(char *), namecmp); - if (stdname != NULL) - return (pdf_obj *)(intptr_t)(stdname - &PDF_NAME_LIST[0]); + int l = 3; /* skip dummy slots */ + int r = nelem(PDF_NAME_LIST) - 1; + while (l <= r) + { + int m = (l + r) >> 1; + int c = strcmp(str, PDF_NAME_LIST[m]); + if (c < 0) + r = m - 1; + else if (c > 0) + l = m + 1; + else + return (pdf_obj*)(intptr_t)m; + } obj = Memento_label(fz_malloc(ctx, offsetof(pdf_obj_name, n) + strlen(str) + 1), "pdf_obj(name)"); obj->super.refs = 1; @@ -197,34 +199,23 @@ pdf_new_indirect(fz_context *ctx, pdf_document *doc, int num, int gen) return &obj->super; } -pdf_obj * -pdf_keep_obj(fz_context *ctx, pdf_obj *obj) -{ - if (obj >= PDF_OBJ_LIMIT) - { - (void)fz_keep_imp16(ctx, obj, &obj->refs); - } - return obj; -} - #define OBJ_IS_NULL(obj) (obj == PDF_NULL) #define OBJ_IS_BOOL(obj) (obj == PDF_TRUE || obj == PDF_FALSE) +#define OBJ_IS_NAME(obj) ((obj > PDF_FALSE && obj < PDF_LIMIT) || (obj >= PDF_LIMIT && obj->kind == PDF_NAME)) #define OBJ_IS_INT(obj) \ - (obj >= PDF_OBJ_LIMIT ? obj->kind == PDF_INT : 0) + (obj >= PDF_LIMIT && obj->kind == PDF_INT) #define OBJ_IS_REAL(obj) \ - (obj >= PDF_OBJ_LIMIT ? obj->kind == PDF_REAL : 0) + (obj >= PDF_LIMIT && obj->kind == PDF_REAL) #define OBJ_IS_NUMBER(obj) \ - (obj >= PDF_OBJ_LIMIT ? (obj->kind == PDF_REAL || obj->kind == PDF_INT) : 0) + (obj >= PDF_LIMIT && (obj->kind == PDF_REAL || obj->kind == PDF_INT)) #define OBJ_IS_STRING(obj) \ - (obj >= PDF_OBJ_LIMIT ? obj->kind == PDF_STRING : 0) -#define OBJ_IS_NAME(obj) \ - ((obj >= PDF_OBJ_LIMIT) ? (obj->kind == PDF_NAME) : (obj != NULL && obj < PDF_NAME_LIMIT)) + (obj >= PDF_LIMIT && obj->kind == PDF_STRING) #define OBJ_IS_ARRAY(obj) \ - (obj >= PDF_OBJ_LIMIT ? obj->kind == PDF_ARRAY : 0) + (obj >= PDF_LIMIT && obj->kind == PDF_ARRAY) #define OBJ_IS_DICT(obj) \ - (obj >= PDF_OBJ_LIMIT ? obj->kind == PDF_DICT : 0) + (obj >= PDF_LIMIT && obj->kind == PDF_DICT) #define OBJ_IS_INDIRECT(obj) \ - (obj >= PDF_OBJ_LIMIT ? obj->kind == PDF_INDIRECT : 0) + (obj >= PDF_LIMIT && obj->kind == PDF_INDIRECT) #define RESOLVE(obj) \ if (OBJ_IS_INDIRECT(obj)) \ @@ -298,7 +289,7 @@ int pdf_to_bool(fz_context *ctx, pdf_obj *obj) int pdf_to_int(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return 0; if (obj->kind == PDF_INT) return (int)NUM(obj)->u.i; @@ -310,7 +301,7 @@ int pdf_to_int(fz_context *ctx, pdf_obj *obj) int64_t pdf_to_int64(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return 0; if (obj->kind == PDF_INT) return NUM(obj)->u.i; @@ -322,7 +313,7 @@ int64_t pdf_to_int64(fz_context *ctx, pdf_obj *obj) float pdf_to_real(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return 0; if (obj->kind == PDF_REAL) return NUM(obj)->u.f; @@ -334,34 +325,33 @@ float pdf_to_real(fz_context *ctx, pdf_obj *obj) const char *pdf_to_name(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (!OBJ_IS_NAME(obj)) - return ""; - if (obj < PDF_NAME_LIMIT) - return PDF_NAME_LIST[(intptr_t)obj]; - return NAME(obj)->n; + if (obj < PDF_LIMIT) + return PDF_NAME_LIST[((intptr_t)obj)]; + if (obj->kind == PDF_NAME) + return NAME(obj)->n; + return ""; } char *pdf_to_str_buf(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (!OBJ_IS_STRING(obj)) - return ""; - return STRING(obj)->buf; + if (OBJ_IS_STRING(obj)) + return STRING(obj)->buf; + return ""; } int pdf_to_str_len(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (!OBJ_IS_STRING(obj)) - return 0; - return STRING(obj)->len; + if (OBJ_IS_STRING(obj)) + return STRING(obj)->len; + return 0; } void pdf_set_int(fz_context *ctx, pdf_obj *obj, int64_t i) { - if (!OBJ_IS_INT(obj)) - return; - NUM(obj)->u.i = i; + if (OBJ_IS_INT(obj)) + NUM(obj)->u.i = i; } /* for use by pdf_crypt_obj_imp to decrypt AES string in place */ @@ -377,28 +367,28 @@ void pdf_set_str_len(fz_context *ctx, pdf_obj *obj, int newlen) int pdf_to_num(fz_context *ctx, pdf_obj *obj) { - if (!OBJ_IS_INDIRECT(obj)) - return 0; - return REF(obj)->num; + if (OBJ_IS_INDIRECT(obj)) + return REF(obj)->num; + return 0; } int pdf_to_gen(fz_context *ctx, pdf_obj *obj) { - if (!OBJ_IS_INDIRECT(obj)) - return 0; - return REF(obj)->gen; + if (OBJ_IS_INDIRECT(obj)) + return REF(obj)->gen; + return 0; } pdf_document *pdf_get_indirect_document(fz_context *ctx, pdf_obj *obj) { - if (!OBJ_IS_INDIRECT(obj)) - return NULL; - return REF(obj)->doc; + if (OBJ_IS_INDIRECT(obj)) + return REF(obj)->doc; + return NULL; } pdf_document *pdf_get_bound_document(fz_context *ctx, pdf_obj *obj) { - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return NULL; if (obj->kind == PDF_INDIRECT) return REF(obj)->doc; @@ -424,32 +414,25 @@ pdf_objcmp(fz_context *ctx, pdf_obj *a, pdf_obj *b) if (a == b) return 0; - if (!a || !b) + if (a <= PDF_FALSE || b <= PDF_FALSE) return 1; - if (a < PDF_NAME_LIMIT) + if (a < PDF_LIMIT) { - if (b < PDF_NAME_LIMIT) + if (b < PDF_LIMIT) return a != b; - if (b < PDF_OBJ_LIMIT) - return 1; if (b->kind != PDF_NAME) return 1; - return strcmp(NAME(b)->n, PDF_NAME_LIST[(intptr_t)a]); + return strcmp(PDF_NAME_LIST[(intptr_t)a], NAME(b)->n); } - if (b < PDF_NAME_LIMIT) + if (b < PDF_LIMIT) { - if (a < PDF_OBJ_LIMIT) - return 1; if (a->kind != PDF_NAME) return 1; return strcmp(NAME(a)->n, PDF_NAME_LIST[(intptr_t)b]); } - if (a < PDF_OBJ_LIMIT || b < PDF_OBJ_LIMIT) - return a != b; - if (a->kind != b->kind) return 1; @@ -513,23 +496,26 @@ pdf_objcmp(fz_context *ctx, pdf_obj *a, pdf_obj *b) int pdf_name_eq(fz_context *ctx, pdf_obj *a, pdf_obj *b) { - /* A quick check in case they are constants */ - if (a < PDF_NAME_LIMIT) - return a == b; - return !pdf_objcmp_resolve(ctx, a, b); + RESOLVE(a); + RESOLVE(b); + if (a <= PDF_FALSE || b <= PDF_FALSE) + return 0; + if (a < PDF_LIMIT || b < PDF_LIMIT) + return (a == b); + if (a->kind == PDF_NAME && b->kind == PDF_NAME) + return !strcmp(NAME(a)->n, NAME(b)->n); + return 0; } static char * pdf_objkindstr(pdf_obj *obj) { - if (!obj) - return "<NULL>"; - if (obj < PDF_NAME_LIMIT) - return "name"; - if (obj == PDF_TRUE || obj == PDF_FALSE) - return "boolean"; if (obj == PDF_NULL) return "null"; + if (obj == PDF_TRUE || obj == PDF_FALSE) + return "boolean"; + if (obj < PDF_LIMIT) + return "name"; switch (obj->kind) { case PDF_INT: return "integer"; @@ -644,7 +630,7 @@ static void prepare_object_for_alteration(fz_context *ctx, pdf_obj *obj, pdf_obj 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) + if (obj < PDF_LIMIT) return; switch (obj->kind) @@ -697,10 +683,6 @@ pdf_array_put(fz_context *ctx, pdf_obj *obj, int i, pdf_obj *item) } if (i < 0 || i > ARRAY(obj)->len) fz_throw(ctx, FZ_ERROR_GENERIC, "index out of bounds"); - - if (!item) - item = PDF_NULL; - prepare_object_for_alteration(ctx, obj, item); pdf_drop_obj(ctx, ARRAY(obj)->items[i]); ARRAY(obj)->items[i] = pdf_keep_obj(ctx, item); @@ -723,10 +705,6 @@ pdf_array_push(fz_context *ctx, pdf_obj *obj, pdf_obj *item) RESOLVE(obj); if (!OBJ_IS_ARRAY(obj)) fz_throw(ctx, FZ_ERROR_GENERIC, "not an array (%s)", pdf_objkindstr(obj)); - - if (!item) - item = PDF_NULL; - prepare_object_for_alteration(ctx, obj, item); if (ARRAY(obj)->len + 1 > ARRAY(obj)->cap) pdf_array_grow(ctx, ARRAY(obj)); @@ -737,16 +715,12 @@ pdf_array_push(fz_context *ctx, pdf_obj *obj, pdf_obj *item) void pdf_array_push_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *item) { - RESOLVE(obj); - if (obj >= PDF_OBJ_LIMIT) - { - fz_try(ctx) - pdf_array_push(ctx, obj, item); - fz_always(ctx) - pdf_drop_obj(ctx, item); - fz_catch(ctx) - fz_rethrow(ctx); - } + fz_try(ctx) + pdf_array_push(ctx, obj, item); + fz_always(ctx) + pdf_drop_obj(ctx, item); + fz_catch(ctx) + fz_rethrow(ctx); } void @@ -757,10 +731,6 @@ pdf_array_insert(fz_context *ctx, pdf_obj *obj, pdf_obj *item, int i) fz_throw(ctx, FZ_ERROR_GENERIC, "not an array (%s)", pdf_objkindstr(obj)); if (i < 0 || i > ARRAY(obj)->len) fz_throw(ctx, FZ_ERROR_GENERIC, "index out of bounds"); - - if (!item) - item = PDF_NULL; - prepare_object_for_alteration(ctx, obj, item); if (ARRAY(obj)->len + 1 > ARRAY(obj)->cap) pdf_array_grow(ctx, ARRAY(obj)); @@ -772,16 +742,12 @@ pdf_array_insert(fz_context *ctx, pdf_obj *obj, pdf_obj *item, int i) void pdf_array_insert_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *item, int i) { - RESOLVE(obj); - if (obj >= PDF_OBJ_LIMIT) - { - fz_try(ctx) - pdf_array_insert(ctx, obj, item, i); - fz_always(ctx) - pdf_drop_obj(ctx, item); - fz_catch(ctx) - fz_rethrow(ctx); - } + fz_try(ctx) + pdf_array_insert(ctx, obj, item, i); + fz_always(ctx) + pdf_drop_obj(ctx, item); + fz_catch(ctx) + fz_rethrow(ctx); } void @@ -792,7 +758,6 @@ pdf_array_delete(fz_context *ctx, pdf_obj *obj, int i) fz_throw(ctx, FZ_ERROR_GENERIC, "not an array (%s)", pdf_objkindstr(obj)); if (i < 0 || i >= ARRAY(obj)->len) fz_throw(ctx, FZ_ERROR_GENERIC, "index out of bounds"); - prepare_object_for_alteration(ctx, obj, NULL); pdf_drop_obj(ctx, ARRAY(obj)->items[i]); ARRAY(obj)->items[i] = 0; @@ -875,16 +840,16 @@ static int keyvalcmp(const void *ap, const void *bp) /* We should never get a->k == NULL or b->k == NULL. If we * do, then they match. */ - if (a->k < PDF_NAME_LIMIT) + if (a->k < PDF_LIMIT) an = PDF_NAME_LIST[(intptr_t)a->k]; - else if (a->k >= PDF_OBJ_LIMIT && a->k->kind == PDF_NAME) + else if (a->k >= PDF_LIMIT && a->k->kind == PDF_NAME) an = NAME(a->k)->n; else return 0; - if (b->k < PDF_NAME_LIMIT) + if (b->k < PDF_LIMIT) bn = PDF_NAME_LIST[(intptr_t)b->k]; - else if (b->k >= PDF_OBJ_LIMIT && b->k->kind == PDF_NAME) + else if (b->k >= PDF_LIMIT && b->k->kind == PDF_NAME) bn = NAME(b->k)->n; else return 0; @@ -1064,7 +1029,7 @@ pdf_dict_find(fz_context *ctx, pdf_obj *obj, pdf_obj *key) int r = len - 1; pdf_obj *k = DICT(obj)->items[r].k; - if (k == key || (k >= PDF_OBJ_LIMIT && strcmp(NAME(k)->n, PDF_NAME_LIST[(intptr_t)key]) < 0)) + if (k == key || (k >= PDF_LIMIT && strcmp(NAME(k)->n, PDF_NAME_LIST[(intptr_t)key]) < 0)) { return -1 - (r+1); } @@ -1075,7 +1040,7 @@ pdf_dict_find(fz_context *ctx, pdf_obj *obj, pdf_obj *key) int c; k = DICT(obj)->items[m].k; - c = (k < PDF_OBJ_LIMIT ? (char *)key-(char *)k : -strcmp(NAME(k)->n, PDF_NAME_LIST[(intptr_t)key])); + c = (k < PDF_LIMIT ? (char *)key-(char *)k : -strcmp(NAME(k)->n, PDF_NAME_LIST[(intptr_t)key])); if (c < 0) r = m - 1; else if (c > 0) @@ -1091,7 +1056,7 @@ pdf_dict_find(fz_context *ctx, pdf_obj *obj, pdf_obj *key) for (i = 0; i < len; i++) { pdf_obj *k = DICT(obj)->items[i].k; - if (k < PDF_OBJ_LIMIT) + if (k < PDF_LIMIT) { if (k == key) return i; @@ -1185,7 +1150,7 @@ pdf_dict_get(fz_context *ctx, pdf_obj *obj, pdf_obj *key) if (!OBJ_IS_NAME(key)) return NULL; - if (key < PDF_NAME_LIMIT) + if (key < PDF_LIMIT) i = pdf_dict_find(ctx, obj, key); else i = pdf_dict_finds(ctx, obj, pdf_to_name(ctx, key)); @@ -1228,13 +1193,10 @@ pdf_dict_get_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val, pdf_ if (!OBJ_IS_NAME(key)) fz_throw(ctx, FZ_ERROR_GENERIC, "key is not a name (%s)", pdf_objkindstr(obj)); - if (!val) - val = PDF_NULL; - if (DICT(obj)->len > 100 && !(obj->flags & PDF_FLAGS_SORTED)) pdf_sort_dict(ctx, obj); - if (key < PDF_NAME_LIMIT) + if (key < PDF_LIMIT) i = pdf_dict_find(ctx, obj, key); else i = pdf_dict_finds(ctx, obj, pdf_to_name(ctx, key)); @@ -1522,7 +1484,7 @@ pdf_dict_del(fz_context *ctx, pdf_obj *obj, pdf_obj *key) if (!OBJ_IS_NAME(key)) fz_throw(ctx, FZ_ERROR_GENERIC, "key is not a name (%s)", pdf_objkindstr(key)); - if (key < PDF_NAME_LIMIT) + if (key < PDF_LIMIT) pdf_dict_dels(ctx, obj, PDF_NAME_LIST[(intptr_t)key]); else pdf_dict_dels(ctx, obj, NAME(key)->n); @@ -1544,9 +1506,9 @@ pdf_sort_dict(fz_context *ctx, pdf_obj *obj) pdf_obj * pdf_deep_copy_obj(fz_context *ctx, pdf_obj *obj) { - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) { - return pdf_keep_obj(ctx, obj); + return obj; } if (obj->kind == PDF_DICT) { @@ -1600,7 +1562,7 @@ int pdf_obj_marked(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return 0; return !!(obj->flags & PDF_FLAGS_MARKED); } @@ -1610,7 +1572,7 @@ pdf_mark_obj(fz_context *ctx, pdf_obj *obj) { int marked; RESOLVE(obj); - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return 0; marked = !!(obj->flags & PDF_FLAGS_MARKED); obj->flags |= PDF_FLAGS_MARKED; @@ -1621,7 +1583,7 @@ void pdf_unmark_obj(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return; obj->flags &= ~PDF_FLAGS_MARKED; } @@ -1629,9 +1591,8 @@ pdf_unmark_obj(fz_context *ctx, pdf_obj *obj) void pdf_set_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int memo) { - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return; - bit <<= 1; obj->flags |= PDF_FLAGS_MEMO_BASE << bit; if (memo) @@ -1643,7 +1604,7 @@ pdf_set_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int memo) int pdf_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int *memo) { - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return 0; bit <<= 1; if (!(obj->flags & (PDF_FLAGS_MEMO_BASE<<bit))) @@ -1655,7 +1616,7 @@ pdf_obj_memo(fz_context *ctx, pdf_obj *obj, int bit, int *memo) int pdf_obj_is_dirty(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return 0; return !!(obj->flags & PDF_FLAGS_DIRTY); } @@ -1663,14 +1624,14 @@ int pdf_obj_is_dirty(fz_context *ctx, pdf_obj *obj) void pdf_dirty_obj(fz_context *ctx, pdf_obj *obj) { RESOLVE(obj); - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return; obj->flags |= PDF_FLAGS_DIRTY; } void pdf_clean_obj(fz_context *ctx, pdf_obj *obj) { - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return; obj->flags &= ~PDF_FLAGS_DIRTY; } @@ -1701,10 +1662,18 @@ pdf_drop_dict(fz_context *ctx, pdf_obj *obj) fz_free(ctx, obj); } +pdf_obj * +pdf_keep_obj(fz_context *ctx, pdf_obj *obj) +{ + if (obj >= PDF_LIMIT) + return fz_keep_imp16(ctx, obj, &obj->refs); + return obj; +} + void pdf_drop_obj(fz_context *ctx, pdf_obj *obj) { - if (obj >= PDF_OBJ_LIMIT) + if (obj >= PDF_LIMIT) { if (fz_drop_imp16(ctx, obj, &obj->refs)) { @@ -1723,10 +1692,10 @@ pdf_set_obj_parent(fz_context *ctx, pdf_obj *obj, int num) { int n, i; - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return; - switch(obj->kind) + switch (obj->kind) { case PDF_ARRAY: ARRAY(obj)->parent_num = num; @@ -1745,10 +1714,10 @@ pdf_set_obj_parent(fz_context *ctx, pdf_obj *obj, int num) int pdf_obj_parent_num(fz_context *ctx, pdf_obj *obj) { - if (obj < PDF_OBJ_LIMIT) + if (obj < PDF_LIMIT) return 0; - switch(obj->kind) + switch (obj->kind) { case PDF_INDIRECT: return REF(obj)->num; @@ -2180,9 +2149,11 @@ void pdf_debug_obj(fz_context *ctx, pdf_obj *obj) putchar('\n'); } -int pdf_obj_refs(fz_context *ctx, pdf_obj *ref) +int pdf_obj_refs(fz_context *ctx, pdf_obj *obj) { - return (ref >= PDF_OBJ_LIMIT ? ref->refs : 0); + if (obj < PDF_LIMIT) + return 0; + return obj->refs; } /* Convenience functions */ |