Commit 4c8836d52053187e8006021d4e5d367bdaf80093

Authored by m-holger
1 parent c912af73

In QPDFParser::parse eliminate most temporary variables

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