Compare commits

...

3 Commits

Author SHA1 Message Date
Michael R Sweet
986c5f0438
Update docos. 2024-06-24 11:51:50 -04:00
Michael R Sweet
a81907bdb9
Refactor get_info_string to rely on pdfioDictGetString to convert binary strings to regular ones. 2024-06-24 11:49:38 -04:00
Michael R Sweet
63a7a2cdbd
Add unit tests for new pdfioFileGetCatalog API (Issue #67)
Fix pdfioDictGetString to convert (formerly) encrypted binary strings to
regular strings.
2024-06-24 11:46:15 -04:00
5 changed files with 331 additions and 212 deletions

View File

@ -1,4 +1,4 @@
.TH pdfio 3 "pdf read/write library" "2024-01-24" "pdf read/write library" .TH pdfio 3 "pdf read/write library" "2024-06-24" "pdf read/write library"
.SH NAME .SH NAME
pdfio \- pdf read/write library pdfio \- pdf read/write library
.SH Introduction .SH Introduction
@ -2148,7 +2148,7 @@ pdfio_file_t * pdfioFileCreate (
pdfio_rect_t *media_box, pdfio_rect_t *media_box,
pdfio_rect_t *crop_box, pdfio_rect_t *crop_box,
pdfio_error_cb_t error_cb, pdfio_error_cb_t error_cb,
void *error_data void *error_cbdata
); );
.fi .fi
.PP .PP
@ -2162,7 +2162,7 @@ The "media_box" and "crop_box" arguments specify the default MediaBox and
CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size
of 8.27x11in (the intersection of US Letter and ISO A4) is used. of 8.27x11in (the intersection of US Letter and ISO A4) is used.
.PP .PP
The "error_cb" and "error_data" arguments specify an error handler callback The "error_cb" and "error_cbdata" arguments specify an error handler callback
and its data pointer - if \fBNULL\fR the default error handler is used that and its data pointer - if \fBNULL\fR the default error handler is used that
writes error messages to \fBstderr\fR. writes error messages to \fBstderr\fR.
.SS pdfioFileCreateArrayObj .SS pdfioFileCreateArrayObj
@ -2325,23 +2325,23 @@ Create a PDF file through an output callback.
.nf .nf
pdfio_file_t * pdfioFileCreateOutput ( pdfio_file_t * pdfioFileCreateOutput (
pdfio_output_cb_t output_cb, pdfio_output_cb_t output_cb,
void *output_ctx, void *output_cbdata,
const char *version, const char *version,
pdfio_rect_t *media_box, pdfio_rect_t *media_box,
pdfio_rect_t *crop_box, pdfio_rect_t *crop_box,
pdfio_error_cb_t error_cb, pdfio_error_cb_t error_cb,
void *error_data void *error_cbdata
); );
.fi .fi
.PP .PP
This function creates a new PDF file that is streamed though an output This function creates a new PDF file that is streamed though an output
callback. The "output_cb" and "output_ctx" arguments specify the output callback. The "output_cb" and "output_cbdata" arguments specify the output
callback and its context pointer which is called whenever data needs to be callback and its data pointer which is called whenever data needs to be
written: written:
.PP .PP
.nf .nf
ssize_t ssize_t
output_cb(void *output_ctx, const void *buffer, size_t bytes) output_cb(void *output_cbdata, const void *buffer, size_t bytes)
{ {
// Write buffer to output and return the number of bytes written // Write buffer to output and return the number of bytes written
} }
@ -2355,7 +2355,7 @@ The "media_box" and "crop_box" arguments specify the default MediaBox and
CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size CropBox for pages in the PDF file - if \fBNULL\fR then a default "Universal" size
of 8.27x11in (the intersection of US Letter and ISO A4) is used. of 8.27x11in (the intersection of US Letter and ISO A4) is used.
.PP .PP
The "error_cb" and "error_data" arguments specify an error handler callback The "error_cb" and "error_cbdata" arguments specify an error handler callback
and its data pointer - if \fBNULL\fR the default error handler is used that and its data pointer - if \fBNULL\fR the default error handler is used that
writes error messages to \fBstderr\fR. writes error messages to \fBstderr\fR.
.PP .PP
@ -2397,7 +2397,7 @@ pdfio_file_t * pdfioFileCreateTemporary (
pdfio_rect_t *media_box, pdfio_rect_t *media_box,
pdfio_rect_t *crop_box, pdfio_rect_t *crop_box,
pdfio_error_cb_t error_cb, pdfio_error_cb_t error_cb,
void *error_data void *error_cbdata
); );
.fi .fi
.SS pdfioFileFindObj .SS pdfioFileFindObj
@ -2420,6 +2420,16 @@ const char * pdfioFileGetAuthor (
pdfio_file_t *pdf pdfio_file_t *pdf
); );
.fi .fi
.SS pdfioFileGetCatalog
Get the document catalog dictionary.
.PP
.nf
pdfio_dict_t * pdfioFileGetCatalog (
pdfio_file_t *pdf
);
.fi
.PP
.SS pdfioFileGetCreationDate .SS pdfioFileGetCreationDate
Get the creation date for a PDF file. Get the creation date for a PDF file.
.PP .PP
@ -2545,22 +2555,22 @@ Open a PDF file for reading.
pdfio_file_t * pdfioFileOpen ( pdfio_file_t * pdfioFileOpen (
const char *filename, const char *filename,
pdfio_password_cb_t password_cb, pdfio_password_cb_t password_cb,
void *password_data, void *password_cbdata,
pdfio_error_cb_t error_cb, pdfio_error_cb_t error_cb,
void *error_data void *error_cbdata
); );
.fi .fi
.PP .PP
This function opens an existing PDF file. The "filename" argument specifies This function opens an existing PDF file. The "filename" argument specifies
the name of the PDF file to create. the name of the PDF file to create.
.PP .PP
The "password_cb" and "password_data" arguments specify a password callback The "password_cb" and "password_cbdata" arguments specify a password callback
and its data pointer for PDF files that use one of the standard Adobe and its data pointer for PDF files that use one of the standard Adobe
"security" handlers. The callback returns a password string or \fBNULL\fR to "security" handlers. The callback returns a password string or \fBNULL\fR to
cancel the open. If \fBNULL\fR is specified for the callback function and the cancel the open. If \fBNULL\fR is specified for the callback function and the
PDF file requires a password, the open will always fail. PDF file requires a password, the open will always fail.
.PP .PP
The "error_cb" and "error_data" arguments specify an error handler callback The "error_cb" and "error_cbdata" arguments specify an error handler callback
and its data pointer - if \fBNULL\fR the default error handler is used that and its data pointer - if \fBNULL\fR the default error handler is used that
writes error messages to \fBstderr\fR. writes error messages to \fBstderr\fR.
.SS pdfioFileSetAuthor .SS pdfioFileSetAuthor

