From 7afdfc725c0693cfd9bc4ede2b5cc10cc30361b9 Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Tue, 4 May 2021 17:04:09 -0400 Subject: [PATCH] Implement object loading. --- pdfio-file.c | 9 ++++--- pdfio-object.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ pdfio-private.h | 4 +-- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/pdfio-file.c b/pdfio-file.c index e209879..5955a0c 100644 --- a/pdfio-file.c +++ b/pdfio-file.c @@ -197,10 +197,11 @@ pdfioFileCreateObject( pdf->objs[pdf->num_objs ++] = obj; // Initialize the object... - obj->pdf = pdf; - obj->number = pdf->num_objs; - obj->dict = dict; - obj->offset = _pdfioFileTell(pdf); + obj->pdf = pdf; + obj->number = pdf->num_objs; + obj->offset = _pdfioFileTell(pdf); + obj->value.type = PDFIO_VALTYPE_DICT; + obj->value.value.dict = dict; // Don't write anything just yet... return (obj); diff --git a/pdfio-object.c b/pdfio-object.c index 7626541..2c99ee9 100644 --- a/pdfio-object.c +++ b/pdfio-object.c @@ -122,3 +122,72 @@ pdfioObjOpenStream(pdfio_obj_t *obj) // I - Object return (NULL); } + + +// +// '()' - Load an object dictionary/value. +// + +bool // O - `true` on success, `false` otherwise +_pdfioObjLoad(pdfio_obj_t *obj) // I - Object +{ + char line[1024], // Line from file + *ptr; // Pointer into line + + + // Seek to the start of the object and read its header... + if (_pdfioFileSeek(obj->pdf, obj->offset, SEEK_SET) != obj->offset) + { + _pdfioFileError(obj->pdf, "Unable to seek to object %lu.", (unsigned long)obj->number); + return (false); + } + + if (!_pdfioFileGets(obj->pdf, line, sizeof(line))) + { + _pdfioFileError(obj->pdf, "Unable to read header for object %lu.", (unsigned long)obj->number); + return (false); + } + + if (strtoimax(line, &ptr, 10) != (intmax_t)obj->number) + { + _pdfioFileError(obj->pdf, "Bad header for object %lu.", (unsigned long)obj->number); + return (false); + } + + if (strtol(ptr, &ptr, 10) != (long)obj->generation) + { + _pdfioFileError(obj->pdf, "Bad header for object %lu.", (unsigned long)obj->number); + return (false); + } + + while (isspace(*ptr & 255)) + ptr ++; + + if (strcmp(ptr, "obj")) + { + _pdfioFileError(obj->pdf, "Bad header for object %lu.", (unsigned long)obj->number); + return (false); + } + + // Then grab the object value... + if (!_pdfioValueRead(obj->pdf, &obj->value)) + { + _pdfioFileError(obj->pdf, "Unable to read value for object %lu.", (unsigned long)obj->number); + return (false); + } + + // Now see if there is an associated stream... + if (!_pdfioFileGets(obj->pdf, line, sizeof(line))) + { + _pdfioFileError(obj->pdf, "Early end-of-file for object %lu.", (unsigned long)obj->number); + return (false); + } + + if (!strcmp(line, "stream")) + { + // Yes, save its location... + obj->stream_offset = _pdfioFileTell(obj->pdf); + } + + return (true); +} diff --git a/pdfio-private.h b/pdfio-private.h index ed43dea..b279f63 100644 --- a/pdfio-private.h +++ b/pdfio-private.h @@ -161,7 +161,7 @@ struct _pdfio_obj_s // Object length_offset, // Offset to /Length in object dict stream_offset; // Offset to start of stream in file size_t stream_length; // Length of stream, if any - pdfio_dict_t *dict; // Dictionary + _pdfio_value_t value; // Dictionary/number/etc. value pdfio_stream_t *stream; // Open stream, if any }; @@ -214,8 +214,8 @@ extern off_t _pdfioFileSeek(pdfio_file_t *pdf, off_t offset, int whence) PDFIO_ extern off_t _pdfioFileTell(pdfio_file_t *pdf) PDFIO_INTERNAL; extern bool _pdfioFileWrite(pdfio_file_t *pdf, const void *buffer, size_t bytes) PDFIO_INTERNAL; -extern pdfio_obj_t *_pdfioObjAdd(pdfio_file_t *pdf, size_t number, unsigned short generation, off_t offset) PDFIO_INTERNAL; extern void _pdfioObjDelete(pdfio_obj_t *obj) PDFIO_INTERNAL; +extern bool _pdfioObjLoad(pdfio_obj_t *obj) PDFIO_INTERNAL; extern void _pdfioStreamDelete(pdfio_stream_t *st) PDFIO_INTERNAL;