Commit 75091093fe89e9b04aad9e1c9b3ad7305a0135e7

Authored by m-holger
Committed by GitHub
2 parents ddfa3a24 83e0f8da

Merge pull request #1280 from m-holger/streams

Tidy QPDF_Stream
include/qpdf/QPDF.hh
... ... @@ -1073,7 +1073,6 @@ class QPDF
1073 1073 QPDFObject* resolve(QPDFObjGen og);
1074 1074 void resolveObjectsInStream(int obj_stream_number);
1075 1075 void stopOnError(std::string const& message);
1076   - QPDFObjectHandle reserveStream(QPDFObjGen const& og);
1077 1076 QPDFObjGen nextObjGen();
1078 1077 QPDFObjectHandle newIndirect(QPDFObjGen const&, std::shared_ptr<QPDFObject> const&);
1079 1078 QPDFObjectHandle makeIndirectFromQPDFObject(std::shared_ptr<QPDFObject> const& obj);
... ...
libqpdf/QPDF.cc
... ... @@ -1547,7 +1547,7 @@ QPDF::readStream(QPDFObjectHandle&amp; object, QPDFObjGen og, qpdf_offset_t offset)
1547 1547 throw;
1548 1548 }
1549 1549 }
1550   - object = newIndirect(og, QPDF_Stream::create(this, og, object, stream_offset, length));
  1550 + object = {QPDF_Stream::create(this, og, object, stream_offset, length)};
1551 1551 }
1552 1552  
1553 1553 void
... ... @@ -2101,12 +2101,6 @@ QPDF::newStream(std::string const&amp; data)
2101 2101 return result;
2102 2102 }
2103 2103  
2104   -QPDFObjectHandle
2105   -QPDF::reserveStream(QPDFObjGen const& og)
2106   -{
2107   - return {QPDF_Stream::create(this, og, QPDFObjectHandle::newDictionary(), 0, 0)};
2108   -}
2109   -
2110 2104 std::shared_ptr<QPDFObject>
2111 2105 QPDF::getObjectForParser(int id, int gen, bool parse_pdf)
2112 2106 {
... ... @@ -2177,7 +2171,7 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh)
2177 2171 void
2178 2172 QPDF::replaceObject(QPDFObjGen const& og, QPDFObjectHandle oh)
2179 2173 {
2180   - if (oh.isIndirect() || !oh.isInitialized()) {
  2174 + if (!oh.isInitialized() || (oh.isIndirect() && !(oh.isStream() && oh.getObjGen() == og))) {
2181 2175 QTC::TC("qpdf", "QPDF replaceObject called with indirect object");
2182 2176 throw std::logic_error("QPDF::replaceObject called with indirect object handle");
2183 2177 }
... ...
libqpdf/QPDF_Stream.cc
... ... @@ -107,12 +107,8 @@ StreamBlobProvider::operator()(Pipeline* p)
107 107 }
108 108  
109 109 QPDF_Stream::QPDF_Stream(
110   - QPDF* qpdf,
111   - QPDFObjGen const& og,
112   - QPDFObjectHandle stream_dict,
113   - qpdf_offset_t offset,
114   - size_t length) :
115   - QPDFValue(::ot_stream),
  110 + QPDF* qpdf, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length) :
  111 + QPDFValue(::ot_stream, qpdf, og),
116 112 filter_on_write(true),
117 113 stream_dict(stream_dict),
118 114 length(length)
... ... @@ -128,11 +124,7 @@ QPDF_Stream::QPDF_Stream(
128 124  
129 125 std::shared_ptr<QPDFObject>
130 126 QPDF_Stream::create(
131   - QPDF* qpdf,
132   - QPDFObjGen const& og,
133   - QPDFObjectHandle stream_dict,
134   - qpdf_offset_t offset,
135   - size_t length)
  127 + QPDF* qpdf, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length)
136 128 {
137 129 return do_create(new QPDF_Stream(qpdf, og, stream_dict, offset, length));
138 130 }
... ...
libqpdf/QPDF_json.cc
... ... @@ -397,14 +397,12 @@ QPDF::JSONReactor::containerEnd(JSON const&amp; value)
397 397 QTC::TC("qpdf", "QPDF_json data datafile both or neither");
398 398 error(
399 399 value.getStart(),
400   - "new \"stream\" must have exactly one of \"data\" or "
401   - "\"datafile\"");
  400 + "new \"stream\" must have exactly one of \"data\" or \"datafile\"");
