Commit 88fd7ca99ab77009974584664396cb9f81aa85d4
1 parent
39abb113
Refactor QPDF::emptyPDF
Showing
2 changed files
with
40 additions
and
32 deletions
libqpdf/QPDF.cc
| @@ -32,67 +32,51 @@ | @@ -32,67 +32,51 @@ | ||
| 32 | // being static as well. | 32 | // being static as well. |
| 33 | std::string const QPDF::qpdf_version(QPDF_VERSION); | 33 | std::string const QPDF::qpdf_version(QPDF_VERSION); |
| 34 | 34 | ||
| 35 | -static char const* EMPTY_PDF = ( | ||
| 36 | - // force line break | ||
| 37 | - "%PDF-1.3\n" | ||
| 38 | - "1 0 obj\n" | ||
| 39 | - "<< /Type /Catalog /Pages 2 0 R >>\n" | ||
| 40 | - "endobj\n" | ||
| 41 | - "2 0 obj\n" | ||
| 42 | - "<< /Type /Pages /Kids [] /Count 0 >>\n" | ||
| 43 | - "endobj\n" | ||
| 44 | - "xref\n" | ||
| 45 | - "0 3\n" | ||
| 46 | - "0000000000 65535 f \n" | ||
| 47 | - "0000000009 00000 n \n" | ||
| 48 | - "0000000058 00000 n \n" | ||
| 49 | - "trailer << /Size 3 /Root 1 0 R >>\n" | ||
| 50 | - "startxref\n" | ||
| 51 | - "110\n" | ||
| 52 | - "%%EOF\n"); | ||
| 53 | - | ||
| 54 | namespace | 35 | namespace |
| 55 | { | 36 | { |
| 56 | - class InvalidInputSource: public InputSource | 37 | + class InvalidInputSource final: public InputSource |
| 57 | { | 38 | { |
| 58 | public: | 39 | public: |
| 59 | - ~InvalidInputSource() override = default; | 40 | + InvalidInputSource(std::string const& name) : |
| 41 | + name(name) | ||
| 42 | + { | ||
| 43 | + } | ||
| 44 | + ~InvalidInputSource() final = default; | ||
| 60 | qpdf_offset_t | 45 | qpdf_offset_t |
| 61 | - findAndSkipNextEOL() override | 46 | + findAndSkipNextEOL() final |
| 62 | { | 47 | { |
| 63 | throwException(); | 48 | throwException(); |
| 64 | return 0; | 49 | return 0; |
| 65 | } | 50 | } |
| 66 | std::string const& | 51 | std::string const& |
| 67 | - getName() const override | 52 | + getName() const final |
| 68 | { | 53 | { |
| 69 | - static std::string name("closed input source"); | ||
| 70 | return name; | 54 | return name; |
| 71 | } | 55 | } |
| 72 | qpdf_offset_t | 56 | qpdf_offset_t |
| 73 | - tell() override | 57 | + tell() final |
| 74 | { | 58 | { |
| 75 | throwException(); | 59 | throwException(); |
| 76 | return 0; | 60 | return 0; |
| 77 | } | 61 | } |
| 78 | void | 62 | void |
| 79 | - seek(qpdf_offset_t offset, int whence) override | 63 | + seek(qpdf_offset_t offset, int whence) final |
| 80 | { | 64 | { |
| 81 | throwException(); | 65 | throwException(); |
| 82 | } | 66 | } |
| 83 | void | 67 | void |
| 84 | - rewind() override | 68 | + rewind() final |
| 85 | { | 69 | { |
| 86 | throwException(); | 70 | throwException(); |
| 87 | } | 71 | } |
| 88 | size_t | 72 | size_t |
| 89 | - read(char* buffer, size_t length) override | 73 | + read(char* buffer, size_t length) final |
| 90 | { | 74 | { |
| 91 | throwException(); | 75 | throwException(); |
| 92 | return 0; | 76 | return 0; |
| 93 | } | 77 | } |
| 94 | void | 78 | void |
| 95 | - unreadCh(char ch) override | 79 | + unreadCh(char ch) final |
| 96 | { | 80 | { |
| 97 | throwException(); | 81 | throwException(); |
| 98 | } | 82 | } |
| @@ -105,6 +89,8 @@ namespace | @@ -105,6 +89,8 @@ namespace | ||
| 105 | "source. QPDF operations are invalid before processFile (or " | 89 | "source. QPDF operations are invalid before processFile (or " |
| 106 | "another process method) or after closeInputSource"); | 90 | "another process method) or after closeInputSource"); |
| 107 | } | 91 | } |
| 92 | + | ||
| 93 | + std::string const& name; | ||
| 108 | }; | 94 | }; |
| 109 | } // namespace | 95 | } // namespace |
| 110 | 96 | ||
| @@ -198,7 +184,7 @@ QPDF::EncryptionParameters::EncryptionParameters() : | @@ -198,7 +184,7 @@ QPDF::EncryptionParameters::EncryptionParameters() : | ||
| 198 | 184 | ||
| 199 | QPDF::Members::Members(QPDF& qpdf) : | 185 | QPDF::Members::Members(QPDF& qpdf) : |
| 200 | log(QPDFLogger::defaultLogger()), | 186 | log(QPDFLogger::defaultLogger()), |
| 201 | - file_sp(new InvalidInputSource()), | 187 | + file_sp(new InvalidInputSource(no_input_name)), |
| 202 | file(file_sp.get()), | 188 | file(file_sp.get()), |
| 203 | encp(new EncryptionParameters), | 189 | encp(new EncryptionParameters), |
| 204 | xref_table(qpdf, file) | 190 | xref_table(qpdf, file) |
| @@ -278,7 +264,8 @@ QPDF::processInputSource(std::shared_ptr<InputSource> source, char const* passwo | @@ -278,7 +264,8 @@ QPDF::processInputSource(std::shared_ptr<InputSource> source, char const* passwo | ||
| 278 | void | 264 | void |
| 279 | QPDF::closeInputSource() | 265 | QPDF::closeInputSource() |
| 280 | { | 266 | { |
| 281 | - m->file_sp = std::shared_ptr<InputSource>(new InvalidInputSource()); | 267 | + m->no_input_name = "closed input source"; |
| 268 | + m->file_sp = std::shared_ptr<InputSource>(new InvalidInputSource(m->no_input_name)); | ||
| 282 | m->file = m->file_sp.get(); | 269 | m->file = m->file_sp.get(); |
| 283 | } | 270 | } |
| 284 | 271 | ||
| @@ -291,7 +278,9 @@ QPDF::setPasswordIsHexKey(bool val) | @@ -291,7 +278,9 @@ QPDF::setPasswordIsHexKey(bool val) | ||
| 291 | void | 278 | void |
| 292 | QPDF::emptyPDF() | 279 | QPDF::emptyPDF() |
| 293 | { | 280 | { |
| 294 | - processMemoryFile("empty PDF", EMPTY_PDF, strlen(EMPTY_PDF)); | 281 | + m->pdf_version = "1.3"; |
| 282 | + m->no_input_name = "empty PDF"; | ||
| 283 | + m->xref_table.initialize_empty(); | ||
| 295 | } | 284 | } |
| 296 | 285 | ||
| 297 | void | 286 | void |
| @@ -490,6 +479,22 @@ QPDF::warn( | @@ -490,6 +479,22 @@ QPDF::warn( | ||
| 490 | } | 479 | } |
| 491 | 480 | ||
| 492 | void | 481 | void |
| 482 | +QPDF::Xref_table::initialize_empty() | ||
| 483 | +{ | ||
| 484 | + initialized_ = true; | ||
| 485 | + trailer_ = QPDFObjectHandle::newDictionary(); | ||
| 486 | + auto rt = qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary()); | ||
| 487 | + auto pgs = qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary()); | ||
| 488 | + pgs.replaceKey("/Type", QPDFObjectHandle::newName("/Pages")); | ||
| 489 | + pgs.replaceKey("/Kids", QPDFObjectHandle::newArray()); | ||
| 490 | + pgs.replaceKey("/Count", QPDFObjectHandle::newInteger(0)); | ||
| 491 | + rt.replaceKey("/Type", QPDFObjectHandle::newName("/Catalog")); | ||
| 492 | + rt.replaceKey("/Pages", pgs); | ||
| 493 | + trailer_.replaceKey("/Root", rt); | ||
| 494 | + trailer_.replaceKey("/Size", QPDFObjectHandle::newInteger(3)); | ||
| 495 | +} | ||
| 496 | + | ||
| 497 | +void | ||
| 493 | QPDF::Xref_table::initialize() | 498 | QPDF::Xref_table::initialize() |
| 494 | { | 499 | { |
| 495 | // PDF spec says %%EOF must be found within the last 1024 bytes of/ the file. We add an extra | 500 | // PDF spec says %%EOF must be found within the last 1024 bytes of/ the file. We add an extra |
libqpdf/qpdf/QPDF_private.hh
| @@ -15,6 +15,7 @@ class QPDF::Xref_table | @@ -15,6 +15,7 @@ class QPDF::Xref_table | ||
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | void initialize(); | 17 | void initialize(); |
| 18 | + void initialize_empty(); | ||
| 18 | void reconstruct(QPDFExc& e); | 19 | void reconstruct(QPDFExc& e); |
| 19 | void show(); | 20 | void show(); |
| 20 | bool resolve(); | 21 | bool resolve(); |
| @@ -640,6 +641,8 @@ class QPDF::Members | @@ -640,6 +641,8 @@ class QPDF::Members | ||
| 640 | std::shared_ptr<QPDFLogger> log; | 641 | std::shared_ptr<QPDFLogger> log; |
| 641 | unsigned long long unique_id{0}; | 642 | unsigned long long unique_id{0}; |
| 642 | QPDFTokenizer tokenizer; | 643 | QPDFTokenizer tokenizer; |
| 644 | + // Filename to use if there is no input PDF | ||
| 645 | + std::string no_input_name{"closed input source"}; | ||
| 643 | // If file_sp is updated, file must also be updated. | 646 | // If file_sp is updated, file must also be updated. |
| 644 | std::shared_ptr<InputSource> file_sp; | 647 | std::shared_ptr<InputSource> file_sp; |
| 645 | InputSource* file; | 648 | InputSource* file; |