Commit db7251f17ab3d603f947c786031de49f9d779f1e
1 parent
b73f6d79
Refactor `QPDF_json` stream reading to simplify and improve performance by repla…
…cing buffered reads with direct data extraction from `InputSource`.
Showing
1 changed file
with
7 additions
and
19 deletions
libqpdf/QPDF_json.cc
| 1 | 1 | #include <qpdf/QPDF.hh> |
| 2 | 2 | |
| 3 | 3 | #include <qpdf/FileInputSource.hh> |
| 4 | +#include <qpdf/InputSource_private.hh> | |
| 4 | 5 | #include <qpdf/JSON_writer.hh> |
| 5 | 6 | #include <qpdf/Pl_Base64.hh> |
| 6 | 7 | #include <qpdf/Pl_StdioFile.hh> |
| ... | ... | @@ -216,18 +217,8 @@ provide_data(std::shared_ptr<InputSource> is, qpdf_offset_t start, qpdf_offset_t |
| 216 | 217 | { |
| 217 | 218 | return [is, start, end](Pipeline* p) { |
| 218 | 219 | Pl_Base64 decode("base64-decode", p, Pl_Base64::a_decode); |
| 219 | - p = &decode; | |
| 220 | - size_t bytes = QIntC::to_size(end - start); | |
| 221 | - char buf[8192]; | |
| 222 | - is->seek(start, SEEK_SET); | |
| 223 | - size_t len = 0; | |
| 224 | - while ((len = is->read(buf, std::min(bytes, sizeof(buf)))) > 0) { | |
| 225 | - p->write(buf, len); | |
| 226 | - bytes -= len; | |
| 227 | - if (bytes == 0) { | |
| 228 | - break; | |
| 229 | - } | |
| 230 | - } | |
| 220 | + auto data = is->read(QIntC::to_size(end - start), start); | |
| 221 | + decode.write(reinterpret_cast<const unsigned char*>(data.data()), data.size()); | |
| 231 | 222 | decode.finish(); |
| 232 | 223 | }; |
| 233 | 224 | } |
| ... | ... | @@ -615,7 +606,6 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value) |
| 615 | 606 | if (!tos.object.isStream()) { |
| 616 | 607 | throw std::logic_error("current object is not stream in st_stream"); |
| 617 | 608 | } |
| 618 | - auto uninitialized = QPDFObjectHandle(); | |
| 619 | 609 | if (key == "dict") { |
| 620 | 610 | this->saw_dict = true; |
| 621 | 611 | if (setNextStateIfDictionary("stream.dict", value, st_object)) { |
| ... | ... | @@ -630,7 +620,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value) |
| 630 | 620 | if (!value.getString(v)) { |
| 631 | 621 | QTC::TC("qpdf", "QPDF_json stream data not string"); |
| 632 | 622 | error(value.getStart(), "\"stream.data\" must be a string"); |
| 633 | - tos.object.replaceStreamData("", uninitialized, uninitialized); | |
| 623 | + tos.object.replaceStreamData("", {}, {}); | |
| 634 | 624 | } else { |
| 635 | 625 | // The range includes the quotes. |
| 636 | 626 | auto start = value.getStart() + 1; |
| ... | ... | @@ -638,8 +628,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value) |
| 638 | 628 | if (end < start) { |
| 639 | 629 | throw std::logic_error("QPDF_json: JSON string length < 0"); |
| 640 | 630 | } |
| 641 | - tos.object.replaceStreamData( | |
| 642 | - provide_data(is, start, end), uninitialized, uninitialized); | |
| 631 | + tos.object.replaceStreamData(provide_data(is, start, end), {}, {}); | |
| 643 | 632 | } |
| 644 | 633 | } else if (key == "datafile") { |
| 645 | 634 | this->saw_datafile = true; |
| ... | ... | @@ -649,10 +638,9 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value) |
| 649 | 638 | error( |
| 650 | 639 | value.getStart(), |
| 651 | 640 | "\"stream.datafile\" must be a string containing a file name"); |
| 652 | - tos.object.replaceStreamData("", uninitialized, uninitialized); | |
| 641 | + tos.object.replaceStreamData("", {}, {}); | |
| 653 | 642 | } else { |
| 654 | - tos.object.replaceStreamData( | |
| 655 | - QUtil::file_provider(filename), uninitialized, uninitialized); | |
| 643 | + tos.object.replaceStreamData(QUtil::file_provider(filename), {}, {}); | |
| 656 | 644 | } |
| 657 | 645 | } else { |
| 658 | 646 | // Ignore unknown keys for forward compatibility. | ... | ... |