Commit bc1c4bb57864c4dbe9b7e42a77e0653c0d473071
1 parent
ed6a56a3
Add QPDF::processFile that takes an open FILE*
Showing
5 changed files
with
58 additions
and
3 deletions
ChangeLog
| 1 | +2012-06-21 Jay Berkenbilt <ejb@ql.org> | ||
| 2 | + | ||
| 3 | + * libqpdf/QPDF.cc: new processFile method that takes an open FILE* | ||
| 4 | + instead of a filename. | ||
| 5 | + | ||
| 1 | 2012-06-20 Jay Berkenbilt <ejb@ql.org> | 6 | 2012-06-20 Jay Berkenbilt <ejb@ql.org> |
| 2 | 7 | ||
| 3 | * Add new array mutation routines to QPDFObjectHandle. | 8 | * Add new array mutation routines to QPDFObjectHandle. |
include/qpdf/QPDF.hh
| @@ -52,6 +52,14 @@ class QPDF | @@ -52,6 +52,14 @@ class QPDF | ||
| 52 | QPDF_DLL | 52 | QPDF_DLL |
| 53 | void processFile(char const* filename, char const* password = 0); | 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 | // Parse a PDF file loaded into a memory buffer. This works | 63 | // Parse a PDF file loaded into a memory buffer. This works |
| 56 | // exactly like processFile except that the PDF file is in memory | 64 | // exactly like processFile except that the PDF file is in memory |
| 57 | // instead of on disk. The description appears in any warning or | 65 | // instead of on disk. The description appears in any warning or |
| @@ -400,6 +408,7 @@ class QPDF | @@ -400,6 +408,7 @@ class QPDF | ||
| 400 | public: | 408 | public: |
| 401 | FileInputSource(); | 409 | FileInputSource(); |
| 402 | void setFilename(char const* filename); | 410 | void setFilename(char const* filename); |
| 411 | + void setFile(FILE* filep); | ||
| 403 | virtual ~FileInputSource(); | 412 | virtual ~FileInputSource(); |
| 404 | virtual std::string const& getName() const; | 413 | virtual std::string const& getName() const; |
| 405 | virtual off_t tell(); | 414 | virtual off_t tell(); |
| @@ -414,6 +423,7 @@ class QPDF | @@ -414,6 +423,7 @@ class QPDF | ||
| 414 | 423 | ||
| 415 | void destroy(); | 424 | void destroy(); |
| 416 | 425 | ||
| 426 | + bool close_file; | ||
| 417 | std::string filename; | 427 | std::string filename; |
| 418 | FILE* file; | 428 | FILE* file; |
| 419 | }; | 429 | }; |
libqpdf/QPDF.cc
| @@ -80,6 +80,7 @@ QPDF::InputSource::readLine() | @@ -80,6 +80,7 @@ QPDF::InputSource::readLine() | ||
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | QPDF::FileInputSource::FileInputSource() : | 82 | QPDF::FileInputSource::FileInputSource() : |
| 83 | + close_file(false), | ||
| 83 | file(0) | 84 | file(0) |
| 84 | { | 85 | { |
| 85 | } | 86 | } |
| @@ -89,10 +90,21 @@ QPDF::FileInputSource::setFilename(char const* filename) | @@ -89,10 +90,21 @@ QPDF::FileInputSource::setFilename(char const* filename) | ||
| 89 | { | 90 | { |
| 90 | destroy(); | 91 | destroy(); |
| 91 | this->filename = filename; | 92 | this->filename = filename; |
| 93 | + this->close_file = true; | ||
| 92 | this->file = QUtil::fopen_wrapper(std::string("open ") + this->filename, | 94 | this->file = QUtil::fopen_wrapper(std::string("open ") + this->filename, |
| 93 | fopen(this->filename.c_str(), "rb")); | 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 | QPDF::FileInputSource::~FileInputSource() | 108 | QPDF::FileInputSource::~FileInputSource() |
| 97 | { | 109 | { |
| 98 | destroy(); | 110 | destroy(); |
| @@ -101,7 +113,7 @@ QPDF::FileInputSource::~FileInputSource() | @@ -101,7 +113,7 @@ QPDF::FileInputSource::~FileInputSource() | ||
| 101 | void | 113 | void |
| 102 | QPDF::FileInputSource::destroy() | 114 | QPDF::FileInputSource::destroy() |
| 103 | { | 115 | { |
| 104 | - if (this->file) | 116 | + if (this->file && this->close_file) |
| 105 | { | 117 | { |
| 106 | fclose(this->file); | 118 | fclose(this->file); |
| 107 | this->file = 0; | 119 | this->file = 0; |
| @@ -317,6 +329,15 @@ QPDF::processFile(char const* filename, char const* password) | @@ -317,6 +329,15 @@ QPDF::processFile(char const* filename, char const* password) | ||
| 317 | } | 329 | } |
| 318 | 330 | ||
| 319 | void | 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 | QPDF::processMemoryFile(char const* description, | 341 | QPDF::processMemoryFile(char const* description, |
| 321 | char const* buf, size_t length, | 342 | char const* buf, size_t length, |
| 322 | char const* password) | 343 | char const* password) |
qpdf/qpdf.testcov
| @@ -200,3 +200,6 @@ qpdf-c set_info_key to null 0 | @@ -200,3 +200,6 @@ qpdf-c set_info_key to null 0 | ||
| 200 | qpdf-c set-info-key use existing info 0 | 200 | qpdf-c set-info-key use existing info 0 |
| 201 | qpdf-c add info to trailer 0 | 201 | qpdf-c add info to trailer 0 |
| 202 | qpdf-c called qpdf_init_write_memory 0 | 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,17 +60,29 @@ void runtest(int n, char const* filename) | ||
| 60 | { | 60 | { |
| 61 | QPDF pdf; | 61 | QPDF pdf; |
| 62 | PointerHolder<char> file_buf; | 62 | PointerHolder<char> file_buf; |
| 63 | + FILE* filep = 0; | ||
| 63 | if (n == 0) | 64 | if (n == 0) |
| 64 | { | 65 | { |
| 65 | pdf.setAttemptRecovery(false); | 66 | pdf.setAttemptRecovery(false); |
| 66 | } | 67 | } |
| 67 | if (n % 2 == 0) | 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 | else | 83 | else |
| 72 | { | 84 | { |
| 73 | - // Exercise processMemoryFile | 85 | + QTC::TC("qpdf", "exercise processMemoryFile"); |
| 74 | FILE* f = QUtil::fopen_wrapper(std::string("open ") + filename, | 86 | FILE* f = QUtil::fopen_wrapper(std::string("open ") + filename, |
| 75 | fopen(filename, "rb")); | 87 | fopen(filename, "rb")); |
| 76 | fseek(f, 0, SEEK_END); | 88 | fseek(f, 0, SEEK_END); |
| @@ -623,6 +635,10 @@ void runtest(int n, char const* filename) | @@ -623,6 +635,10 @@ void runtest(int n, char const* filename) | ||
| 623 | QUtil::int_to_string(n)); | 635 | QUtil::int_to_string(n)); |
| 624 | } | 636 | } |
| 625 | 637 | ||
| 638 | + if (filep) | ||
| 639 | + { | ||
| 640 | + fclose(filep); | ||
| 641 | + } | ||
| 626 | std::cout << "test " << n << " done" << std::endl; | 642 | std::cout << "test " << n << " done" << std::endl; |
| 627 | } | 643 | } |
| 628 | 644 |