Commit 4c8836d52053187e8006021d4e5d367bdaf80093
1 parent
c912af73
In QPDFParser::parse eliminate most temporary variables
Showing
2 changed files
with
36 additions
and
31 deletions
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& 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& 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& 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 | ... | ... |