From e2737ab646bff6aa07ba72e0cc15cc955d9afcc0 Mon Sep 17 00:00:00 2001 From: m-holger Date: Fri, 9 Feb 2024 13:09:08 +0000 Subject: Add new writeJSON methods Create an alternative to getJSON to allow an object handle to be written as JSON without the overhead of creating a JSON object. --- libqpdf/QPDF_Stream.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'libqpdf/QPDF_Stream.cc') diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index a43d91ff..bedc96b2 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -185,6 +186,12 @@ QPDF_Stream::getJSON(int json_version) return getStreamJSON(json_version, qpdf_sj_none, qpdf_dl_none, nullptr, ""); } +void +QPDF_Stream::writeJSON(int json_version, JSON::Writer& p) +{ + stream_dict.writeJSON(json_version, p); +} + JSON QPDF_Stream::getStreamJSON( int json_version, -- cgit v1.2.3-54-g00ecf From 9589fad1e5bde7c51f01c0de16ac0b5ccb7051e0 Mon Sep 17 00:00:00 2001 From: m-holger Date: Mon, 12 Feb 2024 18:40:21 +0000 Subject: Reimplement QPDFObjectHandle::getJSON in terms of writeJSON --- libqpdf/QPDFObjectHandle.cc | 6 +++++- libqpdf/QPDF_Array.cc | 32 -------------------------------- libqpdf/QPDF_Bool.cc | 6 ------ libqpdf/QPDF_Destroyed.cc | 7 ------- libqpdf/QPDF_Dictionary.cc | 20 -------------------- libqpdf/QPDF_InlineImage.cc | 6 ------ libqpdf/QPDF_Integer.cc | 6 ------ libqpdf/QPDF_Name.cc | 14 -------------- libqpdf/QPDF_Null.cc | 7 ------- libqpdf/QPDF_Operator.cc | 6 ------ libqpdf/QPDF_Real.cc | 19 ------------------- libqpdf/QPDF_Reserved.cc | 7 ------- libqpdf/QPDF_Stream.cc | 9 --------- libqpdf/QPDF_String.cc | 29 ----------------------------- libqpdf/QPDF_Unresolved.cc | 7 ------- libqpdf/qpdf/QPDFObject_private.hh | 5 ----- libqpdf/qpdf/QPDFValue.hh | 1 - libqpdf/qpdf/QPDF_Array.hh | 1 - libqpdf/qpdf/QPDF_Bool.hh | 1 - libqpdf/qpdf/QPDF_Destroyed.hh | 1 - libqpdf/qpdf/QPDF_Dictionary.hh | 1 - libqpdf/qpdf/QPDF_InlineImage.hh | 1 - libqpdf/qpdf/QPDF_Integer.hh | 1 - libqpdf/qpdf/QPDF_Name.hh | 1 - libqpdf/qpdf/QPDF_Null.hh | 1 - libqpdf/qpdf/QPDF_Operator.hh | 1 - libqpdf/qpdf/QPDF_Real.hh | 1 - libqpdf/qpdf/QPDF_Reserved.hh | 1 - libqpdf/qpdf/QPDF_Stream.hh | 1 - libqpdf/qpdf/QPDF_String.hh | 1 - libqpdf/qpdf/QPDF_Unresolved.hh | 1 - 31 files changed, 5 insertions(+), 196 deletions(-) (limited to 'libqpdf/QPDF_Stream.cc') diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 7af83a68..4fda24f5 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -1618,7 +1618,11 @@ QPDFObjectHandle::getJSON(int json_version, bool dereference_indirect) } else if (!dereference()) { throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle"); } else { - return obj->getJSON(json_version); + Pl_Buffer p{"json"}; + JSON::Writer jw{&p, 0}; + writeJSON(json_version, jw, dereference_indirect); + p.finish(); + return JSON::parse(p.getString()); } } diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc index 6e50a781..ab2a4c8c 100644 --- a/libqpdf/QPDF_Array.cc +++ b/libqpdf/QPDF_Array.cc @@ -149,38 +149,6 @@ QPDF_Array::unparse() return result; } -JSON -QPDF_Array::getJSON(int json_version) -{ - static const JSON j_null = JSON::makeNull(); - JSON j_array = JSON::makeArray(); - if (sp) { - int next = 0; - for (auto& item: sp->elements) { - int key = item.first; - for (int j = next; j < key; ++j) { - j_array.addArrayElement(j_null); - } - auto og = item.second->getObjGen(); - j_array.addArrayElement( - og.isIndirect() ? JSON::makeString(og.unparse(' ') + " R") - : item.second->getJSON(json_version)); - next = ++key; - } - for (int j = next; j < sp->size; ++j) { - j_array.addArrayElement(j_null); - } - } else { - for (auto const& item: elements) { - auto og = item->getObjGen(); - j_array.addArrayElement( - og.isIndirect() ? JSON::makeString(og.unparse(' ') + " R") - : item->getJSON(json_version)); - } - } - return j_array; -} - void QPDF_Array::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Bool.cc b/libqpdf/QPDF_Bool.cc index 9e57e68e..97f47881 100644 --- a/libqpdf/QPDF_Bool.cc +++ b/libqpdf/QPDF_Bool.cc @@ -26,12 +26,6 @@ QPDF_Bool::unparse() return (val ? "true" : "false"); } -JSON -QPDF_Bool::getJSON(int json_version) -{ - return JSON::makeBool(this->val); -} - void QPDF_Bool::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Destroyed.cc b/libqpdf/QPDF_Destroyed.cc index 06d1a83c..5e04566a 100644 --- a/libqpdf/QPDF_Destroyed.cc +++ b/libqpdf/QPDF_Destroyed.cc @@ -28,13 +28,6 @@ QPDF_Destroyed::unparse() return ""; } -JSON -QPDF_Destroyed::getJSON(int json_version) -{ - throw std::logic_error("attempted to get JSON from a QPDFObjectHandle from a destroyed QPDF"); - return JSON::makeNull(); -} - void QPDF_Destroyed::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Dictionary.cc b/libqpdf/QPDF_Dictionary.cc index ca7fa04a..9332b1d3 100644 --- a/libqpdf/QPDF_Dictionary.cc +++ b/libqpdf/QPDF_Dictionary.cc @@ -68,26 +68,6 @@ QPDF_Dictionary::unparse() return result; } -JSON -QPDF_Dictionary::getJSON(int json_version) -{ - JSON j = JSON::makeDictionary(); - for (auto& iter: this->items) { - if (!iter.second.isNull()) { - if (json_version == 1) { - j.addDictionaryMember( - QPDF_Name::normalizeName(iter.first), iter.second.getJSON(json_version)); - } else if (auto res = QPDF_Name::analyzeJSONEncoding(iter.first); res.first) { - j.addDictionaryMember(iter.first, iter.second.getJSON(json_version)); - } else { - j.addDictionaryMember( - "n:" + QPDF_Name::normalizeName(iter.first), iter.second.getJSON(json_version)); - } - } - } - return j; -} - void QPDF_Dictionary::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_InlineImage.cc b/libqpdf/QPDF_InlineImage.cc index bb5c4d0f..2d62071d 100644 --- a/libqpdf/QPDF_InlineImage.cc +++ b/libqpdf/QPDF_InlineImage.cc @@ -26,12 +26,6 @@ QPDF_InlineImage::unparse() return this->val; } -JSON -QPDF_InlineImage::getJSON(int json_version) -{ - return JSON::makeNull(); -} - void QPDF_InlineImage::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Integer.cc b/libqpdf/QPDF_Integer.cc index d65b3478..aa0437a1 100644 --- a/libqpdf/QPDF_Integer.cc +++ b/libqpdf/QPDF_Integer.cc @@ -27,12 +27,6 @@ QPDF_Integer::unparse() return std::to_string(this->val); } -JSON -QPDF_Integer::getJSON(int json_version) -{ - return JSON::makeInt(this->val); -} - void QPDF_Integer::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Name.cc b/libqpdf/QPDF_Name.cc index 04614769..bcc9498b 100644 --- a/libqpdf/QPDF_Name.cc +++ b/libqpdf/QPDF_Name.cc @@ -103,20 +103,6 @@ QPDF_Name::analyzeJSONEncoding(const std::string& name) return {tail == 0, !needs_escaping}; } -JSON -QPDF_Name::getJSON(int json_version) -{ - if (json_version == 1) { - return JSON::makeString(normalizeName(this->name)); - } else { - if (auto res = analyzeJSONEncoding(name); res.first) { - return JSON::makeString(name); - } else { - return JSON::makeString("n:" + normalizeName(name)); - } - } -} - void QPDF_Name::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Null.cc b/libqpdf/QPDF_Null.cc index 13118e8c..fa4b6cab 100644 --- a/libqpdf/QPDF_Null.cc +++ b/libqpdf/QPDF_Null.cc @@ -44,13 +44,6 @@ QPDF_Null::unparse() return "null"; } -JSON -QPDF_Null::getJSON(int json_version) -{ - // If this is updated, QPDF_Array::getJSON must also be updated. - return JSON::makeNull(); -} - void QPDF_Null::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Operator.cc b/libqpdf/QPDF_Operator.cc index 763c4f12..c35a8391 100644 --- a/libqpdf/QPDF_Operator.cc +++ b/libqpdf/QPDF_Operator.cc @@ -26,12 +26,6 @@ QPDF_Operator::unparse() return val; } -JSON -QPDF_Operator::getJSON(int json_version) -{ - return JSON::makeNull(); -} - void QPDF_Operator::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Real.cc b/libqpdf/QPDF_Real.cc index af96c9df..f4304397 100644 --- a/libqpdf/QPDF_Real.cc +++ b/libqpdf/QPDF_Real.cc @@ -39,25 +39,6 @@ QPDF_Real::unparse() return this->val; } -JSON -QPDF_Real::getJSON(int json_version) -{ - // While PDF allows .x or -.x, JSON does not. Rather than converting from string to double and - // back, just handle this as a special case for JSON. - std::string result; - if (this->val.length() == 0) { - // Can't really happen... - result = "0"; - } else if (this->val.at(0) == '.') { - result = "0" + this->val; - } else if ((this->val.length() >= 2) && (this->val.at(0) == '-') && (this->val.at(1) == '.')) { - result = "-0." + this->val.substr(2); - } else { - result = this->val; - } - return JSON::makeNumber(result); -} - void QPDF_Real::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Reserved.cc b/libqpdf/QPDF_Reserved.cc index 0be60c98..da112acc 100644 --- a/libqpdf/QPDF_Reserved.cc +++ b/libqpdf/QPDF_Reserved.cc @@ -26,13 +26,6 @@ QPDF_Reserved::unparse() return ""; } -JSON -QPDF_Reserved::getJSON(int json_version) -{ - throw std::logic_error("QPDFObjectHandle: attempting to get JSON from a reserved object"); - return JSON::makeNull(); -} - void QPDF_Reserved::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index bedc96b2..8189ae7b 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -177,15 +177,6 @@ QPDF_Stream::unparse() return og.unparse(' ') + " R"; } -JSON -QPDF_Stream::getJSON(int json_version) -{ - if (json_version == 1) { - return this->stream_dict.getJSON(json_version); - } - return getStreamJSON(json_version, qpdf_sj_none, qpdf_dl_none, nullptr, ""); -} - void QPDF_Stream::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_String.cc b/libqpdf/QPDF_String.cc index d3fcaaef..f425b313 100644 --- a/libqpdf/QPDF_String.cc +++ b/libqpdf/QPDF_String.cc @@ -46,35 +46,6 @@ QPDF_String::unparse() return unparse(false); } -JSON -QPDF_String::getJSON(int json_version) -{ - if (json_version == 1) { - return JSON::makeString(getUTF8Val()); - } - // See if we can unambiguously represent as Unicode. - bool is_unicode = false; - std::string result; - std::string candidate = getUTF8Val(); - if (QUtil::is_utf16(this->val) || QUtil::is_explicit_utf8(this->val)) { - is_unicode = true; - result = candidate; - } else if (!useHexString()) { - std::string test; - if (QUtil::utf8_to_pdf_doc(candidate, test, '?') && (test == this->val)) { - // This is a PDF-doc string that can be losslessly encoded as Unicode. - is_unicode = true; - result = candidate; - } - } - if (is_unicode) { - result = "u:" + result; - } else { - result = "b:" + QUtil::hex_encode(this->val); - } - return JSON::makeString(result); -} - void QPDF_String::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/QPDF_Unresolved.cc b/libqpdf/QPDF_Unresolved.cc index c2a50dbf..dc14c2f2 100644 --- a/libqpdf/QPDF_Unresolved.cc +++ b/libqpdf/QPDF_Unresolved.cc @@ -27,13 +27,6 @@ QPDF_Unresolved::unparse() return ""; } -JSON -QPDF_Unresolved::getJSON(int json_version) -{ - throw std::logic_error("attempted to get JSON from an unresolved QPDFObjectHandle"); - return JSON::makeNull(); -} - void QPDF_Unresolved::writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/qpdf/QPDFObject_private.hh b/libqpdf/qpdf/QPDFObject_private.hh index b873bcd0..1c3dadc9 100644 --- a/libqpdf/qpdf/QPDFObject_private.hh +++ b/libqpdf/qpdf/QPDFObject_private.hh @@ -33,11 +33,6 @@ class QPDFObject { return value->unparse(); } - JSON - getJSON(int json_version) - { - return value->getJSON(json_version); - } void writeJSON(int json_version, JSON::Writer& p) { diff --git a/libqpdf/qpdf/QPDFValue.hh b/libqpdf/qpdf/QPDFValue.hh index f7783466..28abf147 100644 --- a/libqpdf/qpdf/QPDFValue.hh +++ b/libqpdf/qpdf/QPDFValue.hh @@ -24,7 +24,6 @@ class QPDFValue: public std::enable_shared_from_this virtual std::shared_ptr copy(bool shallow = false) = 0; virtual std::string unparse() = 0; - virtual JSON getJSON(int json_version) = 0; virtual void writeJSON(int json_version, JSON::Writer& p) = 0; struct JSON_Descr diff --git a/libqpdf/qpdf/QPDF_Array.hh b/libqpdf/qpdf/QPDF_Array.hh index 7ee69b8e..88b2a3d3 100644 --- a/libqpdf/qpdf/QPDF_Array.hh +++ b/libqpdf/qpdf/QPDF_Array.hh @@ -22,7 +22,6 @@ class QPDF_Array: public QPDFValue create(std::vector>&& items, bool sparse); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; void disconnect() override; diff --git a/libqpdf/qpdf/QPDF_Bool.hh b/libqpdf/qpdf/QPDF_Bool.hh index f4ce0b1c..1692bdc4 100644 --- a/libqpdf/qpdf/QPDF_Bool.hh +++ b/libqpdf/qpdf/QPDF_Bool.hh @@ -10,7 +10,6 @@ class QPDF_Bool: public QPDFValue static std::shared_ptr create(bool val); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; bool getVal() const; diff --git a/libqpdf/qpdf/QPDF_Destroyed.hh b/libqpdf/qpdf/QPDF_Destroyed.hh index 400921e3..9259a2dc 100644 --- a/libqpdf/qpdf/QPDF_Destroyed.hh +++ b/libqpdf/qpdf/QPDF_Destroyed.hh @@ -9,7 +9,6 @@ class QPDF_Destroyed: public QPDFValue ~QPDF_Destroyed() override = default; std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; static std::shared_ptr getInstance(); diff --git a/libqpdf/qpdf/QPDF_Dictionary.hh b/libqpdf/qpdf/QPDF_Dictionary.hh index 32c926a3..8713a450 100644 --- a/libqpdf/qpdf/QPDF_Dictionary.hh +++ b/libqpdf/qpdf/QPDF_Dictionary.hh @@ -16,7 +16,6 @@ class QPDF_Dictionary: public QPDFValue static std::shared_ptr create(std::map&& items); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; void disconnect() override; diff --git a/libqpdf/qpdf/QPDF_InlineImage.hh b/libqpdf/qpdf/QPDF_InlineImage.hh index cc4dc31a..c06662d7 100644 --- a/libqpdf/qpdf/QPDF_InlineImage.hh +++ b/libqpdf/qpdf/QPDF_InlineImage.hh @@ -10,7 +10,6 @@ class QPDF_InlineImage: public QPDFValue static std::shared_ptr create(std::string const& val); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; std::string getStringValue() const override diff --git a/libqpdf/qpdf/QPDF_Integer.hh b/libqpdf/qpdf/QPDF_Integer.hh index dd2f9e0d..ae7f7893 100644 --- a/libqpdf/qpdf/QPDF_Integer.hh +++ b/libqpdf/qpdf/QPDF_Integer.hh @@ -10,7 +10,6 @@ class QPDF_Integer: public QPDFValue static std::shared_ptr create(long long value); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; long long getVal() const; diff --git a/libqpdf/qpdf/QPDF_Name.hh b/libqpdf/qpdf/QPDF_Name.hh index fd4ac458..b5d3c318 100644 --- a/libqpdf/qpdf/QPDF_Name.hh +++ b/libqpdf/qpdf/QPDF_Name.hh @@ -10,7 +10,6 @@ class QPDF_Name: public QPDFValue static std::shared_ptr create(std::string const& name); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; // Put # into strings with characters unsuitable for name token diff --git a/libqpdf/qpdf/QPDF_Null.hh b/libqpdf/qpdf/QPDF_Null.hh index 2a099bf9..fc6e0b5f 100644 --- a/libqpdf/qpdf/QPDF_Null.hh +++ b/libqpdf/qpdf/QPDF_Null.hh @@ -18,7 +18,6 @@ class QPDF_Null: public QPDFValue std::string var_descr); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; private: diff --git a/libqpdf/qpdf/QPDF_Operator.hh b/libqpdf/qpdf/QPDF_Operator.hh index d8b99e17..b9b040d6 100644 --- a/libqpdf/qpdf/QPDF_Operator.hh +++ b/libqpdf/qpdf/QPDF_Operator.hh @@ -10,7 +10,6 @@ class QPDF_Operator: public QPDFValue static std::shared_ptr create(std::string const& val); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; std::string getStringValue() const override diff --git a/libqpdf/qpdf/QPDF_Real.hh b/libqpdf/qpdf/QPDF_Real.hh index 5fec919d..aa9baa5f 100644 --- a/libqpdf/qpdf/QPDF_Real.hh +++ b/libqpdf/qpdf/QPDF_Real.hh @@ -12,7 +12,6 @@ class QPDF_Real: public QPDFValue create(double value, int decimal_places, bool trim_trailing_zeroes); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; std::string getStringValue() const override diff --git a/libqpdf/qpdf/QPDF_Reserved.hh b/libqpdf/qpdf/QPDF_Reserved.hh index 4503fb9e..801987e4 100644 --- a/libqpdf/qpdf/QPDF_Reserved.hh +++ b/libqpdf/qpdf/QPDF_Reserved.hh @@ -10,7 +10,6 @@ class QPDF_Reserved: public QPDFValue static std::shared_ptr create(); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; private: diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh index 597a48a8..d8d1d16a 100644 --- a/libqpdf/qpdf/QPDF_Stream.hh +++ b/libqpdf/qpdf/QPDF_Stream.hh @@ -25,7 +25,6 @@ class QPDF_Stream: public QPDFValue size_t length); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; void setDescription( QPDF*, std::shared_ptr& description, qpdf_offset_t offset) override; diff --git a/libqpdf/qpdf/QPDF_String.hh b/libqpdf/qpdf/QPDF_String.hh index e7a87a53..967b2d30 100644 --- a/libqpdf/qpdf/QPDF_String.hh +++ b/libqpdf/qpdf/QPDF_String.hh @@ -16,7 +16,6 @@ class QPDF_String: public QPDFValue std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; std::string unparse(bool force_binary); - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; std::string getUTF8Val() const; std::string diff --git a/libqpdf/qpdf/QPDF_Unresolved.hh b/libqpdf/qpdf/QPDF_Unresolved.hh index 669e314e..b4c1d9e4 100644 --- a/libqpdf/qpdf/QPDF_Unresolved.hh +++ b/libqpdf/qpdf/QPDF_Unresolved.hh @@ -10,7 +10,6 @@ class QPDF_Unresolved: public QPDFValue static std::shared_ptr create(QPDF* qpdf, QPDFObjGen const& og); std::shared_ptr copy(bool shallow = false) override; std::string unparse() override; - JSON getJSON(int json_version) override; void writeJSON(int json_version, JSON::Writer& p) override; private: -- cgit v1.2.3-54-g00ecf From 920e929864aecf1e9e16c96565ac28a9121e278e Mon Sep 17 00:00:00 2001 From: m-holger Date: Wed, 14 Feb 2024 15:59:00 +0000 Subject: Reimplement QPDF_Stream::getStreamJSON in terms of writeStreamJSON writeStreamJSON is a temporary implementation minimally adapted from getStreamJSON. --- libqpdf/QPDF_Stream.cc | 48 +++++++++++++++++++++++++++++++++------------ libqpdf/qpdf/QPDF_Stream.hh | 8 ++++++++ 2 files changed, 44 insertions(+), 12 deletions(-) (limited to 'libqpdf/QPDF_Stream.cc') diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index 8189ae7b..d7087819 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -190,22 +190,44 @@ QPDF_Stream::getStreamJSON( qpdf_stream_decode_level_e decode_level, Pipeline* p, std::string const& data_filename) +{ + Pl_Buffer pb{"streamjson"}; + JSON::Writer jw{&pb, 0}; + decode_level = + writeStreamJSON(json_version, jw, json_data, decode_level, p, data_filename, true); + pb.finish(); + auto result = JSON::parse(pb.getString()); + if (json_data == qpdf_sj_inline) { + result.addDictionaryMember("data", JSON::makeBlob(StreamBlobProvider(this, decode_level))); + } + return result; +} + +qpdf_stream_decode_level_e +QPDF_Stream::writeStreamJSON( + int json_version, + JSON::Writer& jw, + qpdf_json_stream_data_e json_data, + qpdf_stream_decode_level_e decode_level, + Pipeline* p, + std::string const& data_filename, + bool no_data_key) { switch (json_data) { case qpdf_sj_none: case qpdf_sj_inline: if (p != nullptr) { - throw std::logic_error("QPDF_Stream::getStreamJSON: pipeline should only be supplied " + throw std::logic_error("QPDF_Stream::writeStreamJSON: pipeline should only be supplied " "when json_data is file"); } break; case qpdf_sj_file: if (p == nullptr) { throw std::logic_error( - "QPDF_Stream::getStreamJSON: pipeline must be supplied when json_data is file"); + "QPDF_Stream::writeStreamJSON: pipeline must be supplied when json_data is file"); } if (data_filename.empty()) { - throw std::logic_error("QPDF_Stream::getStreamJSON: data_filename must be supplied " + throw std::logic_error("QPDF_Stream::writeStreamJSON: data_filename must be supplied " "when json_data is file"); } break; @@ -234,12 +256,13 @@ QPDF_Stream::getStreamJSON( decode_level = qpdf_dl_none; buf_pl.getString(); // reset buf_pl } else { - if (json_data == qpdf_sj_file) { - buf_pl_ready = true; - } + buf_pl_ready = true; break; } } + if (!buf_pl_ready) { + throw std::logic_error("QPDF_Stream: failed to get stream data"); + } // We can use unsafeShallowCopy because we are only touching top-level keys. dict = this->stream_dict.unsafeShallowCopy(); dict.removeKey("/Length"); @@ -249,19 +272,20 @@ QPDF_Stream::getStreamJSON( } if (json_data == qpdf_sj_file) { result.addDictionaryMember("datafile", JSON::makeString(data_filename)); - if (!buf_pl_ready) { - throw std::logic_error("QPDF_Stream: failed to get stream data in json file mode"); - } + p->writeString(buf_pl.getString()); } else if (json_data == qpdf_sj_inline) { - result.addDictionaryMember( - "data", JSON::makeBlob(StreamBlobProvider(this, decode_level))); + if (!no_data_key) { + result.addDictionaryMember( + "data", JSON::makeBlob(StreamBlobProvider(this, decode_level))); + } } else { throw std::logic_error("QPDF_Stream: unexpected value of json_data"); } } result.addDictionaryMember("dict", dict.getJSON(json_version)); - return result; + jw << std::move(result); + return decode_level; } void diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh index d8d1d16a..3fcbc428 100644 --- a/libqpdf/qpdf/QPDF_Stream.hh +++ b/libqpdf/qpdf/QPDF_Stream.hh @@ -64,6 +64,14 @@ class QPDF_Stream: public QPDFValue qpdf_stream_decode_level_e decode_level, Pipeline* p, std::string const& data_filename); + qpdf_stream_decode_level_e writeStreamJSON( + int json_version, + JSON::Writer& jw, + qpdf_json_stream_data_e json_data, + qpdf_stream_decode_level_e decode_level, + Pipeline* p, + std::string const& data_filename, + bool no_data_key = false); void replaceDict(QPDFObjectHandle const& new_dict); -- cgit v1.2.3-54-g00ecf From b15d0bf6e1305982450879b498a116d3387b705b Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 15 Feb 2024 12:33:31 +0000 Subject: Add new method QPDF_Stream::writeStreamJSON (Replacing the temporary implementation from the last commit.) --- libqpdf/QPDF_Stream.cc | 109 +++++++++++++++++++++++--------------------- libqpdf/qpdf/JSON_writer.hh | 12 +++++ 2 files changed, 70 insertions(+), 51 deletions(-) (limited to 'libqpdf/QPDF_Stream.cc') diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index d7087819..6cfcdd46 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -178,9 +178,9 @@ QPDF_Stream::unparse() } void -QPDF_Stream::writeJSON(int json_version, JSON::Writer& p) +QPDF_Stream::writeJSON(int json_version, JSON::Writer& jw) { - stream_dict.writeJSON(json_version, p); + stream_dict.writeJSON(json_version, jw); } JSON @@ -233,58 +233,65 @@ QPDF_Stream::writeStreamJSON( break; } - auto dict = this->stream_dict; - JSON result = JSON::makeDictionary(); - if (json_data != qpdf_sj_none) { - Pl_Discard discard; - Pl_Buffer buf_pl{"stream data"}; - // buf_pl contains valid data and is ready for retrieval of the data. - bool buf_pl_ready = false; - bool filtered = false; - bool filter = (decode_level != qpdf_dl_none); - for (int attempt = 1; attempt <= 2; ++attempt) { - Pipeline* data_pipeline = &discard; - if (json_data == qpdf_sj_file) { - // We need to capture the data to write - data_pipeline = &buf_pl; - } - bool succeeded = - pipeStreamData(data_pipeline, &filtered, 0, decode_level, false, (attempt == 1)); - if (!succeeded || (filter && !filtered)) { - // Try again - filter = false; - decode_level = qpdf_dl_none; - buf_pl.getString(); // reset buf_pl - } else { - buf_pl_ready = true; - break; - } - } - if (!buf_pl_ready) { - throw std::logic_error("QPDF_Stream: failed to get stream data"); - } - // We can use unsafeShallowCopy because we are only touching top-level keys. - dict = this->stream_dict.unsafeShallowCopy(); - dict.removeKey("/Length"); - if (filter && filtered) { - dict.removeKey("/Filter"); - dict.removeKey("/DecodeParms"); - } - if (json_data == qpdf_sj_file) { - result.addDictionaryMember("datafile", JSON::makeString(data_filename)); - - p->writeString(buf_pl.getString()); - } else if (json_data == qpdf_sj_inline) { - if (!no_data_key) { - result.addDictionaryMember( - "data", JSON::makeBlob(StreamBlobProvider(this, decode_level))); - } + jw.writeStart('{'); + + if (json_data == qpdf_sj_none) { + jw.writeNext(); + jw << R"("dict": )"; + stream_dict.writeJSON(json_version, jw); + jw.writeEnd('}'); + return decode_level; + } + + Pl_Discard discard; + Pl_Buffer buf_pl{"stream data"}; + Pipeline* data_pipeline = &buf_pl; + if (no_data_key && json_data == qpdf_sj_inline) { + data_pipeline = &discard; + } + // pipeStreamData produced valid data. + bool buf_pl_ready = false; + bool filtered = false; + bool filter = (decode_level != qpdf_dl_none); + for (int attempt = 1; attempt <= 2; ++attempt) { + bool succeeded = + pipeStreamData(data_pipeline, &filtered, 0, decode_level, false, (attempt == 1)); + if (!succeeded || (filter && !filtered)) { + // Try again + filter = false; + decode_level = qpdf_dl_none; + buf_pl.getString(); // reset buf_pl } else { - throw std::logic_error("QPDF_Stream: unexpected value of json_data"); + buf_pl_ready = true; + break; + } + } + if (!buf_pl_ready) { + throw std::logic_error("QPDF_Stream: failed to get stream data"); + } + // We can use unsafeShallowCopy because we are only touching top-level keys. + auto dict = stream_dict.unsafeShallowCopy(); + dict.removeKey("/Length"); + if (filter && filtered) { + dict.removeKey("/Filter"); + dict.removeKey("/DecodeParms"); + } + if (json_data == qpdf_sj_file) { + jw.writeNext() << R"("datafile": ")" << JSON::Writer::encode_string(data_filename) << "\""; + p->writeString(buf_pl.getString()); + } else if (json_data == qpdf_sj_inline) { + if (!no_data_key) { + jw.writeNext() << R"("data": ")"; + jw.writeBase64(buf_pl.getString()) << "\""; } + } else { + throw std::logic_error("QPDF_Stream::writeStreamJSON : unexpected value of json_data"); } - result.addDictionaryMember("dict", dict.getJSON(json_version)); - jw << std::move(result); + + jw.writeNext() << R"("dict": )"; + dict.writeJSON(json_version, jw); + jw.writeEnd('}'); + return decode_level; } diff --git a/libqpdf/qpdf/JSON_writer.hh b/libqpdf/qpdf/JSON_writer.hh index 6d870b88..3f770c58 100644 --- a/libqpdf/qpdf/JSON_writer.hh +++ b/libqpdf/qpdf/JSON_writer.hh @@ -3,6 +3,8 @@ #include #include +#include +#include #include @@ -27,6 +29,16 @@ class JSON::Writer return *this; } + Writer& + writeBase64(std::string_view sv) + { + Pl_Concatenate cat{"writer concat", p}; + Pl_Base64 base{"writer base64", &cat, Pl_Base64::a_encode}; + base.write(reinterpret_cast(sv.data()), sv.size()); + base.finish(); + return *this; + } + Writer& writeNext() { -- cgit v1.2.3-54-g00ecf