mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2026-01-19 18:20:07 +01:00
Minor refactoring to more easily add in object stream support (Issue #101)
This commit is contained in:
@@ -670,27 +670,29 @@ pdfioArrayRemove(pdfio_array_t *a, // I - Array
|
||||
//
|
||||
|
||||
bool // O - `true` on success, `false` otherwise
|
||||
_pdfioArrayWrite(pdfio_array_t *a, // I - Array
|
||||
pdfio_obj_t *obj) // I - Object, if any
|
||||
_pdfioArrayWrite(
|
||||
_pdfio_printf_t cb, // I - Printf callback function
|
||||
void *cbdata, // I - Printf callback data
|
||||
pdfio_obj_t *obj, // I - Object, if any
|
||||
pdfio_array_t *a) // I - Array
|
||||
{
|
||||
pdfio_file_t *pdf = a->pdf; // PDF file
|
||||
size_t i; // Looping var
|
||||
_pdfio_value_t *v; // Current value
|
||||
|
||||
|
||||
// Arrays are surrounded by square brackets ([ ... ])
|
||||
if (!_pdfioFilePuts(pdf, "["))
|
||||
if (!(cb)(cbdata, "["))
|
||||
return (false);
|
||||
|
||||
// Write each value...
|
||||
for (i = a->num_values, v = a->values; i > 0; i --, v ++)
|
||||
{
|
||||
if (!_pdfioValueWrite(pdf, obj, v, NULL))
|
||||
if (!_pdfioValueWrite(cb, cbdata, obj, v, NULL))
|
||||
return (false);
|
||||
}
|
||||
|
||||
// Closing bracket...
|
||||
return (_pdfioFilePuts(pdf, "]"));
|
||||
return ((cb)(cbdata, "]"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
24
pdfio-dict.c
24
pdfio-dict.c
@@ -1073,11 +1073,13 @@ _pdfioDictSetValue(
|
||||
//
|
||||
|
||||
bool // O - `true` on success, `false` on failure
|
||||
_pdfioDictWrite(pdfio_dict_t *dict, // I - Dictionary
|
||||
pdfio_obj_t *obj, // I - Object, if any
|
||||
off_t *length) // I - Offset to length value
|
||||
_pdfioDictWrite(
|
||||
_pdfio_printf_t cb, // I - Printf callback function
|
||||
void *cbdata, // I - Printf callback data
|
||||
pdfio_obj_t *obj, // I - Object, if any
|
||||
pdfio_dict_t *dict, // I - Dictionary
|
||||
off_t *length) // I - Offset to length value
|
||||
{
|
||||
pdfio_file_t *pdf = dict->pdf; // PDF file
|
||||
size_t i; // Looping var
|
||||
_pdfio_pair_t *pair; // Current key/value pair
|
||||
|
||||
@@ -1086,28 +1088,30 @@ _pdfioDictWrite(pdfio_dict_t *dict, // I - Dictionary
|
||||
*length = 0;
|
||||
|
||||
// Dictionaries are bounded by "<<" and ">>"...
|
||||
if (!_pdfioFilePuts(pdf, "<<"))
|
||||
if (!(cb)(cbdata, "<<"))
|
||||
return (false);
|
||||
|
||||
// Write all of the key/value pairs...
|
||||
for (i = dict->num_pairs, pair = dict->pairs; i > 0; i --, pair ++)
|
||||
{
|
||||
if (!_pdfioFilePrintf(pdf, "%N", pair->key))
|
||||
if (!(cb)(cbdata, "%N", pair->key))
|
||||
return (false);
|
||||
|
||||
if (length && !strcmp(pair->key, "Length") && pair->value.type == PDFIO_VALTYPE_NUMBER && pair->value.value.number <= 0.0)
|
||||
{
|
||||
// Writing an object dictionary with an undefined length
|
||||
*length = _pdfioFileTell(pdf) + 1;
|
||||
if (!_pdfioFilePuts(pdf, " 9999999999"))
|
||||
*length = _pdfioFileTell(dict->pdf) + 1;
|
||||
if (!(cb)(cbdata, " 9999999999"))
|
||||
return (false);
|
||||
}
|
||||
else if (!_pdfioValueWrite(pdf, obj, &pair->value, NULL))
|
||||
else if (!_pdfioValueWrite(cb, cbdata, obj, &pair->value, NULL))
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
// Close it up...
|
||||
return (_pdfioFilePuts(pdf, ">>"));
|
||||
return ((cb)(cbdata, ">>"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3124,7 +3124,7 @@ write_trailer(pdfio_file_t *pdf) // I - PDF file
|
||||
pdfioDictSetObj(pdf->trailer_dict, "Root", pdf->root_obj);
|
||||
pdfioDictSetNumber(pdf->trailer_dict, "Size", (double)(pdf->num_objs + 1));
|
||||
|
||||
if (!_pdfioDictWrite(pdf->trailer_dict, NULL, NULL))
|
||||
if (!_pdfioDictWrite((_pdfio_printf_t)_pdfioFilePrintf, pdf, /*obj*/NULL, pdf->trailer_dict, /*length*/NULL))
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to write trailer.");
|
||||
ret = false;
|
||||
|
||||
@@ -608,7 +608,7 @@ _pdfioObjWriteHeader(pdfio_obj_t *obj) // I - Object
|
||||
if (!_pdfioFilePrintf(obj->pdf, "%lu %u obj\n", (unsigned long)obj->number, obj->generation))
|
||||
return (false);
|
||||
|
||||
if (!_pdfioValueWrite(obj->pdf, obj, &obj->value, &obj->length_offset))
|
||||
if (!_pdfioValueWrite((_pdfio_printf_t)_pdfioFilePrintf, obj->pdf, obj, &obj->value, &obj->length_offset))
|
||||
return (false);
|
||||
|
||||
return (_pdfioFilePuts(obj->pdf, "\n"));
|
||||
|
||||
@@ -96,8 +96,10 @@
|
||||
# define PDFIO_MAX_DEPTH 32 // Maximum nesting depth for values
|
||||
# define PDFIO_MAX_STRING 131072 // Maximum length of string
|
||||
|
||||
typedef void (*_pdfio_extfree_t)(void *);
|
||||
typedef void (*_pdfio_extfree_t)(void *p);
|
||||
// Extension data free function
|
||||
typedef bool (*_pdfio_printf_t)(void *data, const char *format, ...);
|
||||
// "printf" function
|
||||
|
||||
typedef enum _pdfio_mode_e // Read/write mode
|
||||
{
|
||||
@@ -408,7 +410,7 @@ extern void _pdfioArrayDebug(pdfio_array_t *a, FILE *fp) _PDFIO_INTERNAL;
|
||||
extern void _pdfioArrayDelete(pdfio_array_t *a) _PDFIO_INTERNAL;
|
||||
extern _pdfio_value_t *_pdfioArrayGetValue(pdfio_array_t *a, size_t n) _PDFIO_INTERNAL;
|
||||
extern pdfio_array_t *_pdfioArrayRead(pdfio_file_t *pdf, pdfio_obj_t *obj, _pdfio_token_t *ts, size_t depth) _PDFIO_INTERNAL;
|
||||
extern bool _pdfioArrayWrite(pdfio_array_t *a, pdfio_obj_t *obj) _PDFIO_INTERNAL;
|
||||
extern bool _pdfioArrayWrite(_pdfio_printf_t cb, void *cbdata, pdfio_obj_t *obj, pdfio_array_t *a) _PDFIO_INTERNAL;
|
||||
|
||||
extern void _pdfioCryptoAESInit(_pdfio_aes_t *ctx, const uint8_t *key, size_t keylen, const uint8_t *iv) _PDFIO_INTERNAL;
|
||||
extern size_t _pdfioCryptoAESDecrypt(_pdfio_aes_t *ctx, uint8_t *outbuffer, const uint8_t *inbuffer, size_t len) _PDFIO_INTERNAL;
|
||||
@@ -433,7 +435,7 @@ extern void _pdfioDictDelete(pdfio_dict_t *dict) _PDFIO_INTERNAL;
|
||||
extern _pdfio_value_t *_pdfioDictGetValue(pdfio_dict_t *dict, const char *key) _PDFIO_INTERNAL;
|
||||
extern pdfio_dict_t *_pdfioDictRead(pdfio_file_t *pdf, pdfio_obj_t *obj, _pdfio_token_t *ts, size_t depth) _PDFIO_INTERNAL;
|
||||
extern bool _pdfioDictSetValue(pdfio_dict_t *dict, const char *key, _pdfio_value_t *value) _PDFIO_INTERNAL;
|
||||
extern bool _pdfioDictWrite(pdfio_dict_t *dict, pdfio_obj_t *obj, off_t *length) _PDFIO_INTERNAL;
|
||||
extern bool _pdfioDictWrite(_pdfio_printf_t cb, void *cbdata, pdfio_obj_t *obj, pdfio_dict_t *dict, off_t *length) _PDFIO_INTERNAL;
|
||||
|
||||
extern bool _pdfioFileAddMappedObj(pdfio_file_t *pdf, pdfio_obj_t *dst_obj, pdfio_obj_t *src_obj) _PDFIO_INTERNAL;
|
||||
extern bool _pdfioFileAddPage(pdfio_file_t *pdf, pdfio_obj_t *obj) _PDFIO_INTERNAL;
|
||||
@@ -482,7 +484,7 @@ extern bool _pdfioValueDecrypt(pdfio_file_t *pdf, pdfio_obj_t *obj, _pdfio_valu
|
||||
extern void _pdfioValueDebug(_pdfio_value_t *v, FILE *fp) _PDFIO_INTERNAL;
|
||||
extern void _pdfioValueDelete(_pdfio_value_t *v) _PDFIO_INTERNAL;
|
||||
extern _pdfio_value_t *_pdfioValueRead(pdfio_file_t *pdf, pdfio_obj_t *obj, _pdfio_token_t *ts, _pdfio_value_t *v, size_t depth) _PDFIO_INTERNAL;
|
||||
extern bool _pdfioValueWrite(pdfio_file_t *pdf, pdfio_obj_t *obj, _pdfio_value_t *v, off_t *length) _PDFIO_INTERNAL;
|
||||
extern bool _pdfioValueWrite(_pdfio_printf_t cb, void *cbdata, pdfio_obj_t *obj, _pdfio_value_t *v, off_t *length) _PDFIO_INTERNAL;
|
||||
|
||||
|
||||
#endif // !PDFIO_PRIVATE_H
|
||||
|
||||
@@ -603,10 +603,12 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
//
|
||||
|
||||
bool // O - `true` on success, `false` on failure
|
||||
_pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
pdfio_obj_t *obj, // I - Object, if any
|
||||
_pdfio_value_t *v, // I - Value
|
||||
off_t *length)// O - Offset to /Length value, if any
|
||||
_pdfioValueWrite(
|
||||
_pdfio_printf_t cb, // I - Printf callback function
|
||||
void *cbdata, // I - Printf callback data
|
||||
pdfio_obj_t *obj, // I - Object, if any
|
||||
_pdfio_value_t *v, // I - Value
|
||||
off_t *length) // O - Offset to /Length value, if any
|
||||
{
|
||||
switch (v->type)
|
||||
{
|
||||
@@ -614,7 +616,7 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
return (false);
|
||||
|
||||
case PDFIO_VALTYPE_ARRAY :
|
||||
return (_pdfioArrayWrite(v->value.array, obj));
|
||||
return (_pdfioArrayWrite(cb, cbdata, obj, v->value.array));
|
||||
|
||||
case PDFIO_VALTYPE_BINARY :
|
||||
{
|
||||
@@ -624,26 +626,26 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
bool ret = false; // Return value
|
||||
|
||||
|
||||
if (obj && pdf->encryption)
|
||||
if (obj && obj->pdf->encryption)
|
||||
{
|
||||
// Write encrypted string...
|
||||
_pdfio_crypto_ctx_t ctx; // Encryption context
|
||||
_pdfio_crypto_cb_t cb; // Encryption callback
|
||||
_pdfio_crypto_cb_t ccb; // Encryption callback
|
||||
size_t ivlen; // Number of initialization vector bytes
|
||||
|
||||
if (v->value.binary.datalen > PDFIO_MAX_STRING)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to write encrypted binary string - too long.");
|
||||
_pdfioFileError(obj->pdf, "Unable to write encrypted binary string - too long.");
|
||||
return (false);
|
||||
}
|
||||
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(obj->pdf)) == NULL)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to write encrypted binary string - out of memory.");
|
||||
_pdfioFileError(obj->pdf, "Unable to write encrypted binary string - out of memory.");
|
||||
return (false);
|
||||
}
|
||||
|
||||
cb = _pdfioCryptoMakeWriter(pdf, obj, &ctx, temp, &ivlen);
|
||||
databytes = (cb)(&ctx, temp + ivlen, v->value.binary.data, v->value.binary.datalen) + ivlen;
|
||||
ccb = _pdfioCryptoMakeWriter(obj->pdf, obj, &ctx, temp, &ivlen);
|
||||
databytes = (ccb)(&ctx, temp + ivlen, v->value.binary.data, v->value.binary.datalen) + ivlen;
|
||||
dataptr = temp;
|
||||
}
|
||||
else
|
||||
@@ -652,33 +654,33 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
databytes = v->value.binary.datalen;
|
||||
}
|
||||
|
||||
if (!_pdfioFilePuts(pdf, "<"))
|
||||
if (!(cb)(cbdata, "<"))
|
||||
goto bindone;
|
||||
|
||||
for (; databytes > 1; databytes -= 2, dataptr += 2)
|
||||
{
|
||||
if (!_pdfioFilePrintf(pdf, "%02X%02X", dataptr[0], dataptr[1]))
|
||||
if (!(cb)(cbdata, "%02X%02X", dataptr[0], dataptr[1]))
|
||||
goto bindone;
|
||||
}
|
||||
|
||||
if (databytes > 0 && !_pdfioFilePrintf(pdf, "%02X", dataptr[0]))
|
||||
if (databytes > 0 && !(cb)(cbdata, "%02X", dataptr[0]))
|
||||
goto bindone;
|
||||
|
||||
ret = _pdfioFilePuts(pdf, ">");
|
||||
ret = (cb)(cbdata, ">");
|
||||
|
||||
bindone:
|
||||
|
||||
if (temp)
|
||||
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||
_pdfioStringFreeBuffer(obj->pdf, (char *)temp);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
case PDFIO_VALTYPE_BOOLEAN :
|
||||
if (v->value.boolean)
|
||||
return (_pdfioFilePuts(pdf, " true"));
|
||||
return ((cb)(cbdata, " true"));
|
||||
else
|
||||
return (_pdfioFilePuts(pdf, " false"));
|
||||
return ((cb)(cbdata, " false"));
|
||||
|
||||
case PDFIO_VALTYPE_DATE :
|
||||
{
|
||||
@@ -693,64 +695,64 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
|
||||
snprintf(datestr, sizeof(datestr), "D:%04d%02d%02d%02d%02d%02dZ", date.tm_year + 1900, date.tm_mon + 1, date.tm_mday, date.tm_hour, date.tm_min, date.tm_sec);
|
||||
|
||||
if (obj && pdf->encryption)
|
||||
if (obj && obj->pdf->encryption)
|
||||
{
|
||||
// Write encrypted string...
|
||||
uint8_t temp[64], // Encrypted bytes
|
||||
*tempptr; // Pointer into encrypted bytes
|
||||
_pdfio_crypto_ctx_t ctx; // Encryption context
|
||||
_pdfio_crypto_cb_t cb; // Encryption callback
|
||||
_pdfio_crypto_cb_t ccb; // Encryption callback
|
||||
size_t len = strlen(datestr),
|
||||
// Length of value
|
||||
ivlen, // Number of initialization vector bytes
|
||||
tempbytes; // Number of output bytes
|
||||
|
||||
cb = _pdfioCryptoMakeWriter(pdf, obj, &ctx, temp, &ivlen);
|
||||
tempbytes = (cb)(&ctx, temp + ivlen, (const uint8_t *)datestr, len) + ivlen;
|
||||
ccb = _pdfioCryptoMakeWriter(obj->pdf, obj, &ctx, temp, &ivlen);
|
||||
tempbytes = (ccb)(&ctx, temp + ivlen, (const uint8_t *)datestr, len) + ivlen;
|
||||
|
||||
if (!_pdfioFilePuts(pdf, "<"))
|
||||
if (!(cb)(cbdata, "<"))
|
||||
return (false);
|
||||
|
||||
for (tempptr = temp; tempbytes > 1; tempbytes -= 2, tempptr += 2)
|
||||
{
|
||||
if (!_pdfioFilePrintf(pdf, "%02X%02X", tempptr[0], tempptr[1]))
|
||||
if (!(cb)(cbdata, "%02X%02X", tempptr[0], tempptr[1]))
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (tempbytes > 0)
|
||||
return (_pdfioFilePrintf(pdf, "%02X>", *tempptr));
|
||||
return ((cb)(cbdata, "%02X>", *tempptr));
|
||||
else
|
||||
return (_pdfioFilePuts(pdf, ">"));
|
||||
return ((cb)(cbdata, ">"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (_pdfioFilePrintf(pdf, "%S", datestr));
|
||||
return ((cb)(cbdata, "%S", datestr));
|
||||
}
|
||||
}
|
||||
|
||||
case PDFIO_VALTYPE_DICT :
|
||||
return (_pdfioDictWrite(v->value.dict, obj, length));
|
||||
return (_pdfioDictWrite(cb, cbdata, obj, v->value.dict, length));
|
||||
|
||||
case PDFIO_VALTYPE_INDIRECT :
|
||||
return (_pdfioFilePrintf(pdf, " %lu %u R", (unsigned long)v->value.indirect.number, v->value.indirect.generation));
|
||||
return ((cb)(cbdata, " %lu %u R", (unsigned long)v->value.indirect.number, v->value.indirect.generation));
|
||||
|
||||
case PDFIO_VALTYPE_NAME :
|
||||
return (_pdfioFilePrintf(pdf, "%N", v->value.name));
|
||||
return ((cb)(cbdata, "%N", v->value.name));
|
||||
|
||||
case PDFIO_VALTYPE_NULL :
|
||||
return (_pdfioFilePuts(pdf, " null"));
|
||||
return ((cb)(cbdata, " null"));
|
||||
|
||||
case PDFIO_VALTYPE_NUMBER :
|
||||
return (_pdfioFilePrintf(pdf, " %.6f", v->value.number));
|
||||
return ((cb)(cbdata, " %.6f", v->value.number));
|
||||
|
||||
case PDFIO_VALTYPE_STRING :
|
||||
if (obj && pdf->encryption)
|
||||
if (obj && obj->pdf->encryption)
|
||||
{
|
||||
// Write encrypted string...
|
||||
uint8_t *temp = NULL, // Encrypted bytes
|
||||
*tempptr; // Pointer into encrypted bytes
|
||||
_pdfio_crypto_ctx_t ctx; // Encryption context
|
||||
_pdfio_crypto_cb_t cb; // Encryption callback
|
||||
_pdfio_crypto_cb_t ccb; // Encryption callback
|
||||
size_t len = strlen(v->value.string),
|
||||
// Length of value
|
||||
ivlen, // Number of initialization vector bytes
|
||||
@@ -759,42 +761,42 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
|
||||
if (len > PDFIO_MAX_STRING)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to write encrypted string - too long.");
|
||||
_pdfioFileError(obj->pdf, "Unable to write encrypted string - too long.");
|
||||
return (false);
|
||||
}
|
||||
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(obj->pdf)) == NULL)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to write encrypted string - out of memory.");
|
||||
_pdfioFileError(obj->pdf, "Unable to write encrypted string - out of memory.");
|
||||
return (false);
|
||||
}
|
||||
|
||||
cb = _pdfioCryptoMakeWriter(pdf, obj, &ctx, temp, &ivlen);
|
||||
tempbytes = (cb)(&ctx, temp + ivlen, (const uint8_t *)v->value.string, len) + ivlen;
|
||||
ccb = _pdfioCryptoMakeWriter(obj->pdf, obj, &ctx, temp, &ivlen);
|
||||
tempbytes = (ccb)(&ctx, temp + ivlen, (const uint8_t *)v->value.string, len) + ivlen;
|
||||
|
||||
if (!_pdfioFilePuts(pdf, "<"))
|
||||
if (!(cb)(cbdata, "<"))
|
||||
goto strdone;
|
||||
|
||||
for (tempptr = temp; tempbytes > 1; tempbytes -= 2, tempptr += 2)
|
||||
{
|
||||
if (!_pdfioFilePrintf(pdf, "%02X%02X", tempptr[0], tempptr[1]))
|
||||
if (!(cb)(cbdata, "%02X%02X", tempptr[0], tempptr[1]))
|
||||
goto strdone;
|
||||
}
|
||||
|
||||
if (tempbytes > 0 && !_pdfioFilePrintf(pdf, "%02X", *tempptr))
|
||||
if (tempbytes > 0 && !(cb)(cbdata, "%02X", *tempptr))
|
||||
goto strdone;
|
||||
|
||||
ret = _pdfioFilePuts(pdf, ">");
|
||||
ret = (cb)(cbdata, ">");
|
||||
|
||||
strdone :
|
||||
|
||||
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||
_pdfioStringFreeBuffer(obj->pdf, (char *)temp);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write unencrypted string...
|
||||
return (_pdfioFilePrintf(pdf, "%S", v->value.string));
|
||||
return ((cb)(cbdata, "%S", v->value.string));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user