Commit 553ac7f353c7043806ec0de70d8630f5cd0a7bb8
1 parent
efdd46da
Add QUtil::pipe_file and QUtil::file_provider
Showing
5 changed files
with
63 additions
and
1 deletions
ChangeLog
| 1 | +2021-02-07 Jay Berkenbilt <ejb@ql.org> | ||
| 2 | + | ||
| 3 | + * Add new functions QUtil::pipe_file and QUtil::file_provider for | ||
| 4 | + sending the contents of a file through a pipeline as binary data. | ||
| 5 | + | ||
| 1 | 2021-02-04 Jay Berkenbilt <ejb@ql.org> | 6 | 2021-02-04 Jay Berkenbilt <ejb@ql.org> |
| 2 | 7 | ||
| 3 | * Add new option --pasword-file=file for reading the decryption | 8 | * Add new option --pasword-file=file for reading the decryption |
include/qpdf/QUtil.hh
| @@ -34,6 +34,7 @@ | @@ -34,6 +34,7 @@ | ||
| 34 | #include <time.h> | 34 | #include <time.h> |
| 35 | 35 | ||
| 36 | class RandomDataProvider; | 36 | class RandomDataProvider; |
| 37 | +class Pipeline; | ||
| 37 | 38 | ||
| 38 | namespace QUtil | 39 | namespace QUtil |
| 39 | { | 40 | { |
| @@ -119,6 +120,18 @@ namespace QUtil | @@ -119,6 +120,18 @@ namespace QUtil | ||
| 119 | QPDF_DLL | 120 | QPDF_DLL |
| 120 | void rename_file(char const* oldname, char const* newname); | 121 | void rename_file(char const* oldname, char const* newname); |
| 121 | 122 | ||
| 123 | + // Write the contents of filename as a binary file to the | ||
| 124 | + // pipeline. | ||
| 125 | + QPDF_DLL | ||
| 126 | + void | ||
| 127 | + pipe_file(char const* filename, Pipeline* p); | ||
| 128 | + | ||
| 129 | + // Return a function that will send the contents of the given file | ||
| 130 | + // through the given pipeline as binary data. | ||
| 131 | + QPDF_DLL | ||
| 132 | + std::function<void(Pipeline*)> | ||
| 133 | + file_provider(std::string const& filename); | ||
| 134 | + | ||
| 122 | QPDF_DLL | 135 | QPDF_DLL |
| 123 | char* copy_string(std::string const&); | 136 | char* copy_string(std::string const&); |
| 124 | 137 |
libqpdf/QUtil.cc
| @@ -7,6 +7,7 @@ | @@ -7,6 +7,7 @@ | ||
| 7 | #include <qpdf/QPDFSystemError.hh> | 7 | #include <qpdf/QPDFSystemError.hh> |
| 8 | #include <qpdf/QTC.hh> | 8 | #include <qpdf/QTC.hh> |
| 9 | #include <qpdf/QIntC.hh> | 9 | #include <qpdf/QIntC.hh> |
| 10 | +#include <qpdf/Pipeline.hh> | ||
| 10 | 11 | ||
| 11 | #include <cmath> | 12 | #include <cmath> |
| 12 | #include <iomanip> | 13 | #include <iomanip> |
| @@ -612,6 +613,35 @@ QUtil::rename_file(char const* oldname, char const* newname) | @@ -612,6 +613,35 @@ QUtil::rename_file(char const* oldname, char const* newname) | ||
| 612 | #endif | 613 | #endif |
| 613 | } | 614 | } |
| 614 | 615 | ||
| 616 | +void | ||
| 617 | +QUtil::pipe_file(char const* filename, Pipeline* p) | ||
| 618 | +{ | ||
| 619 | + // Exercised in test suite by testing file_provider. | ||
| 620 | + FILE* f = safe_fopen(filename, "rb"); | ||
| 621 | + FileCloser fc(f); | ||
| 622 | + size_t len = 0; | ||
| 623 | + int constexpr size = 8192; | ||
| 624 | + unsigned char buf[size]; | ||
| 625 | + while ((len = fread(buf, 1, size, f)) > 0) | ||
| 626 | + { | ||
| 627 | + p->write(buf, len); | ||
| 628 | + } | ||
| 629 | + p->finish(); | ||
| 630 | + if (ferror(f)) | ||
| 631 | + { | ||
| 632 | + throw std::runtime_error( | ||
| 633 | + std::string("failure reading file ") + filename); | ||
| 634 | + } | ||
| 635 | +} | ||
| 636 | + | ||
| 637 | +std::function<void(Pipeline*)> | ||
| 638 | +QUtil::file_provider(std::string const& filename) | ||
| 639 | +{ | ||
| 640 | + return [filename](Pipeline* p) { | ||
| 641 | + pipe_file(filename.c_str(), p); | ||
| 642 | + }; | ||
| 643 | +} | ||
| 644 | + | ||
| 615 | char* | 645 | char* |
| 616 | QUtil::copy_string(std::string const& str) | 646 | QUtil::copy_string(std::string const& str) |
| 617 | { | 647 | { |
| @@ -1018,6 +1048,7 @@ QUtil::read_file_into_memory( | @@ -1018,6 +1048,7 @@ QUtil::read_file_into_memory( | ||
| 1018 | PointerHolder<char>& file_buf, size_t& size) | 1048 | PointerHolder<char>& file_buf, size_t& size) |
| 1019 | { | 1049 | { |
| 1020 | FILE* f = safe_fopen(filename, "rb"); | 1050 | FILE* f = safe_fopen(filename, "rb"); |
| 1051 | + FileCloser fc(f); | ||
| 1021 | fseek(f, 0, SEEK_END); | 1052 | fseek(f, 0, SEEK_END); |
| 1022 | size = QIntC::to_size(QUtil::tell(f)); | 1053 | size = QIntC::to_size(QUtil::tell(f)); |
| 1023 | fseek(f, 0, SEEK_SET); | 1054 | fseek(f, 0, SEEK_SET); |
| @@ -1048,7 +1079,6 @@ QUtil::read_file_into_memory( | @@ -1048,7 +1079,6 @@ QUtil::read_file_into_memory( | ||
| 1048 | uint_to_string(size)); | 1079 | uint_to_string(size)); |
| 1049 | } | 1080 | } |
| 1050 | } | 1081 | } |
| 1051 | - fclose(f); | ||
| 1052 | } | 1082 | } |
| 1053 | 1083 | ||
| 1054 | static bool read_char_from_FILE(char& ch, FILE* f) | 1084 | static bool read_char_from_FILE(char& ch, FILE* f) |
libtests/qutil.cc
| @@ -6,6 +6,7 @@ | @@ -6,6 +6,7 @@ | ||
| 6 | #include <qpdf/QUtil.hh> | 6 | #include <qpdf/QUtil.hh> |
| 7 | #include <qpdf/PointerHolder.hh> | 7 | #include <qpdf/PointerHolder.hh> |
| 8 | #include <qpdf/QPDFSystemError.hh> | 8 | #include <qpdf/QPDFSystemError.hh> |
| 9 | +#include <qpdf/Pl_Buffer.hh> | ||
| 9 | #include <string.h> | 10 | #include <string.h> |
| 10 | #include <limits.h> | 11 | #include <limits.h> |
| 11 | #include <assert.h> | 12 | #include <assert.h> |
| @@ -483,6 +484,12 @@ void read_from_file_test() | @@ -483,6 +484,12 @@ void read_from_file_test() | ||
| 483 | assert(memcmp(p, "This file is used for qutil testing.", 36) == 0); | 484 | assert(memcmp(p, "This file is used for qutil testing.", 36) == 0); |
| 484 | assert(p[59] == static_cast<char>(13)); | 485 | assert(p[59] == static_cast<char>(13)); |
| 485 | assert(memcmp(p + 24641, "very long.", 10) == 0); | 486 | assert(memcmp(p + 24641, "very long.", 10) == 0); |
| 487 | + Pl_Buffer b2("buffer"); | ||
| 488 | + // QUtil::file_provider also exercises QUtil::pipe_file | ||
| 489 | + QUtil::file_provider("other-file")(&b2); | ||
| 490 | + auto buf2 = b2.getBuffer(); | ||
| 491 | + assert(buf2->getSize() == size); | ||
| 492 | + assert(memcmp(buf2->getBuffer(), p, size) == 0); | ||
| 486 | } | 493 | } |
| 487 | 494 | ||
| 488 | void assert_hex_encode(std::string const& input, std::string const& expected) | 495 | void assert_hex_encode(std::string const& input, std::string const& expected) |
manual/qpdf-manual.xml
| @@ -4964,6 +4964,13 @@ print "\n"; | @@ -4964,6 +4964,13 @@ print "\n"; | ||
| 4964 | read/write implementation of name and number trees. | 4964 | read/write implementation of name and number trees. |
| 4965 | </para> | 4965 | </para> |
| 4966 | </listitem> | 4966 | </listitem> |
| 4967 | + <listitem> | ||
| 4968 | + <para> | ||
| 4969 | + Add new functions <function>QUtil::pipe_file</function> and | ||
| 4970 | + <function>QUtil::file_provider</function> for sending the | ||
| 4971 | + contents of a file through a pipeline as binary data. | ||
| 4972 | + </para> | ||
| 4973 | + </listitem> | ||
| 4967 | </itemizedlist> | 4974 | </itemizedlist> |
| 4968 | </listitem> | 4975 | </listitem> |
| 4969 | <listitem> | 4976 | <listitem> |