Commit bc1c4bb57864c4dbe9b7e42a77e0653c0d473071
1 parent
ed6a56a3
Add QPDF::processFile that takes an open FILE*
Showing
5 changed files
with
58 additions
and
3 deletions
ChangeLog
include/qpdf/QPDF.hh
| ... | ... | @@ -52,6 +52,14 @@ class QPDF |
| 52 | 52 | QPDF_DLL |
| 53 | 53 | void processFile(char const* filename, char const* password = 0); |
| 54 | 54 | |
| 55 | + // Parse a PDF from a stdio FILE*. The FILE must be open in | |
| 56 | + // binary mode and must be seekable. It may be open read only. | |
| 57 | + // This works exactly like processFile except that the PDF file is | |
| 58 | + // read from an already opened FILE*. The caller is responsible | |
| 59 | + // for closing the file. | |
| 60 | + QPDF_DLL | |
| 61 | + void processFile(FILE* file, char const* password = 0); | |
| 62 | + | |
| 55 | 63 | // Parse a PDF file loaded into a memory buffer. This works |
| 56 | 64 | // exactly like processFile except that the PDF file is in memory |
| 57 | 65 | // instead of on disk. The description appears in any warning or |
| ... | ... | @@ -400,6 +408,7 @@ class QPDF |
| 400 | 408 | public: |
| 401 | 409 | FileInputSource(); |
| 402 | 410 | void setFilename(char const* filename); |
| 411 | + void setFile(FILE* filep); | |
| 403 | 412 | virtual ~FileInputSource(); |
| 404 | 413 | virtual std::string const& getName() const; |
| 405 | 414 | virtual off_t tell(); |
| ... | ... | @@ -414,6 +423,7 @@ class QPDF |
| 414 | 423 | |
| 415 | 424 | void destroy(); |
| 416 | 425 | |
| 426 | + bool close_file; | |
| 417 | 427 | std::string filename; |
| 418 | 428 | FILE* file; |
| 419 | 429 | }; | ... | ... |
libqpdf/QPDF.cc
| ... | ... | @@ -80,6 +80,7 @@ QPDF::InputSource::readLine() |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | 82 | QPDF::FileInputSource::FileInputSource() : |
| 83 | + close_file(false), | |
| 83 | 84 | file(0) |
| 84 | 85 | { |
| 85 | 86 | } |
| ... | ... | @@ -89,10 +90,21 @@ QPDF::FileInputSource::setFilename(char const* filename) |
| 89 | 90 | { |
| 90 | 91 | destroy(); |
| 91 | 92 | this->filename = filename; |
| 93 | + this->close_file = true; | |
| 92 | 94 | this->file = QUtil::fopen_wrapper(std::string("open ") + this->filename, |
| 93 | 95 | fopen(this->filename.c_str(), "rb")); |
| 94 | 96 | } |
| 95 | 97 | |
| 98 | +void | |
| 99 | +QPDF::FileInputSource::setFile(FILE* f) | |
| 100 | +{ | |
| 101 | + destroy(); | |
| 102 | + this->filename = "stdio FILE"; | |
| 103 | + this->close_file = false; | |
| 104 | + this->file = f; | |
| 105 | + this->seek(0, SEEK_SET); | |
| 106 | +} | |
| 107 | + | |
| 96 | 108 | QPDF::FileInputSource::~FileInputSource() |
| 97 | 109 | { |
| 98 | 110 | destroy(); |
| ... | ... | @@ -101,7 +113,7 @@ QPDF::FileInputSource::~FileInputSource() |
| 101 | 113 | void |
| 102 | 114 | QPDF::FileInputSource::destroy() |
| 103 | 115 | { |
| 104 | - if (this->file) | |
| 116 | + if (this->file && this->close_file) | |
| 105 | 117 | { |
| 106 | 118 | fclose(this->file); |
| 107 | 119 | this->file = 0; |
| ... | ... | @@ -317,6 +329,15 @@ QPDF::processFile(char const* filename, char const* password) |
| 317 | 329 | } |
| 318 | 330 | |
| 319 | 331 | void |
| 332 | +QPDF::processFile(FILE* filep, char const* password) | |
| 333 | +{ | |
| 334 | + FileInputSource* fi = new FileInputSource(); | |
| 335 | + this->file = fi; | |
| 336 | + fi->setFile(filep); | |
| 337 | + parse(password); | |
| 338 | +} | |
| 339 | + | |
| 340 | +void | |
| 320 | 341 | QPDF::processMemoryFile(char const* description, |
| 321 | 342 | char const* buf, size_t length, |
| 322 | 343 | char const* password) | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -200,3 +200,6 @@ qpdf-c set_info_key to null 0 |
| 200 | 200 | qpdf-c set-info-key use existing info 0 |
| 201 | 201 | qpdf-c add info to trailer 0 |
| 202 | 202 | qpdf-c called qpdf_init_write_memory 0 |
| 203 | +exercise processFile(name) 0 | |
| 204 | +exercise processFile(FILE*) 0 | |
| 205 | +exercise processMemoryFile 0 | ... | ... |
qpdf/test_driver.cc
| ... | ... | @@ -60,17 +60,29 @@ void runtest(int n, char const* filename) |
| 60 | 60 | { |
| 61 | 61 | QPDF pdf; |
| 62 | 62 | PointerHolder<char> file_buf; |
| 63 | + FILE* filep = 0; | |
| 63 | 64 | if (n == 0) |
| 64 | 65 | { |
| 65 | 66 | pdf.setAttemptRecovery(false); |
| 66 | 67 | } |
| 67 | 68 | if (n % 2 == 0) |
| 68 | 69 | { |
| 69 | - pdf.processFile(filename); | |
| 70 | + if (n % 4 == 0) | |
| 71 | + { | |
| 72 | + QTC::TC("qpdf", "exercise processFile(name)"); | |
| 73 | + pdf.processFile(filename); | |
| 74 | + } | |
| 75 | + else | |
| 76 | + { | |
| 77 | + QTC::TC("qpdf", "exercise processFile(FILE*)"); | |
| 78 | + filep = QUtil::fopen_wrapper(std::string("open ") + filename, | |
| 79 | + fopen(filename, "rb")); | |
| 80 | + pdf.processFile(filep); | |
| 81 | + } | |
| 70 | 82 | } |
| 71 | 83 | else |
| 72 | 84 | { |
| 73 | - // Exercise processMemoryFile | |
| 85 | + QTC::TC("qpdf", "exercise processMemoryFile"); | |
| 74 | 86 | FILE* f = QUtil::fopen_wrapper(std::string("open ") + filename, |
| 75 | 87 | fopen(filename, "rb")); |
| 76 | 88 | fseek(f, 0, SEEK_END); |
| ... | ... | @@ -623,6 +635,10 @@ void runtest(int n, char const* filename) |
| 623 | 635 | QUtil::int_to_string(n)); |
| 624 | 636 | } |
| 625 | 637 | |
| 638 | + if (filep) | |
| 639 | + { | |
| 640 | + fclose(filep); | |
| 641 | + } | |
| 626 | 642 | std::cout << "test " << n << " done" << std::endl; |
| 627 | 643 | } |
| 628 | 644 | ... | ... |