File diff suppressed because it is too large Load Diff

View File

@ -426,9 +426,27 @@ pdfioDictGetString(pdfio_dict_t *dict, // I - Dictionary
if (value && value->type == PDFIO_VALTYPE_STRING) if (value && value->type == PDFIO_VALTYPE_STRING)
{
return (value->value.string); return (value->value.string);
}
else if (value && value->type == PDFIO_VALTYPE_BINARY && value->value.binary.datalen < 4096)
{
// Convert binary string to regular string...
char temp[4096]; // Temporary string
memcpy(temp, value->value.binary.data, value->value.binary.datalen);
temp[value->value.binary.datalen] = '\0';
free(value->value.binary.data);
value->type = PDFIO_VALTYPE_STRING;
value->value.string = pdfioStringCreate(dict->pdf, temp);
return (value->value.string);
}
else else
{
return (NULL); return (NULL);
}
} }

View File

@ -1412,36 +1412,13 @@ get_info_string(pdfio_file_t *pdf, // I - PDF file
const char *key) // I - Dictionary key const char *key) // I - Dictionary key
{ {
pdfio_dict_t *dict; // Info dictionary pdfio_dict_t *dict; // Info dictionary
_pdfio_value_t *value; // Value
// Range check input... // Range check input...
if (!pdf || !pdf->info_obj || (dict = pdfioObjGetDict(pdf->info_obj)) == NULL || (value = _pdfioDictGetValue(dict, key)) == NULL) if (!pdf || !pdf->info_obj || (dict = pdfioObjGetDict(pdf->info_obj)) == NULL)
return (NULL); return (NULL);
// If we already have a value, return it...
if (value->type == PDFIO_VALTYPE_NAME || value->type == PDFIO_VALTYPE_STRING)
{
return (value->value.string);
}
else if (value->type == PDFIO_VALTYPE_BINARY && value->value.binary.datalen < 4096)
{
// Convert binary string to regular string...
char temp[4096]; // Temporary string
memcpy(temp, value->value.binary.data, value->value.binary.datalen);
temp[value->value.binary.datalen] = '\0';
free(value->value.binary.data);
value->type = PDFIO_VALTYPE_STRING;
value->value.string = pdfioStringCreate(pdf, temp);
return (value->value.string);
}
else else
{ return (pdfioDictGetString(dict, key));
// Something else that is not a string...
return (NULL);
}
} }