402 401 } else if (saw_datafile) {
403 402 QTC::TC("qpdf", "QPDF_json data and datafile");
404 403 error(
405 404 value.getStart(),
406   - "existing \"stream\" may at most one of \"data\" or "
407   - "\"datafile\"");
  405 + "existing \"stream\" may at most one of \"data\" or \"datafile\"");
408 406 } else {
409 407 QTC::TC("qpdf", "QPDF_json no stream data in update mode");
410 408 }
... ... @@ -427,15 +425,15 @@ QPDF::JSONReactor::containerEnd(JSON const&amp; value)
427 425 void
428 426 QPDF::JSONReactor::replaceObject(QPDFObjectHandle&& replacement, JSON const& value)
429 427 {
430   - if (replacement.isIndirect()) {
  428 + auto& tos = stack.back();
  429 + auto og = tos.object.getObjGen();
  430 + if (replacement.isIndirect() && !(replacement.isStream() && replacement.getObjGen() == og)) {
431 431 error(
432 432 replacement.getParsedOffset(),
433 433 "the value of an object may not be an indirect object reference");
434 434 return;
435 435 }
436   - auto& tos = stack.back();
437   - auto og = tos.object.getObjGen();
438   - this->pdf.replaceObject(og, replacement);
  436 + pdf.replaceObject(og, replacement);
439 437 next_obj = pdf.getObject(og);
440 438 setObjectDescription(tos.object, value);
441 439 }
... ... @@ -575,8 +573,11 @@ QPDF::JSONReactor::dictionaryItem(std::string const&amp; key, JSON const&amp; value)
575 573 if (tos.object.isStream()) {
576 574 QTC::TC("qpdf", "QPDF_json updating existing stream");
577 575 } else {
578   - this->this_stream_needs_data = true;
579   - replaceObject(pdf.reserveStream(tos.object.getObjGen()), value);
  576 + this_stream_needs_data = true;
  577 + replaceObject(
  578 + QPDF_Stream::create(
  579 + &pdf, tos.object.getObjGen(), QPDFObjectHandle::newDictionary(), 0, 0),
  580 + value);
580 581 }
581 582 next_obj = tos.object;
582 583 } else {
... ...
libqpdf/qpdf/QPDF_Stream.hh
... ... @@ -13,22 +13,18 @@
13 13 class Pipeline;
14 14 class QPDF;
15 15  
16   -class QPDF_Stream: public QPDFValue
  16 +class QPDF_Stream final: public QPDFValue
17 17 {
18 18 public:
19   - ~QPDF_Stream() override = default;
20   - static std::shared_ptr<QPDFObject> create(
21   - QPDF*,
22   - QPDFObjGen const& og,
23   - QPDFObjectHandle stream_dict,
24   - qpdf_offset_t offset,
25   - size_t length);
26   - std::shared_ptr<QPDFObject> copy(bool shallow = false) override;
27   - std::string unparse() override;
28   - void writeJSON(int json_version, JSON::Writer& p) override;
  19 + ~QPDF_Stream() final = default;
  20 + static std::shared_ptr<QPDFObject>
  21 + create(QPDF*, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length);
  22 + std::shared_ptr<QPDFObject> copy(bool shallow = false) final;
  23 + std::string unparse() final;
  24 + void writeJSON(int json_version, JSON::Writer& p) final;
29 25 void setDescription(
30   - QPDF*, std::shared_ptr<QPDFValue::Description>& description, qpdf_offset_t offset) override;
31   - void disconnect() override;
  26 + QPDF*, std::shared_ptr<QPDFValue::Description>& description, qpdf_offset_t offset) final;
  27 + void disconnect() final;
32 28 QPDFObjectHandle getDict() const;
33 29 bool isDataModified() const;
34 30 void setFilterOnWrite(bool);
... ... @@ -80,11 +76,7 @@ class QPDF_Stream: public QPDFValue
80 76  
81 77 private:
82 78 QPDF_Stream(
83   - QPDF*,
84   - QPDFObjGen const& og,
85   - QPDFObjectHandle stream_dict,
86   - qpdf_offset_t offset,
87   - size_t length);
  79 + QPDF*, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length);
88 80 static std::map<std::string, std::string> filter_abbreviations;
89 81 static std::map<std::string, std::function<std::shared_ptr<QPDFStreamFilter>()>>
90 82 filter_factories;
... ...