Commit 4c8836d52053187e8006021d4e5d367bdaf80093

Authored by m-holger
1 parent c912af73

In QPDFParser::parse eliminate most temporary variables

libqpdf/QPDFParser.cc
@@ -21,6 +21,8 @@ @@ -21,6 +21,8 @@
21 21
22 #include <memory> 22 #include <memory>
23 23
  24 +using ObjectPtr = std::shared_ptr<QPDFObject>;
  25 +
24 QPDFObjectHandle 26 QPDFObjectHandle
25 QPDFParser::parse(bool& empty, bool content_stream) 27 QPDFParser::parse(bool& empty, bool content_stream)
26 { 28 {
@@ -31,9 +33,7 @@ QPDFParser::parse(bool&amp; empty, bool content_stream) @@ -31,9 +33,7 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
31 33
32 QPDF::ParseGuard pg(context); 34 QPDF::ParseGuard pg(context);
33 empty = false; 35 empty = false;
34 -  
35 - std::shared_ptr<QPDFObject> object;  
36 - auto offset = input->tell(); 36 + start = input->tell();
37 37
38 if (!tokenizer.nextToken(*input, object_description)) { 38 if (!tokenizer.nextToken(*input, object_description)) {
39 warn(tokenizer.getErrorMessage()); 39 warn(tokenizer.getErrorMessage());
@@ -79,29 +79,25 @@ QPDFParser::parse(bool&amp; empty, bool content_stream) @@ -79,29 +79,25 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
79 return parseRemainder(content_stream); 79 return parseRemainder(content_stream);
80 80
81 case QPDFTokenizer::tt_bool: 81 case QPDFTokenizer::tt_bool:
82 - object = QPDF_Bool::create((tokenizer.getValue() == "true"));  
83 - break; 82 + return withDescription<QPDF_Bool>(tokenizer.getValue() == "true");
84 83
85 case QPDFTokenizer::tt_null: 84 case QPDFTokenizer::tt_null:
86 return {QPDF_Null::create()}; 85 return {QPDF_Null::create()};
87 86
88 case QPDFTokenizer::tt_integer: 87 case QPDFTokenizer::tt_integer:
89 - object = QPDF_Integer::create(QUtil::string_to_ll(tokenizer.getValue().c_str()));  
90 - break; 88 + return withDescription<QPDF_Integer>(QUtil::string_to_ll(tokenizer.getValue().c_str()));
91 89
92 case QPDFTokenizer::tt_real: 90 case QPDFTokenizer::tt_real:
93 - object = QPDF_Real::create(tokenizer.getValue());  
94 - break; 91 + return withDescription<QPDF_Real>(tokenizer.getValue());
95 92
96 case QPDFTokenizer::tt_name: 93 case QPDFTokenizer::tt_name:
97 - object = QPDF_Name::create(tokenizer.getValue());  
98 - break; 94 + return withDescription<QPDF_Name>(tokenizer.getValue());
99 95
100 case QPDFTokenizer::tt_word: 96 case QPDFTokenizer::tt_word:
101 { 97 {
102 auto const& value = tokenizer.getValue(); 98 auto const& value = tokenizer.getValue();
103 if (content_stream) { 99 if (content_stream) {
104 - object = QPDF_Operator::create(value); 100 + return withDescription<QPDF_Operator>(value);
105 } else if (value == "endobj") { 101 } else if (value == "endobj") {
106 // We just saw endobj without having read anything. Treat this as a null and do 102 // We just saw endobj without having read anything. Treat this as a null and do
107 // not move the input source's offset. 103 // not move the input source's offset.
@@ -111,28 +107,23 @@ QPDFParser::parse(bool&amp; empty, bool content_stream) @@ -111,28 +107,23 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
111 } else { 107 } else {
112 QTC::TC("qpdf", "QPDFParser treat word as string"); 108 QTC::TC("qpdf", "QPDFParser treat word as string");
113 warn("unknown token while reading object; treating as string"); 109 warn("unknown token while reading object; treating as string");
114 - object = QPDF_String::create(value); 110 + return withDescription<QPDF_String>(value);
115 } 111 }
116 } 112 }
117 - break;  
118 113
119 case QPDFTokenizer::tt_string: 114 case QPDFTokenizer::tt_string:
120 if (decrypter) { 115 if (decrypter) {
121 - std::string s{tokenizer.getValue()};  
122 - decrypter->decryptString(s);  
123 - object = QPDF_String::create(s); 116 + std::string s{tokenizer.getValue()};
  117 + decrypter->decryptString(s);
  118 + return withDescription<QPDF_String>(s);
124 } else { 119 } else {
125 - object = QPDF_String::create(tokenizer.getValue()); 120 + return withDescription<QPDF_String>(tokenizer.getValue());
126 } 121 }
127 - break;  
128 122
129 default: 123 default:
130 warn("treating unknown token type as null while reading object"); 124 warn("treating unknown token type as null while reading object");
131 return {QPDF_Null::create()}; 125 return {QPDF_Null::create()};
132 } 126 }
133 -  
134 - setDescription(object, offset);  
135 - return object;  
136 } 127 }
137 128
138 QPDFObjectHandle 129 QPDFObjectHandle
@@ -143,9 +134,9 @@ QPDFParser::parseRemainder(bool content_stream) @@ -143,9 +134,9 @@ QPDFParser::parseRemainder(bool content_stream)
143 // effect of reading the object and changing the file pointer. If you do this, it will cause a 134 // effect of reading the object and changing the file pointer. If you do this, it will cause a
144 // logic error to be thrown from QPDF::inParse(). 135 // logic error to be thrown from QPDF::inParse().
145 136
146 - const static std::shared_ptr<QPDFObject> null_oh = QPDF_Null::create(); 137 + const static ObjectPtr null_oh = QPDF_Null::create();
147 138
148 - std::shared_ptr<QPDFObject> object; 139 + ObjectPtr object;
149 bool set_offset = false; 140 bool set_offset = false;
150 bool b_contents = false; 141 bool b_contents = false;
151 bool is_null = false; 142 bool is_null = false;
@@ -256,7 +247,7 @@ QPDFParser::parseRemainder(bool content_stream) @@ -256,7 +247,7 @@ QPDFParser::parseRemainder(bool content_stream)
256 } 247 }
257 248
258 // Calculate value. 249 // Calculate value.
259 - std::shared_ptr<QPDFObject> val; 250 + ObjectPtr val;
260 if (iter != frame->olist.end()) { 251 if (iter != frame->olist.end()) {
261 val = *iter; 252 val = *iter;
262 ++iter; 253 ++iter;
@@ -429,8 +420,17 @@ QPDFParser::parseRemainder(bool content_stream) @@ -429,8 +420,17 @@ QPDFParser::parseRemainder(bool content_stream)
429 return {}; // unreachable 420 return {}; // unreachable
430 } 421 }
431 422
  423 +template <typename T, typename... Args>
  424 +QPDFObjectHandle
  425 +QPDFParser::withDescription(Args&&... args)
  426 +{
  427 + auto obj = T::create(args...);
  428 + obj->setDescription(context, description, start);
  429 + return {obj};
  430 +}
  431 +
