diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h index f3f02e97..d83adcca 100644 --- a/include/qpdf/qpdf-c.h +++ b/include/qpdf/qpdf-c.h @@ -183,7 +183,21 @@ extern "C" { QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename, char const* password); - /* Read functions below must be called after qpdf_read. */ + /* Calling qpdf_read_memory causes processMemoryFile to be called + * in the C++ API. Otherwise, it behaves in the same way as + * qpdf_read. The description argument will be used in place of + * the file name in any error or warning messages generated by the + * library. + */ + QPDF_DLL + QPDF_ERROR_CODE qpdf_read_memory(qpdf_data qpdf, + char const* description, + char const* buffer, + unsigned long size, + char const* password); + + /* Read functions below must be called after qpdf_read or + * qpdf_read_memory. */ /* Return the version of the PDF file. */ QPDF_DLL diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index d7776d21..10260753 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -28,7 +28,9 @@ struct _qpdf_data std::string tmp_string; // Parameters for functions we call - char const* filename; + char const* filename; // or description + char const* buffer; + unsigned long size; char const* password; }; @@ -50,6 +52,13 @@ static void call_read(qpdf_data qpdf) qpdf->qpdf->processFile(qpdf->filename, qpdf->password); } +// must set qpdf->filename, qpdf->buffer, qpdf->size, and qpdf->password +static void call_read_memory(qpdf_data qpdf) +{ + qpdf->qpdf->processMemoryFile(qpdf->filename, qpdf->buffer, + qpdf->size, qpdf->password); +} + // must set qpdf->filename static void call_init_write(qpdf_data qpdf) { @@ -244,6 +253,22 @@ QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename, return status; } +QPDF_ERROR_CODE qpdf_read_memory(qpdf_data qpdf, + char const* description, + char const* buffer, + unsigned long size, + char const* password) +{ + QPDF_ERROR_CODE status = QPDF_SUCCESS; + qpdf->filename = description; + qpdf->buffer = buffer; + qpdf->size = size; + qpdf->password = password; + status = trap_errors(qpdf, &call_read_memory); + QTC::TC("qpdf", "qpdf-c called qpdf_read_memory", status); + return status; +} + char const* qpdf_get_pdf_version(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_get_pdf_version"); diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml index 0c193e20..a855234d 100644 --- a/manual/qpdf-manual.xml +++ b/manual/qpdf-manual.xml @@ -5,8 +5,8 @@ - - + + ]> @@ -2074,6 +2074,21 @@ print "\n"; ChangeLog in the source distribution. + + 2.2.2: October 4, 2010 + + + + + Add new function qpdf_read_memory + to the C API to call + QPDF::processMemoryFile. This was an + omission in qpdf 2.2.1. + + + + + 2.2.1: October 1, 2010 diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c index 30e7af2f..0797d9a2 100644 --- a/qpdf/qpdf-ctest.c +++ b/qpdf/qpdf-ctest.c @@ -3,7 +3,9 @@ #include #include #include +#include +static char* whoami = 0; static qpdf_data qpdf = 0; static void report_errors() @@ -42,6 +44,57 @@ static void report_errors() } } +static void read_file_into_memory(char const* filename, + char** buf, unsigned long* size) +{ + char* buf_p = 0; + FILE* f = NULL; + size_t bytes_read = 0; + size_t len = 0; + + f = fopen(filename, "rb"); + if (f == NULL) + { + fprintf(stderr, "%s: unable to open %s: %s\n", + whoami, filename, strerror(errno)); + exit(2); + } + fseek(f, 0, SEEK_END); + *size = (unsigned long) ftell(f); + fseek(f, 0, SEEK_SET); + *buf = malloc(*size); + if (*buf == NULL) + { + fprintf(stderr, "%s: unable to allocate %lu bytes\n", + whoami, *size); + exit(2); + } + buf_p = *buf; + bytes_read = 0; + len = 0; + while ((len = fread(buf_p + bytes_read, 1, *size - bytes_read, f)) > 0) + { + bytes_read += len; + } + if (bytes_read != *size) + { + if (ferror(f)) + { + fprintf(stderr, "%s: failure reading file %s into memory:", + whoami, filename); + } + else + { + fprintf(stderr, "%s: premature EOF reading file %s:", + whoami, filename); + } + fprintf(stderr, " read %lu, wanted %lu\n", + (unsigned long) bytes_read, (unsigned long) size); + exit(2); + } + fclose(f); +} + static void test01(char const* infile, char const* password, char const* outfile, @@ -135,7 +188,10 @@ static void test06(char const* infile, char const* outfile, char const* outfile2) { - qpdf_read(qpdf, infile, password); + char* buf = NULL; + unsigned long size = 0; + read_file_into_memory(infile, &buf, &size); + qpdf_read_memory(qpdf, infile, buf, size, password); qpdf_init_write(qpdf, outfile); qpdf_set_static_ID(qpdf, QPDF_TRUE); qpdf_set_object_stream_mode(qpdf, qpdf_o_generate); @@ -271,7 +327,6 @@ static void test15(char const* infile, int main(int argc, char* argv[]) { - char* whoami = 0; char* p = 0; int n = 0; char const* infile = 0; diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index 85455a68..f0b3e06a 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -186,3 +186,4 @@ QPDFObjectHandle append page contents 0 QPDF_Stream getRawStreamData 0 QPDF_Stream getStreamData 0 QPDF_Stream expand filter abbreviation 0 +qpdf-c called qpdf_read_memory 0