2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-06-02 10:20:52 +00:00

In QPDFParser::parse eliminate most temporary variables

This commit is contained in:
m-holger 2023-10-30 20:03:00 +00:00
parent c912af7384
commit 4c8836d520
2 changed files with 36 additions and 31 deletions

View File

@ -21,6 +21,8 @@
#include <memory> #include <memory>
using ObjectPtr = std::shared_ptr<QPDFObject>;
QPDFObjectHandle QPDFObjectHandle
QPDFParser::parse(bool& empty, bool content_stream) QPDFParser::parse(bool& empty, bool content_stream)
{ {
@ -31,9 +33,7 @@ QPDFParser::parse(bool& empty, bool content_stream)
QPDF::ParseGuard pg(context); QPDF::ParseGuard pg(context);
empty = false; empty = false;
start = input->tell();
std::shared_ptr<QPDFObject> object;
auto offset = input->tell();
if (!tokenizer.nextToken(*input, object_description)) { if (!tokenizer.nextToken(*input, object_description)) {
warn(tokenizer.getErrorMessage()); warn(tokenizer.getErrorMessage());
@ -79,29 +79,25 @@ QPDFParser::parse(bool& empty, bool content_stream)
return parseRemainder(content_stream); return parseRemainder(content_stream);
case QPDFTokenizer::tt_bool: case QPDFTokenizer::tt_bool:
object = QPDF_Bool::create((tokenizer.getValue() == "true")); return withDescription<QPDF_Bool>(tokenizer.getValue() == "true");
break;
case QPDFTokenizer::tt_null: case QPDFTokenizer::tt_null:
return {QPDF_Null::create()}; return {QPDF_Null::create()};
case QPDFTokenizer::tt_integer: case QPDFTokenizer::tt_integer:
object = QPDF_Integer::create(QUtil::string_to_ll(tokenizer.getValue().c_str())); return withDescription<QPDF_Integer>(QUtil::string_to_ll(tokenizer.getValue().c_str()));
break;
case QPDFTokenizer::tt_real: case QPDFTokenizer::tt_real:
object = QPDF_Real::create(tokenizer.getValue()); return withDescription<QPDF_Real>(tokenizer.getValue());
break;
case QPDFTokenizer::tt_name: case QPDFTokenizer::tt_name:
object = QPDF_Name::create(tokenizer.getValue()); return withDescription<QPDF_Name>(tokenizer.getValue());
break;
case QPDFTokenizer::tt_word: case QPDFTokenizer::tt_word:
{ {
auto const& value = tokenizer.getValue(); auto const& value = tokenizer.getValue();
if (content_stream) { if (content_stream) {
object = QPDF_Operator::create(value); return withDescription<QPDF_Operator>(value);
} else if (value == "endobj") { } else if (value == "endobj") {
// We just saw endobj without having read anything. Treat this as a null and do // We just saw endobj without having read anything. Treat this as a null and do
// not move the input source's offset. // not move the input source's offset.
@ -111,28 +107,23 @@ QPDFParser::parse(bool& empty, bool content_stream)
} else { } else {
QTC::TC("qpdf", "QPDFParser treat word as string"); QTC::TC("qpdf", "QPDFParser treat word as string");
warn("unknown token while reading object; treating as string"); warn("unknown token while reading object; treating as string");
object = QPDF_String::create(value); return withDescription<QPDF_String>(value);
} }
} }
break;
case QPDFTokenizer::tt_string: case QPDFTokenizer::tt_string:
if (decrypter) { if (decrypter) {
std::string s{tokenizer.getValue()}; std::string s{tokenizer.getValue()};
decrypter->decryptString(s); decrypter->decryptString(s);
object = QPDF_String::create(s); return withDescription<QPDF_String>(s);
} else { } else {
object = QPDF_String::create(tokenizer.getValue()); return withDescription<QPDF_String>(tokenizer.getValue());
} }
break;
default: default:
warn("treating unknown token type as null while reading object"); warn("treating unknown token type as null while reading object");
return {QPDF_Null::create()}; return {QPDF_Null::create()};
} }
setDescription(object, offset);
return object;
} }
QPDFObjectHandle QPDFObjectHandle
@ -143,9 +134,9 @@ QPDFParser::parseRemainder(bool content_stream)
// effect of reading the object and changing the file pointer. If you do this, it will cause a // effect of reading the object and changing the file pointer. If you do this, it will cause a
// logic error to be thrown from QPDF::inParse(). // logic error to be thrown from QPDF::inParse().
const static std::shared_ptr<QPDFObject> null_oh = QPDF_Null::create(); const static ObjectPtr null_oh = QPDF_Null::create();
std::shared_ptr<QPDFObject> object; ObjectPtr object;
bool set_offset = false; bool set_offset = false;
bool b_contents = false; bool b_contents = false;
bool is_null = false; bool is_null = false;
@ -256,7 +247,7 @@ QPDFParser::parseRemainder(bool content_stream)
} }
// Calculate value. // Calculate value.
std::shared_ptr<QPDFObject> val; ObjectPtr val;
if (iter != frame->olist.end()) { if (iter != frame->olist.end()) {
val = *iter; val = *iter;
++iter; ++iter;
@ -429,8 +420,17 @@ QPDFParser::parseRemainder(bool content_stream)
return {}; // unreachable return {}; // unreachable
} }
template <typename T, typename... Args>
QPDFObjectHandle
QPDFParser::withDescription(Args&&... args)
{
auto obj = T::create(args...);
obj->setDescription(context, description, start);
return {obj};
}
void void
QPDFParser::setDescription(std::shared_ptr<QPDFObject>& obj, qpdf_offset_t parsed_offset) QPDFParser::setDescription(ObjectPtr& obj, qpdf_offset_t parsed_offset)
{ {
if (obj) { if (obj) {
obj->setDescription(context, description, parsed_offset); obj->setDescription(context, description, parsed_offset);

View File

@ -45,18 +45,20 @@ class QPDFParser
std::vector<std::shared_ptr<QPDFObject>> olist; std::vector<std::shared_ptr<QPDFObject>> olist;
parser_state_e state; parser_state_e state;
qpdf_offset_t offset; qpdf_offset_t offset;
std::string contents_string{""}; std::string contents_string;
qpdf_offset_t contents_offset{-1}; qpdf_offset_t contents_offset{-1};
int null_count{0}; int null_count{0};
}; };
QPDFObjectHandle parseRemainder(bool content_stream);
QPDFObjectHandle
parseRemainder(bool content_stream);
bool tooManyBadTokens(); bool tooManyBadTokens();
void warn(qpdf_offset_t offset, std::string const& msg) const; void warn(qpdf_offset_t offset, std::string const& msg) const;
void warn(std::string const& msg) const; void warn(std::string const& msg) const;
void warn(QPDFExc const&) const; void warn(QPDFExc const&) const;
template <typename T, typename... Args>
// Create a new scalar object complete with parsed offset and description.
// NB the offset includes any leading whitespace.
QPDFObjectHandle withDescription(Args&&... args);
void setDescription(std::shared_ptr<QPDFObject>& obj, qpdf_offset_t parsed_offset); void setDescription(std::shared_ptr<QPDFObject>& obj, qpdf_offset_t parsed_offset);
std::shared_ptr<InputSource> input; std::shared_ptr<InputSource> input;
std::string const& object_description; std::string const& object_description;
@ -65,11 +67,14 @@ class QPDFParser
QPDF* context; QPDF* context;
std::shared_ptr<QPDFValue::Description> description; std::shared_ptr<QPDFValue::Description> description;
std::vector<StackFrame> stack; std::vector<StackFrame> stack;
StackFrame* frame; StackFrame* frame;
// Number of recent bad tokens. // Number of recent bad tokens.
int bad_count = 0; int bad_count = 0;
// Number of good tokens since last bad token. Irrelevant if bad_count == 0. // Number of good tokens since last bad token. Irrelevant if bad_count == 0.
int good_count = 0; int good_count = 0;
// Start offset including any leading whitespace.
qpdf_offset_t start;
}; };
#endif // QPDFPARSER_HH #endif // QPDFPARSER_HH