View File

@ -1308,6 +1308,7 @@ read_unit_file(const char *filename, // I - File to read
bool is_output) // I - File written with output callback? bool is_output) // I - File written with output callback?
{ {
pdfio_file_t *pdf; // PDF file pdfio_file_t *pdf; // PDF file
pdfio_dict_t *catalog; // Catalog dictionary
size_t i; // Looping var size_t i; // Looping var
const char *s; // String const char *s; // String
bool error = false; // Error callback data bool error = false; // Error callback data
@ -1320,6 +1321,83 @@ read_unit_file(const char *filename, // I - File to read
else else
return (1); return (1);
// Get the root object/catalog dictionary
fputs("pdfioFileGetCatalog: ", stdout);
if ((catalog = pdfioFileGetCatalog(pdf)) != NULL)
{
puts("PASS");
}
else
{
puts("FAIL (got NULL, expected dictionary)");
return (1);
}
// Verify some catalog values...
fputs("pdfioDictGetName(PageLayout): ", stdout);
if ((s = pdfioDictGetName(catalog, "PageLayout")) != NULL && !strcmp(s, "SinglePage"))
{
puts("PASS");
}
else if (s)
{
printf("FAIL (got '%s', expected 'SinglePage')\n", s);
return (1);
}
else
{
puts("FAIL (got NULL, expected 'SinglePage')");
return (1);
}
fputs("pdfioDictGetName(PageLayout): ", stdout);
if ((s = pdfioDictGetName(catalog, "PageLayout")) != NULL && !strcmp(s, "SinglePage"))
{
puts("PASS");
}
else if (s)
{
printf("FAIL (got '%s', expected 'SinglePage')\n", s);
return (1);
}
else
{
puts("FAIL (got NULL, expected 'SinglePage')");
return (1);
}
fputs("pdfioDictGetName(PageMode): ", stdout);
if ((s = pdfioDictGetName(catalog, "PageMode")) != NULL && !strcmp(s, "UseThumbs"))
{
puts("PASS");
}
else if (s)
{
printf("FAIL (got '%s', expected 'UseThumbs')\n", s);
return (1);
}
else
{
puts("FAIL (got NULL, expected 'UseThumbs')");
return (1);
}
fputs("pdfioDictGetString(Lang): ", stdout);
if ((s = pdfioDictGetString(catalog, "Lang")) != NULL && !strcmp(s, "en"))
{
puts("PASS");
}
else if (s)
{
printf("FAIL (got '%s', expected 'en')\n", s);
return (1);
}
else
{
puts("FAIL (got NULL, expected 'en')");
return (1);
}
// Verify metadata... // Verify metadata...
fputs("pdfioFileGetAuthor: ", stdout); fputs("pdfioFileGetAuthor: ", stdout);
if ((s = pdfioFileGetAuthor(pdf)) != NULL && !strcmp(s, "Michael R Sweet")) if ((s = pdfioFileGetAuthor(pdf)) != NULL && !strcmp(s, "Michael R Sweet"))
@ -3256,8 +3334,26 @@ write_unit_file(
*gray_jpg, // gray.jpg image *gray_jpg, // gray.jpg image
*helvetica, // Helvetica font *helvetica, // Helvetica font
*page; // Page from test PDF file *page; // Page from test PDF file
pdfio_dict_t *catalog; // Catalog dictionary
// Get the root object/catalog dictionary
fputs("pdfioFileGetCatalog: ", stdout);
if ((catalog = pdfioFileGetCatalog(outpdf)) != NULL)
{
puts("PASS");
}
else
{
puts("FAIL (got NULL, expected dictionary)");
return (1);
}
// Set some catalog values...
pdfioDictSetName(catalog, "PageLayout", "SinglePage");
pdfioDictSetName(catalog, "PageMode", "UseThumbs");
pdfioDictSetString(catalog, "Lang", "en");
// Set info values... // Set info values...
fputs("pdfioFileGet/SetAuthor: ", stdout); fputs("pdfioFileGet/SetAuthor: ", stdout);
pdfioFileSetAuthor(outpdf, "Michael R Sweet"); pdfioFileSetAuthor(outpdf, "Michael R Sweet");