432 void 432 void
433 -QPDFParser::setDescription(std::shared_ptr<QPDFObject>& obj, qpdf_offset_t parsed_offset) 433 +QPDFParser::setDescription(ObjectPtr& obj, qpdf_offset_t parsed_offset)
434 { 434 {
435 if (obj) { 435 if (obj) {
436 obj->setDescription(context, description, parsed_offset); 436 obj->setDescription(context, description, parsed_offset);
libqpdf/qpdf/QPDFParser.hh
@@ -45,18 +45,20 @@ class QPDFParser @@ -45,18 +45,20 @@ class QPDFParser
45 std::vector<std::shared_ptr<QPDFObject>> olist; 45 std::vector<std::shared_ptr<QPDFObject>> olist;
46 parser_state_e state; 46 parser_state_e state;
47 qpdf_offset_t offset; 47 qpdf_offset_t offset;
48 - std::string contents_string{""}; 48 + std::string contents_string;
49 qpdf_offset_t contents_offset{-1}; 49 qpdf_offset_t contents_offset{-1};
50 int null_count{0}; 50 int null_count{0};
51 }; 51 };
52 52
53 -  
54 - QPDFObjectHandle  
55 - parseRemainder(bool content_stream); 53 + QPDFObjectHandle parseRemainder(bool content_stream);
56 bool tooManyBadTokens(); 54 bool tooManyBadTokens();
57 void warn(qpdf_offset_t offset, std::string const& msg) const; 55 void warn(qpdf_offset_t offset, std::string const& msg) const;
58 void warn(std::string const& msg) const; 56 void warn(std::string const& msg) const;
59 void warn(QPDFExc const&) const; 57 void warn(QPDFExc const&) const;
  58 + template <typename T, typename... Args>
  59 + // Create a new scalar object complete with parsed offset and description.
  60 + // NB the offset includes any leading whitespace.
  61 + QPDFObjectHandle withDescription(Args&&... args);
60 void setDescription(std::shared_ptr<QPDFObject>& obj, qpdf_offset_t parsed_offset); 62 void setDescription(std::shared_ptr<QPDFObject>& obj, qpdf_offset_t parsed_offset);
61 std::shared_ptr<InputSource> input; 63 std::shared_ptr<InputSource> input;
62 std::string const& object_description; 64 std::string const& object_description;
@@ -65,11 +67,14 @@ class QPDFParser @@ -65,11 +67,14 @@ class QPDFParser
65 QPDF* context; 67 QPDF* context;
66 std::shared_ptr<QPDFValue::Description> description; 68 std::shared_ptr<QPDFValue::Description> description;
67 std::vector<StackFrame> stack; 69 std::vector<StackFrame> stack;
68 - StackFrame* frame; 70 + StackFrame* frame;
69 // Number of recent bad tokens. 71 // Number of recent bad tokens.
70 int bad_count = 0; 72 int bad_count = 0;
71 // Number of good tokens since last bad token. Irrelevant if bad_count == 0. 73 // Number of good tokens since last bad token. Irrelevant if bad_count == 0.
72 int good_count = 0; 74 int good_count = 0;
  75 + // Start offset including any leading whitespace.
  76 + qpdf_offset_t start;
  77 +
73 }; 78 };
74 79
75 #endif // QPDFPARSER_HH 80 #endif // QPDFPARSER_HH