summaryrefslogtreecommitdiff
path: root/src/xref.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2017-12-21 23:49:13 +0000
committerVincent Sanders <vince@kyllikki.org>2017-12-21 23:49:13 +0000
commit897a8900bf77db2d804b0f78bc4b41371e05347f (patch)
tree31dfd1c54ceaef746bfb867a4657b7cdcc3d5c61 /src/xref.c
parentb22daf7d9b39210a0c7f8b5522a884a828b656b0 (diff)
downloadlibnspdf-897a8900bf77db2d804b0f78bc4b41371e05347f.tar.gz
libnspdf-897a8900bf77db2d804b0f78bc4b41371e05347f.tar.bz2
split code up a bit
Diffstat (limited to 'src/xref.c')
-rw-r--r--src/xref.c1076
1 files changed, 10 insertions, 1066 deletions
diff --git a/src/xref.c b/src/xref.c
index d6a07b8..5e5ac8b 100644
--- a/src/xref.c
+++ b/src/xref.c
@@ -7,136 +7,12 @@
#include "nspdferror.h"
#include "byte_class.h"
+#include "cos_object.h"
+#include "pdf_doc.h"
#define SLEN(x) (sizeof((x)) - 1)
-enum cos_type {
- COS_TYPE_NULL,
- COS_TYPE_BOOL,
- COS_TYPE_INT,
- COS_TYPE_REAL,
- COS_TYPE_NAME,
- COS_TYPE_STRING,
- COS_TYPE_ARRAY,
- COS_TYPE_DICTIONARY,
- COS_TYPE_NAMETREE,
- COS_TYPE_NUMBERTREE,
- COS_TYPE_STREAM,
- COS_TYPE_REFERENCE,
-};
-
-struct cos_object;
-
-struct cos_dictionary_entry {
- /** next key/value in dictionary */
- struct cos_dictionary_entry *next;
-
- /** key (name) */
- struct cos_object *key;
-
- /** value */
- struct cos_object *value;
-};
-
-struct cos_array_entry {
- /** next value in array */
- struct cos_array_entry *next;
-
- /** value */
- struct cos_object *value;
-};
-
-struct cos_string {
- uint8_t *data;
- size_t length;
- size_t alloc;
-};
-
-struct cos_reference {
- /** id of indirect object */
- uint64_t id;
-
- /* generation of indirect object */
- uint64_t generation;
-};
-
-struct cos_object {
- int type;
- union {
- /** boolean */
- bool b;
-
- /** integer */
- int64_t i;
-
- /** real */
- double r;
-
- /** name */
- char *n;
-
- /** string */
- struct cos_string *s;
-
- /** stream data */
- uint8_t *stream;
-
- /* dictionary */
- struct cos_dictionary_entry *dictionary;
-
- /* array */
- struct cos_array_entry *array;
-
- /** reference */
- struct cos_reference *reference;
-
- } u;
-};
-
-
-/** indirect object */
-struct cos_indirect_object {
- /* reference identifier */
- struct cos_reference ref;
-
- /** offset of object */
- uint64_t offset;
-
- /* direct object if already decoded */
- struct cos_object *o;
-};
-
-
-/** pdf document */
-struct pdf_doc {
- uint8_t *buffer;
- uint64_t buffer_length;
-
- uint8_t *start; /* start of pdf document in input stream */
- uint64_t length;
-
- int major;
- int minor;
-
- /**
- * Indirect object cross reference table
- */
- uint64_t xref_size;
- struct cos_indirect_object *xref_table;
-
- struct cos_object *root;
- struct cos_object *encrypt;
- struct cos_object *info;
- struct cos_object *id;
-
-};
-
-
-int cos_decode_object(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out);
-
int
read_whole_pdf(struct pdf_doc *doc, const char *fname)
{
@@ -178,46 +54,7 @@ read_whole_pdf(struct pdf_doc *doc, const char *fname)
#define STARTXREF_SEARCH_SIZE 1024
-/* byte data acessory, allows for more complex buffer handling in future */
-#define DOC_BYTE(doc, offset) (doc->start[(offset)])
-
-/**
- * move offset to next non whitespace byte
- */
-static int doc_skip_ws(struct pdf_doc *doc, uint64_t *offset)
-{
- uint8_t c;
- /* TODO sort out keeping offset in range */
- c = DOC_BYTE(doc, *offset);
- while ((bclass[c] & (BC_WSPC | BC_CMNT) ) != 0) {
- (*offset)++;
- /* skip comments */
- if ((bclass[c] & BC_CMNT) != 0) {
- c = DOC_BYTE(doc, *offset);
- while ((bclass[c] & BC_EOLM ) == 0) {
- (*offset)++;
- c = DOC_BYTE(doc, *offset);
- }
- }
- c = DOC_BYTE(doc, *offset);
- }
- return 0;
-}
-/**
- * move offset to next non eol byte
- */
-static int doc_skip_eol(struct pdf_doc *doc, uint64_t *offset)
-{
- uint8_t c;
- /* TODO sort out keeping offset in range */
- c = DOC_BYTE(doc, *offset);
- while ((bclass[c] & BC_EOLM) != 0) {
- (*offset)++;
- c = DOC_BYTE(doc, *offset);
- }
- return 0;
-}
static nspdferror
doc_read_uint(struct pdf_doc *doc, uint64_t *offset_out, uint64_t *result_out)
@@ -388,842 +225,7 @@ int check_header(struct pdf_doc *doc)
}
-nspdferror cos_free_object(struct cos_object *cos_obj)
-{
- struct cos_dictionary_entry *dentry;
- struct cos_array_entry *aentry;
-
- switch (cos_obj->type) {
- case COS_TYPE_NAME:
- free(cos_obj->u.n);
- break;
-
- case COS_TYPE_STRING:
- free(cos_obj->u.s->data);
- free(cos_obj->u.s);
- break;
-
- case COS_TYPE_DICTIONARY:
- dentry = cos_obj->u.dictionary;
- while (dentry != NULL) {
- struct cos_dictionary_entry *odentry;
-
- cos_free_object(dentry->key);
- cos_free_object(dentry->value);
-
- odentry = dentry;
- dentry = dentry->next;
- free(odentry);
- }
- break;
- case COS_TYPE_ARRAY:
- aentry = cos_obj->u.array;
- while (aentry != NULL) {
- struct cos_array_entry *oaentry;
-
- cos_free_object(aentry->value);
-
- oaentry = aentry;
- aentry = aentry->next;
- free(oaentry);
- }
-
- case COS_TYPE_STREAM:
- free(cos_obj->u.stream);
- break;
-
- }
- free(cos_obj);
-
- return NSPDFERROR_OK;
-}
-
-int cos_decode_number(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- struct cos_object *cosobj;
- uint8_t c; /* current byte from source data */
- unsigned int len; /* number of decimal places in number */
- uint8_t num[21]; /* temporary buffer for decimal values */
- uint64_t offset; /* current offset of source data */
-
- offset = *offset_out;
-
- for (len = 0; len < sizeof(num); len++) {
- c = DOC_BYTE(doc, offset);
- if ((bclass[c] & BC_DCML) != BC_DCML) {
- int64_t result = 0; /* parsed result */
- uint64_t tens;
-
- if (len == 0) {
- return -2; /* parse error no decimals in input */
- }
- /* sum value from each place */
- for (tens = 1; len > 0; tens = tens * 10, len--) {
- result += (num[len - 1] * tens);
- }
-
- doc_skip_ws(doc, &offset);
-
- cosobj = calloc(1, sizeof(struct cos_object));
- if (cosobj == NULL) {
- return -1; /* memory error */
- }
-
- cosobj->type = COS_TYPE_INT;
- cosobj->u.i = result;
-
- *cosobj_out = cosobj;
-
- *offset_out = offset;
-
- return 0;
- }
- num[len] = c - '0';
- offset++;
- }
- return -1; /* number too long */
-}
-
-#define COS_STRING_ALLOC 32
-
-nspdferror
-cos_string_append(struct cos_string *s, uint8_t c)
-{
- //printf("appending 0x%x to %p len %d alloc %d\n", c, s->data, s->length, s->alloc);
- if (s->length == s->alloc) {
- uint8_t *ns;
- ns = realloc(s->data, s->alloc + COS_STRING_ALLOC);
- if (ns == NULL) {
- return NSPDFERROR_NOMEM;
- }
- s->data = ns;
- s->alloc += COS_STRING_ALLOC;
- }
- s->data[s->length++] = c;
- return NSPDFERROR_OK;
-}
-
-/**
- * literal string processing
- *
- */
-nspdferror
-cos_decode_string(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- uint64_t offset;
- struct cos_object *cosobj;
- uint8_t c;
- unsigned int pdepth = 1; /* depth of open parens */
- struct cos_string *cstring;
-
- offset = *offset_out;
-
- c = DOC_BYTE(doc, offset++);
- if (c != '(') {
- return NSPDFERROR_SYNTAX;
- }
-
- cstring = calloc(1, sizeof(*cstring));
- if (cstring == NULL) {
- return NSPDFERROR_NOMEM;
- }
-
- cosobj = calloc(1, sizeof(*cosobj));
- if (cosobj == NULL) {
- return NSPDFERROR_NOMEM;
- }
- cosobj->type = COS_TYPE_STRING;
- cosobj->u.s = cstring;
-
- while (pdepth > 0) {
- c = DOC_BYTE(doc, offset++);
-
- if (c == ')') {
- pdepth--;
- if (pdepth == 0) {
- break;
- }
- } else if (c == '(') {
- pdepth++;
- } else if ((bclass[c] & BC_EOLM ) != 0) {
- /* unescaped end of line characters are translated to a single
- * newline
- */
- c = DOC_BYTE(doc, offset);
- while ((bclass[c] & BC_EOLM) != 0) {
- offset++;
- c = DOC_BYTE(doc, offset);
- }
- c = '\n';
- } else if (c == '\\') {
- /* escaped chars */
- c = DOC_BYTE(doc, offset++);
- switch (c) {
- case 'n':
- c = '\n';
- break;
-
- case 'r':
- c = '\r';
- break;
-
- case 't':
- c = '\t';
- break;
-
- case 'b':
- c = '\b';
- break;
-
- case 'f':
- c = '\f';
- break;
-
- case '(':
- c = '(';
- break;
-
- case ')':
- c = ')';
- break;
-
- case '\\':
- c = '\\';
- break;
-
- default:
-
- if ((bclass[c] & BC_EOLM) != 0) {
- /* escaped end of line, swallow it */
- c = DOC_BYTE(doc, offset++);
- while ((bclass[c] & BC_EOLM) != 0) {
- c = DOC_BYTE(doc, offset++);
- }
- } else if ((bclass[c] & BC_OCTL) != 0) {
- /* octal value */
- uint8_t val;
- val = (c - '0');
- c = DOC_BYTE(doc, offset);
- if ((bclass[c] & BC_OCTL) != 0) {
- offset++;
- val = (val << 3) | (c - '0');
- c = DOC_BYTE(doc, offset);
- if ((bclass[c] & BC_OCTL) != 0) {
- offset++;
- val = (val << 3) | (c - '0');
- c = val;
- }
- }
- } /* else invalid (skip backslash) */
- break;
- }
- }
-
- /* c contains the character to add to the string */
- cos_string_append(cstring, c);
- }
-
- doc_skip_ws(doc, &offset);
-
- *cosobj_out = cosobj;
- *offset_out = offset;
-
- return NSPDFERROR_OK;
-}
-
-uint8_t xtoi(uint8_t x)
-{
- if (x >= '0' && x <= '9') {
- x = x - '0';
- } else if (x >= 'a' && x <='f') {
- x = x - 'a' + 10;
- } else if (x >= 'A' && x <='F') {
- x = x - 'A' + 10;
- }
- return x;
-}
-
-nspdferror
-cos_decode_hex_string(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- uint64_t offset;
- struct cos_object *cosobj;
- uint8_t c;
- uint8_t value = 0;
- struct cos_string *cstring;
- bool first = true;
-
- offset = *offset_out;
-
- c = DOC_BYTE(doc, offset++);
- if (c != '<') {
- return NSPDFERROR_SYNTAX;
- }
-
- cstring = calloc(1, sizeof(*cstring));
- if (cstring == NULL) {
- return NSPDFERROR_NOMEM;
- }
-
- cosobj = calloc(1, sizeof(*cosobj));
- if (cosobj == NULL) {
- return NSPDFERROR_NOMEM;
- }
- cosobj->type = COS_TYPE_STRING;
- cosobj->u.s = cstring;
-
- for (; offset < doc->length; offset++) {
- c = DOC_BYTE(doc, offset);
- if (c == '>') {
- if (first == false) {
- cos_string_append(cstring, value);
- }
- offset++;
- doc_skip_ws(doc, &offset);
-
- *cosobj_out = cosobj;
- *offset_out = offset;
-
- return NSPDFERROR_OK;
- } else if ((bclass[c] & BC_HEXL) != 0) {
- if (first) {
- value = xtoi(c) << 4;
- first = false;
- } else {
- value |= xtoi(c);
- first = true;
- cos_string_append(cstring, value);
- }
- } else if ((bclass[c] & BC_WSPC) == 0) {
- break; /* unknown byte value in string */
- }
- }
- return NSPDFERROR_SYNTAX;
-}
-
-
-int cos_decode_dictionary(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- uint64_t offset;
- struct cos_object *cosobj;
- struct cos_dictionary_entry *entry;
- struct cos_object *key;
- struct cos_object *value;
- int res;
-
- offset = *offset_out;
-
- if ((DOC_BYTE(doc, offset) != '<') ||
- (DOC_BYTE(doc, offset + 1) != '<')) {
- return -1; /* syntax error */
- }
- offset += 2;
- doc_skip_ws(doc, &offset);
-
- printf("found a dictionary\n");
-
- cosobj = calloc(1, sizeof(struct cos_object));
- if (cosobj == NULL) {
- return -1; /* memory error */
- }
- cosobj->type = COS_TYPE_DICTIONARY;
-
- while ((DOC_BYTE(doc, offset) != '>') &&
- (DOC_BYTE(doc, offset + 1) != '>')) {
-
- res = cos_decode_object(doc, &offset, &key);
- if (res != 0) {
- /* todo free up any dictionary entries already created */
- printf("key object decode failed\n");
- return res;
- }
- if (key->type != COS_TYPE_NAME) {
- /* key value pairs without a name */
- printf("key was %d not a name %d\n", key->type, COS_TYPE_NAME);
- return -1; /* syntax error */
- }
- printf("key: %s\n", key->u.n);
-
- res = cos_decode_object(doc, &offset, &value);
- if (res != 0) {
- printf("Unable to decode value object in dictionary\n");
- /* todo free up any dictionary entries already created */
- return res;
- }
-
- /* add dictionary entry */
- entry = calloc(1, sizeof(struct cos_dictionary_entry));
- if (entry == NULL) {
- /* todo free up any dictionary entries already created */
- return -1; /* memory error */
- }
-
- entry->key = key;
- entry->value = value;
- entry->next = cosobj->u.dictionary;
-
- cosobj->u.dictionary = entry;
-
- }
- offset += 2; /* skip closing >> */
- doc_skip_ws(doc, &offset);
-
- *cosobj_out = cosobj;
- *offset_out = offset;
-
- return 0;
-}
-
-
-nspdferror
-cos_decode_list(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- uint64_t offset;
- struct cos_object *cosobj;
- struct cos_array_entry *entry;
- struct cos_object *value;
- nspdferror res;
-
- offset = *offset_out;
-
- /* sanity check first token is list open */
- if (DOC_BYTE(doc, offset) != '[') {
- printf("not a [\n");
- return NSPDFERROR_SYNTAX; /* syntax error */
- }
- offset++;
-
- /* advance offset to next token */
- res = doc_skip_ws(doc, &offset);
- if (res != NSPDFERROR_OK) {
- return res;
- }
-
- printf("found a list\n");
-
- cosobj = calloc(1, sizeof(struct cos_object));
- if (cosobj == NULL) {
- return NSPDFERROR_NOMEM;
- }
- cosobj->type = COS_TYPE_ARRAY;
-
- while (DOC_BYTE(doc, offset) != ']') {
-
- res = cos_decode_object(doc, &offset, &value);
- if (res != NSPDFERROR_OK) {
- cos_free_object(cosobj);
- printf("Unable to decode value object in list\n");
- return res;
- }
-
- /* add entry to array */
- entry = calloc(1, sizeof(struct cos_array_entry));
- if (entry == NULL) {
- cos_free_object(cosobj);
- return NSPDFERROR_NOMEM;
- }
-
- entry->value = value;
- entry->next = cosobj->u.array;
-
- cosobj->u.array = entry;
- }
- offset++; /* skip closing ] */
-
- doc_skip_ws(doc, &offset);
-
- *cosobj_out = cosobj;
- *offset_out = offset;
-
- return 0;
-}
-
-#define NAME_MAX_LENGTH 127
-
-/**
- * decode a name object
- *
- * \todo deal with # symbols on pdf versions 1.2 and later
- */
-int cos_decode_name(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- uint64_t offset;
- struct cos_object *cosobj;
- uint8_t c;
- char name[NAME_MAX_LENGTH + 1];
- int idx = 0;
-
- offset = *offset_out;
-
- c = DOC_BYTE(doc, offset++);
- if (c != '/') {
- return -1; /* names must be prefixed with a / */
- }
- printf("found a name\n");
-
- c = DOC_BYTE(doc, offset);
- while ((idx <= NAME_MAX_LENGTH) &&
- ((bclass[c] & (BC_WSPC | BC_DELM)) == 0)) {
- offset++;
- //printf("%c", c);
- name[idx++] = c;
- c = DOC_BYTE(doc, offset);
- }
- //printf("\nidx: %d\n", idx);
- if (idx > NAME_MAX_LENGTH) {
- /* name length exceeded implementation limit */
- return -1;
- }
- name[idx] = 0;
-
- //printf("name: %s\n", name);
-
- doc_skip_ws(doc, &offset);
-
- cosobj = calloc(1, sizeof(struct cos_object));
- if (cosobj == NULL) {
- return -1; /* memory error */
- }
-
- cosobj->type = COS_TYPE_NAME;
- cosobj->u.n = strdup(name);
-
- *cosobj_out = cosobj;
-
- *offset_out = offset;
-
- return 0;
-}
-
-
-int cos_decode_boolean(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- uint64_t offset;
- struct cos_object *cosobj;
- uint8_t c;
- bool value;
-
- offset = *offset_out;
-
- c = DOC_BYTE(doc, offset++);
- if ((c == 't') || (c == 'T')) {
- /* true branch */
-
- c = DOC_BYTE(doc, offset++);
- if ((c != 'r') && (c != 'R')) {
- return -1; /* syntax error */
- }
- c = DOC_BYTE(doc, offset++);
- if ((c != 'u') && (c != 'U')) {
- return -1; /* syntax error */
- }
- c = DOC_BYTE(doc, offset++);
- if ((c != 'e') && (c != 'E')) {
- return -1; /* syntax error */
- }
- value = true;
-
- } else if ((c == 'f') || (c == 'F')) {
- /* false branch */
-
- c = DOC_BYTE(doc, offset++);
- if ((c != 'a') && (c != 'A')) {
- return -1; /* syntax error */
- }
- c = DOC_BYTE(doc, offset++);
- if ((c != 'l') && (c != 'L')) {
- return -1; /* syntax error */
- }
- c = DOC_BYTE(doc, offset++);
- if ((c != 's') && (c != 'S')) {
- return -1; /* syntax error */
- }
- c = DOC_BYTE(doc, offset++);
- if ((c != 'e') && (c != 'E')) {
- return -1; /* syntax error */
- }
-
- value = false;
-
- } else {
- return -1; /* syntax error */
- }
-
- doc_skip_ws(doc, &offset);
-
- cosobj = calloc(1, sizeof(struct cos_object));
- if (cosobj == NULL) {
- return -1; /* memory error */
- }
-
- cosobj->type = COS_TYPE_BOOL;
- cosobj->u.b = value;
-
- *cosobj_out = cosobj;
-
- *offset_out = offset;
-
- return 0;
-
-}
-
-int cos_decode_null(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- uint64_t offset;
- struct cos_object *cosobj;
- uint8_t c;
-
- offset = *offset_out;
-
- c = DOC_BYTE(doc, offset++);
- if ((c != 'n') && (c != 'N')) {
- return -1; /* syntax error */
- }
- c = DOC_BYTE(doc, offset++);
- if ((c != 'u') && (c != 'U')) {
- return -1; /* syntax error */
- }
- c = DOC_BYTE(doc, offset++);
- if ((c != 'l') && (c != 'L')) {
- return -1; /* syntax error */
- }
- c = DOC_BYTE(doc, offset++);
- if ((c != 'l') && (c != 'L')) {
- return -1; /* syntax error */
- }
-
- doc_skip_ws(doc, &offset);
-
- cosobj = calloc(1, sizeof(struct cos_object));
- if (cosobj == NULL) {
- return -1; /* memory error */
- }
-
- cosobj->type = COS_TYPE_NULL;
- *offset_out = offset;
-
- return 0;
-}
-
-/**
- * attempt to decode the stream into a reference
- *
- * The stream has already had a positive integer decoded from it. if another
- * positive integer follows and a R character after that it is a reference,
- * otherwise bail, but not finding a ref is not an error!
- *
- * \param doc the pdf document
- * \param offset_out offset of current cursor in stream
- * \param cosobj_out the object to return into, on input contains the first
- * integer
- */
-int cos_attempt_decode_reference(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- uint64_t offset;
- struct cos_object *cosobj; /* possible generation object */
- uint8_t c;
- int res;
- struct cos_reference *nref; /* new reference */
-
- offset = *offset_out;
-
- res = cos_decode_number(doc, &offset, &cosobj);
- if (res != 0) {
- return 0; /* no error if object could not be decoded */
- }
-
- if (cosobj->type != COS_TYPE_INT) {
- /* next object was not an integer so not a reference */
- cos_free_object(cosobj);
- return 0;
- }
-
- if (cosobj->u.i < 0) {
- /* integer was negative so not a reference (generations must be
- * non-negative
- */
- cos_free_object(cosobj);
- return 0;
-
- }
-
- /* two int in a row, look for the R */
- c = DOC_BYTE(doc, offset++);
- if (c != 'R') {
- /* no R so not a reference */
- cos_free_object(cosobj);
- return 0;
- }
-
- /* found reference */
-
- printf("found reference\n");
- doc_skip_ws(doc, &offset);
-
- nref = calloc(1, sizeof(struct cos_reference));
- if (nref == NULL) {
- /* todo free objects */
- return -1; /* memory error */
- }
-
- nref->id = (*cosobj_out)->u.i;
- nref->generation = cosobj->u.i;
-
- cos_free_object(*cosobj_out);
-
- cosobj->type = COS_TYPE_REFERENCE;
- cosobj->u.reference = nref;
-
- *cosobj_out = cosobj;
-
- *offset_out = offset;
-
- return 0;
-}
-
-/**
- * Decode input stream into an object
- *
- * lex and parse a byte stream to generate COS objects
- *
- * lexing the input.
- * check first character:
- *
- * < either a hex string or a dictionary
- * second char < means dictionary else hex string
- * - either an integer or real
- * + either an integer or real
- * 0-9 an integer, unsigned integer or real
- * . a real number
- * ( a string
- * / a name
- * [ a list
- * t|T boolean true
- * f|F boolean false
- * n|N null
- *
- * Grammar is:
- * cos_object:
- * TOK_NULL |
- * TOK_BOOLEAN |
- * TOK_INT |
- * TOK_REAL |
- * TOK_NAME |
- * TOK_STRING |
- * list |
- * dictionary |
- * object_reference;
- *
- * list:
- * '[' listargs ']';
- *
- * listargs:
- * cos_object
- * |
- * listargs cos_object
- * ;
- *
- * object_reference:
- * TOK_UINT TOK_UINT 'R';
- */
-int cos_decode_object(struct pdf_doc *doc,
- uint64_t *offset_out,
- struct cos_object **cosobj_out)
-{
- uint64_t offset;
- int res;
- struct cos_object *cosobj;
-
- offset = *offset_out;
-
- /* object could be any type use first char to try and select */
- switch (DOC_BYTE(doc, offset)) {
-
- case '-':
- case '+':
- case '.':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- res = cos_decode_number(doc, &offset, &cosobj);
- /* if type is positive integer try to check for reference */
- if ((res == 0) &&
- (cosobj->type == COS_TYPE_INT) &&
- (cosobj->u.i > 0)) {
- res = cos_attempt_decode_reference(doc, &offset, &cosobj);
- }
- break;
-
- case '<':
- if (DOC_BYTE(doc, offset + 1) == '<') {
- res = cos_decode_dictionary(doc, &offset, &cosobj);
- } else {
- res = cos_decode_hex_string(doc, &offset, &cosobj);
- }
- break;
-
- case '(':
- res = cos_decode_string(doc, &offset, &cosobj);
- break;
-
- case '/':
- res = cos_decode_name(doc, &offset, &cosobj);
- break;
-
- case '[':
- res = cos_decode_list(doc, &offset, &cosobj);
- break;
-
- case 't':
- case 'T':
- case 'f':
- case 'F':
- res = cos_decode_boolean(doc, &offset, &cosobj);
- break;
-
- case 'n':
- case 'N':
- res = cos_decode_null(doc, &offset, &cosobj);
- break;
-
- default:
- res = -1; /* syntax error */
- }
-
-
- if (res == 0) {
- *cosobj_out = cosobj;
- *offset_out = offset;
- }
-
- return res;
-}
@@ -1335,7 +337,7 @@ decode_xref(struct pdf_doc *doc, uint64_t *offset_out)
if ((DOC_BYTE(doc, offset++) == 'n')) {
if (objnumber < doc->xref_size) {
- struct cos_indirect_object *indobj;
+ struct xref_table_entry *indobj;
indobj = doc->xref_table + objnumber;
indobj->ref.id = objnumber;
@@ -1357,69 +359,6 @@ decode_xref(struct pdf_doc *doc, uint64_t *offset_out)
return NSPDFERROR_OK;
}
-nspdferror
-cos_dictionary_get_value(struct cos_object *dict,
- const char *key,
- struct cos_object **value_out)
-{
- struct cos_dictionary_entry *entry;
-
- if (dict->type != COS_TYPE_DICTIONARY) {
- return NSPDFERROR_TYPE;
- }
-
- entry = dict->u.dictionary;
- while (entry != NULL) {
- if (strcmp(entry->key->u.n, key) == 0) {
- *value_out = entry->value;
- return NSPDFERROR_OK;
- }
- entry = entry->next;
- }
- return NSPDFERROR_NOTFOUND;
-}
-
-/**
- * extracts a value for a key in a dictionary.
- *
- * this finds and returns a value for a given key removing it from a dictionary
- */
-nspdferror
-cos_dictionary_extract_value(struct cos_object *dict,
- const char *key,
- struct cos_object **value_out)
-{
- struct cos_dictionary_entry *entry;
- struct cos_dictionary_entry **prev;
-
- if (dict->type != COS_TYPE_DICTIONARY) {
- return NSPDFERROR_TYPE;
- }
-
- prev = &dict->u.dictionary;
- entry = *prev;
- while (entry != NULL) {
- if (strcmp(entry->key->u.n, key) == 0) {
- *value_out = entry->value;
- *prev = entry->next;
- cos_free_object(entry->key);
- free(entry);
- return NSPDFERROR_OK;
- }
- prev = &entry->next;
- entry = *prev;
- }
- return NSPDFERROR_NOTFOUND;
-}
-
-nspdferror cos_get_int(struct cos_object *cobj, int64_t *value_out)
-{
- if (cobj->type != COS_TYPE_INT) {
- return NSPDFERROR_TYPE;
- }
- *value_out = cobj->u.i;
- return NSPDFERROR_OK;
-}
/**
* recursively parse trailers and xref tables
@@ -1480,7 +419,7 @@ nspdferror decode_xref_trailer(struct pdf_doc *doc, uint64_t xref_offset)
goto decode_xref_trailer_failed;
}
- doc->xref_table = calloc(size, sizeof(struct cos_indirect_object));
+ doc->xref_table = calloc(size, sizeof(struct xref_table_entry));
if (doc->xref_table == NULL) {
res = NSPDFERROR_NOMEM;
goto decode_xref_trailer_failed;
@@ -1580,7 +519,12 @@ nspdferror decode_trailers(struct pdf_doc *doc)
nspdferror decode_catalog(struct pdf_doc *doc)
{
- return NSPDFERROR_OK;
+ nspdferror res;
+ struct cos_object *catalog;
+
+ res = cos_get_dictionary(doc->root, &catalog);
+
+ return res;
}
nspdferror new_pdf_doc(struct pdf_doc **doc_out)