diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | include/qpdf/QUtil.hh | 13 | ||||
-rw-r--r-- | libqpdf/QUtil.cc | 32 | ||||
-rw-r--r-- | libtests/qutil.cc | 7 | ||||
-rw-r--r-- | manual/qpdf-manual.xml | 7 |
5 files changed, 63 insertions, 1 deletions
@@ -1,3 +1,8 @@ +2021-02-07 Jay Berkenbilt <ejb@ql.org> + + * Add new functions QUtil::pipe_file and QUtil::file_provider for + sending the contents of a file through a pipeline as binary data. + 2021-02-04 Jay Berkenbilt <ejb@ql.org> * Add new option --pasword-file=file for reading the decryption diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh index 30a73441..fe18c9b7 100644 --- a/include/qpdf/QUtil.hh +++ b/include/qpdf/QUtil.hh @@ -34,6 +34,7 @@ #include <time.h> class RandomDataProvider; +class Pipeline; namespace QUtil { @@ -119,6 +120,18 @@ namespace QUtil QPDF_DLL void rename_file(char const* oldname, char const* newname); + // Write the contents of filename as a binary file to the + // pipeline. + QPDF_DLL + void + pipe_file(char const* filename, Pipeline* p); + + // Return a function that will send the contents of the given file + // through the given pipeline as binary data. + QPDF_DLL + std::function<void(Pipeline*)> + file_provider(std::string const& filename); + QPDF_DLL char* copy_string(std::string const&); diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc index 5442b5ff..dc847679 100644 --- a/libqpdf/QUtil.cc +++ b/libqpdf/QUtil.cc @@ -7,6 +7,7 @@ #include <qpdf/QPDFSystemError.hh> #include <qpdf/QTC.hh> #include <qpdf/QIntC.hh> +#include <qpdf/Pipeline.hh> #include <cmath> #include <iomanip> @@ -612,6 +613,35 @@ QUtil::rename_file(char const* oldname, char const* newname) #endif } +void +QUtil::pipe_file(char const* filename, Pipeline* p) +{ + // Exercised in test suite by testing file_provider. + FILE* f = safe_fopen(filename, "rb"); + FileCloser fc(f); + size_t len = 0; + int constexpr size = 8192; + unsigned char buf[size]; + while ((len = fread(buf, 1, size, f)) > 0) + { + p->write(buf, len); + } + p->finish(); + if (ferror(f)) + { + throw std::runtime_error( + std::string("failure reading file ") + filename); + } +} + +std::function<void(Pipeline*)> +QUtil::file_provider(std::string const& filename) +{ + return [filename](Pipeline* p) { + pipe_file(filename.c_str(), p); + }; +} + char* QUtil::copy_string(std::string const& str) { @@ -1018,6 +1048,7 @@ QUtil::read_file_into_memory( PointerHolder<char>& file_buf, size_t& size) { FILE* f = safe_fopen(filename, "rb"); + FileCloser fc(f); fseek(f, 0, SEEK_END); size = QIntC::to_size(QUtil::tell(f)); fseek(f, 0, SEEK_SET); @@ -1048,7 +1079,6 @@ QUtil::read_file_into_memory( uint_to_string(size)); } } - fclose(f); } static bool read_char_from_FILE(char& ch, FILE* f) diff --git a/libtests/qutil.cc b/libtests/qutil.cc index abfefce0..bc12a6ea 100644 --- a/libtests/qutil.cc +++ b/libtests/qutil.cc @@ -6,6 +6,7 @@ #include <qpdf/QUtil.hh> #include <qpdf/PointerHolder.hh> #include <qpdf/QPDFSystemError.hh> +#include <qpdf/Pl_Buffer.hh> #include <string.h> #include <limits.h> #include <assert.h> @@ -483,6 +484,12 @@ void read_from_file_test() assert(memcmp(p, "This file is used for qutil testing.", 36) == 0); assert(p[59] == static_cast<char>(13)); assert(memcmp(p + 24641, "very long.", 10) == 0); + Pl_Buffer b2("buffer"); + // QUtil::file_provider also exercises QUtil::pipe_file + QUtil::file_provider("other-file")(&b2); + auto buf2 = b2.getBuffer(); + assert(buf2->getSize() == size); + assert(memcmp(buf2->getBuffer(), p, size) == 0); } void assert_hex_encode(std::string const& input, std::string const& expected) diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml index 09ba7408..39f3d969 100644 --- a/manual/qpdf-manual.xml +++ b/manual/qpdf-manual.xml @@ -4964,6 +4964,13 @@ print "\n"; read/write implementation of name and number trees. </para> </listitem> + <listitem> + <para> + Add new functions <function>QUtil::pipe_file</function> and + <function>QUtil::file_provider</function> for sending the + contents of a file through a pipeline as binary data. + </para> + </listitem> </itemizedlist> </listitem> <listitem> |