Commit 88fd7ca99ab77009974584664396cb9f81aa85d4

Authored by m-holger
1 parent 39abb113

Refactor QPDF::emptyPDF

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&lt;InputSource&gt; source, char const* passwo @@ -278,7 +264,8 @@ QPDF::processInputSource(std::shared_ptr&lt;InputSource&gt; 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;