Add _pdfioStringPrintf function and support for using a string buffer to collect an object's value (Issue #101)

This commit is contained in:
Michael R Sweet
2026-01-18 19:51:56 -05:00
parent e61e08b5d2
commit a37455c009
3 changed files with 61 additions and 14 deletions

View File

@@ -277,9 +277,11 @@ typedef struct _pdfio_objmap_s // PDF object map
typedef struct _pdfio_strbuf_s // PDF string buffer
{
struct _pdfio_strbuf_s *next; // Next string buffer
pdfio_file_t *pdf; // PDF file
bool bufused; // Is this string buffer being used?
char buffer[PDFIO_MAX_STRING + 32];
char buffer[PDFIO_MAX_STRING + 32],
// String buffer
*bufptr; // Pointer into buffer
} _pdfio_strbuf_t;
struct _pdfio_file_s // PDF file structure
@@ -468,9 +470,10 @@ extern bool _pdfioObjWriteHeader(pdfio_obj_t *obj) _PDFIO_INTERNAL;
extern pdfio_stream_t *_pdfioStreamCreate(pdfio_obj_t *obj, pdfio_obj_t *length_obj, size_t cbsize, pdfio_filter_t compression) _PDFIO_INTERNAL;
extern pdfio_stream_t *_pdfioStreamOpen(pdfio_obj_t *obj, bool decode) _PDFIO_INTERNAL;
extern char *_pdfioStringAllocBuffer(pdfio_file_t *pdf);
extern char *_pdfioStringAllocBuffer(pdfio_file_t *pdf, _pdfio_strbuf_t **bptr);
extern void _pdfioStringFreeBuffer(pdfio_file_t *pdf, char *buffer);
extern bool _pdfioStringIsAllocated(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL;
extern bool _pdfioStringPrintf(_pdfio_strbuf_t *bptr, const char *format, ...) _PDFIO_INTERNAL;
extern void _pdfioTokenClear(_pdfio_token_t *tb) _PDFIO_INTERNAL;
extern void _pdfioTokenFlush(_pdfio_token_t *tb) _PDFIO_INTERNAL;

View File

@@ -674,7 +674,8 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
char * // O - Buffer or `NULL` on error
_pdfioStringAllocBuffer(
pdfio_file_t *pdf) // I - PDF file
pdfio_file_t *pdf, // I - PDF file
_pdfio_strbuf_t **bptr) // O - String buffer pointer
{
_pdfio_strbuf_t *current; // Current string buffer
@@ -683,21 +684,34 @@ _pdfioStringAllocBuffer(
for (current = pdf->strbuffers; current; current = current->next)
{
if (!current->bufused)
{
current->bufused = true;
return (current->buffer);
}
goto done;
}
// Didn't find one, allocate a new one...
if ((current = calloc(1, sizeof(_pdfio_strbuf_t))) == NULL)
{
if (bptr)
*bptr = NULL;
return (NULL);
}
// Add to the linked list of string buffers...
current->next = pdf->strbuffers;
current->pdf = pdf;
current->next = pdf->strbuffers;
pdf->strbuffers = current;
// Claim and return the free string buffer...
done:
current->bufused = true;
pdf->strbuffers = current;
if (bptr)
{
*bptr = current;
current->buffer[0] = '\0';
current->bufptr = current->buffer;
}
return (current->buffer);
}
@@ -857,6 +871,36 @@ _pdfioStringIsAllocated(
}
//
// '_pdfioStringPrintf()' - Append a formatted string to a string buffer.
//
bool // O - `true` on success, `false` on failure
_pdfioStringPrintf(
_pdfio_strbuf_t *bptr, // I - String buffer
const char *format, // I - Format string
...) // I - Additional arguments as needed
{
va_list ap; // Pointer to additional arguments
size_t remaining; // Remaining bytes
ssize_t bytes; // Formatted bytes
// Format the string in the buffer...
va_start(ap, format);
remaining = sizeof(bptr->buffer) - (size_t)(bptr->bufptr - bptr->buffer);
bytes = _pdfio_vsnprintf(bptr->pdf, bptr->bufptr, remaining, format, ap);
va_end(ap);
// Advance the current position in the buffer and return.
bptr->bufptr += strlen(bptr->bufptr);
return (bytes < (ssize_t)remaining && bytes >= 0);
}
//
// 'find_string()' - Find an element in the array.
//

View File

@@ -160,7 +160,7 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
_pdfioFileError(pdf, "Unable to read encrypted binary string - too long.");
return (false);
}
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf, /*bptr*/NULL)) == NULL)
{
_pdfioFileError(pdf, "Unable to read encrypted binary string - out of memory.");
return (false);
@@ -191,7 +191,7 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
_pdfioFileError(pdf, "Unable to read encrypted string - too long.");
return (false);
}
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf, /*bptr*/NULL)) == NULL)
{
_pdfioFileError(pdf, "Unable to read encrypted binary string - out of memory.");
return (false);
@@ -341,7 +341,7 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
size_t depth) // I - Depth of value
{
_pdfio_value_t *ret = NULL; // Return value
char *token = _pdfioStringAllocBuffer(pdf);
char *token = _pdfioStringAllocBuffer(pdf, /*bptr*/NULL);
// Token buffer
time_t timeval; // Date/time value
#ifdef DEBUG
@@ -638,7 +638,7 @@ _pdfioValueWrite(
_pdfioFileError(obj->pdf, "Unable to write encrypted binary string - too long.");
return (false);
}
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(obj->pdf)) == NULL)
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(obj->pdf, /*bptr*/NULL)) == NULL)
{
_pdfioFileError(obj->pdf, "Unable to write encrypted binary string - out of memory.");
return (false);
@@ -764,7 +764,7 @@ _pdfioValueWrite(
_pdfioFileError(obj->pdf, "Unable to write encrypted string - too long.");
return (false);
}
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(obj->pdf)) == NULL)
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(obj->pdf, /*bptr*/NULL)) == NULL)
{
_pdfioFileError(obj->pdf, "Unable to write encrypted string - out of memory.");
return (false);