diff options
Diffstat (limited to 'libqpdf/qpdf')
-rw-r--r-- | libqpdf/qpdf/JSON_writer.hh | 137 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDFObject_private.hh | 6 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDFValue.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Array.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Bool.hh | 3 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Destroyed.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Dictionary.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_InlineImage.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Integer.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Name.hh | 7 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Null.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Operator.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Real.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Reserved.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Stream.hh | 10 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_String.hh | 2 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Unresolved.hh | 2 |
17 files changed, 169 insertions, 18 deletions
diff --git a/libqpdf/qpdf/JSON_writer.hh b/libqpdf/qpdf/JSON_writer.hh new file mode 100644 index 00000000..3f770c58 --- /dev/null +++ b/libqpdf/qpdf/JSON_writer.hh @@ -0,0 +1,137 @@ +#ifndef JSON_WRITER_HH +#define JSON_WRITER_HH + +#include <qpdf/JSON.hh> +#include <qpdf/Pipeline.hh> +#include <qpdf/Pl_Base64.hh> +#include <qpdf/Pl_Concatenate.hh> + +#include <string_view> + +// Writer is a small utility class to aid writing JSON to a pipeline. Methods are designed to allow +// chaining of calls. +// +// Some uses of the class have a significant performance impact. The class is intended purely for +// internal use to allow it to be adapted as needed to maintain performance. +class JSON::Writer +{ + public: + Writer(Pipeline* p, size_t depth) : + p(p), + indent(2 * depth) + { + } + + Writer& + write(char const* data, size_t len) + { + p->write(reinterpret_cast<unsigned char const*>(data), len); + 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<unsigned char const*>(sv.data()), sv.size()); + base.finish(); + return *this; + } + + Writer& + writeNext() + { + auto n = indent; + if (first) { + first = false; + write(&spaces[1], n % n_spaces + 1); + } else { + write(&spaces[0], n % n_spaces + 2); + } + while (n >= n_spaces) { + write(&spaces[2], n_spaces); + n -= n_spaces; + } + return *this; + } + + Writer& + writeStart(char const& c) + { + write(&c, 1); + first = true; + indent += 2; + return *this; + } + + Writer& + writeEnd(char const& c) + { + if (indent > 1) { + indent -= 2; + } + if (!first) { + first = true; + writeNext(); + } + first = false; + write(&c, 1); + return *this; + } + + Writer& + operator<<(std::string_view sv) + { + p->write(reinterpret_cast<unsigned char const*>(sv.data()), sv.size()); + return *this; + } + + Writer& + operator<<(char const* s) + { + *this << std::string_view{s}; + return *this; + } + + Writer& + operator<<(bool val) + { + *this << (val ? "true" : "false"); + return *this; + } + + Writer& + operator<<(int val) + { + *this << std::to_string(val); + return *this; + } + + Writer& + operator<<(size_t val) + { + *this << std::to_string(val); + return *this; + } + + Writer& + operator<<(JSON&& j) + { + j.write(p, indent / 2); + return *this; + } + + static std::string encode_string(std::string const& utf8); + + private: + Pipeline* p; + bool first{true}; + size_t indent; + + static constexpr std::string_view spaces = + ",\n "; + static constexpr auto n_spaces = spaces.size() - 2; +}; + +#endif // JSON_WRITER_HH diff --git a/libqpdf/qpdf/QPDFObject_private.hh b/libqpdf/qpdf/QPDFObject_private.hh index 5e87c215..1c3dadc9 100644 --- a/libqpdf/qpdf/QPDFObject_private.hh +++ b/libqpdf/qpdf/QPDFObject_private.hh @@ -33,10 +33,10 @@ class QPDFObject { return value->unparse(); } - JSON - getJSON(int json_version) + void + writeJSON(int json_version, JSON::Writer& p) { - return value->getJSON(json_version); + return value->writeJSON(json_version, p); } std::string getStringValue() const diff --git a/libqpdf/qpdf/QPDFValue.hh b/libqpdf/qpdf/QPDFValue.hh index db8fb923..28abf147 100644 --- a/libqpdf/qpdf/QPDFValue.hh +++ b/libqpdf/qpdf/QPDFValue.hh @@ -24,7 +24,7 @@ class QPDFValue: public std::enable_shared_from_this<QPDFValue> virtual std::shared_ptr<QPDFObject> 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 281e1d48..88b2a3d3 100644 --- a/libqpdf/qpdf/QPDF_Array.hh +++ b/libqpdf/qpdf/QPDF_Array.hh @@ -22,7 +22,7 @@ class QPDF_Array: public QPDFValue create(std::vector<std::shared_ptr<QPDFObject>>&& items, bool sparse); std::shared_ptr<QPDFObject> 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; int diff --git a/libqpdf/qpdf/QPDF_Bool.hh b/libqpdf/qpdf/QPDF_Bool.hh index 0b4a71fd..1692bdc4 100644 --- a/libqpdf/qpdf/QPDF_Bool.hh +++ b/libqpdf/qpdf/QPDF_Bool.hh @@ -10,7 +10,8 @@ class QPDF_Bool: public QPDFValue static std::shared_ptr<QPDFObject> create(bool val); std::shared_ptr<QPDFObject> 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; private: diff --git a/libqpdf/qpdf/QPDF_Destroyed.hh b/libqpdf/qpdf/QPDF_Destroyed.hh index 72e9130a..9259a2dc 100644 --- a/libqpdf/qpdf/QPDF_Destroyed.hh +++ b/libqpdf/qpdf/QPDF_Destroyed.hh @@ -9,7 +9,7 @@ class QPDF_Destroyed: public QPDFValue ~QPDF_Destroyed() override = default; std::shared_ptr<QPDFObject> 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<QPDFValue> getInstance(); private: diff --git a/libqpdf/qpdf/QPDF_Dictionary.hh b/libqpdf/qpdf/QPDF_Dictionary.hh index 0fb6636e..8713a450 100644 --- a/libqpdf/qpdf/QPDF_Dictionary.hh +++ b/libqpdf/qpdf/QPDF_Dictionary.hh @@ -16,7 +16,7 @@ class QPDF_Dictionary: public QPDFValue static std::shared_ptr<QPDFObject> create(std::map<std::string, QPDFObjectHandle>&& items); std::shared_ptr<QPDFObject> 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; // hasKey() and getKeys() treat keys with null values as if they aren't there. getKey() returns diff --git a/libqpdf/qpdf/QPDF_InlineImage.hh b/libqpdf/qpdf/QPDF_InlineImage.hh index bee12354..c06662d7 100644 --- a/libqpdf/qpdf/QPDF_InlineImage.hh +++ b/libqpdf/qpdf/QPDF_InlineImage.hh @@ -10,7 +10,7 @@ class QPDF_InlineImage: public QPDFValue static std::shared_ptr<QPDFObject> create(std::string const& val); std::shared_ptr<QPDFObject> 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 2c2cf2f9..ae7f7893 100644 --- a/libqpdf/qpdf/QPDF_Integer.hh +++ b/libqpdf/qpdf/QPDF_Integer.hh @@ -10,7 +10,7 @@ class QPDF_Integer: public QPDFValue static std::shared_ptr<QPDFObject> create(long long value); std::shared_ptr<QPDFObject> 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; private: diff --git a/libqpdf/qpdf/QPDF_Name.hh b/libqpdf/qpdf/QPDF_Name.hh index c14d8659..b5d3c318 100644 --- a/libqpdf/qpdf/QPDF_Name.hh +++ b/libqpdf/qpdf/QPDF_Name.hh @@ -10,10 +10,15 @@ class QPDF_Name: public QPDFValue static std::shared_ptr<QPDFObject> create(std::string const& name); std::shared_ptr<QPDFObject> 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 static std::string normalizeName(std::string const& name); + + // Check whether name is valid utf-8 and whether it contains characters that require escaping. + // Return {false, false} if the name is not valid utf-8, otherwise return {true, true} if no + // characters require or {true, false} if escaping is required. + static std::pair<bool, bool> analyzeJSONEncoding(std::string const& name); std::string getStringValue() const override { diff --git a/libqpdf/qpdf/QPDF_Null.hh b/libqpdf/qpdf/QPDF_Null.hh index a59b7509..fc6e0b5f 100644 --- a/libqpdf/qpdf/QPDF_Null.hh +++ b/libqpdf/qpdf/QPDF_Null.hh @@ -18,7 +18,7 @@ class QPDF_Null: public QPDFValue std::string var_descr); std::shared_ptr<QPDFObject> 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: QPDF_Null(); diff --git a/libqpdf/qpdf/QPDF_Operator.hh b/libqpdf/qpdf/QPDF_Operator.hh index 77aa5a17..b9b040d6 100644 --- a/libqpdf/qpdf/QPDF_Operator.hh +++ b/libqpdf/qpdf/QPDF_Operator.hh @@ -10,7 +10,7 @@ class QPDF_Operator: public QPDFValue static std::shared_ptr<QPDFObject> create(std::string const& val); std::shared_ptr<QPDFObject> 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 db5e0940..aa9baa5f 100644 --- a/libqpdf/qpdf/QPDF_Real.hh +++ b/libqpdf/qpdf/QPDF_Real.hh @@ -12,7 +12,7 @@ class QPDF_Real: public QPDFValue create(double value, int decimal_places, bool trim_trailing_zeroes); std::shared_ptr<QPDFObject> 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 9ba855b7..801987e4 100644 --- a/libqpdf/qpdf/QPDF_Reserved.hh +++ b/libqpdf/qpdf/QPDF_Reserved.hh @@ -10,7 +10,7 @@ class QPDF_Reserved: public QPDFValue static std::shared_ptr<QPDFObject> create(); std::shared_ptr<QPDFObject> 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: QPDF_Reserved(); diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh index 8488e157..3fcbc428 100644 --- a/libqpdf/qpdf/QPDF_Stream.hh +++ b/libqpdf/qpdf/QPDF_Stream.hh @@ -25,7 +25,7 @@ class QPDF_Stream: public QPDFValue size_t length); std::shared_ptr<QPDFObject> 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<QPDFValue::Description>& description, qpdf_offset_t offset) override; void disconnect() override; @@ -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); diff --git a/libqpdf/qpdf/QPDF_String.hh b/libqpdf/qpdf/QPDF_String.hh index c34cafef..967b2d30 100644 --- a/libqpdf/qpdf/QPDF_String.hh +++ b/libqpdf/qpdf/QPDF_String.hh @@ -16,7 +16,7 @@ class QPDF_String: public QPDFValue std::shared_ptr<QPDFObject> 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 getStringValue() const override diff --git a/libqpdf/qpdf/QPDF_Unresolved.hh b/libqpdf/qpdf/QPDF_Unresolved.hh index 0a1fa9a5..b4c1d9e4 100644 --- a/libqpdf/qpdf/QPDF_Unresolved.hh +++ b/libqpdf/qpdf/QPDF_Unresolved.hh @@ -10,7 +10,7 @@ class QPDF_Unresolved: public QPDFValue static std::shared_ptr<QPDFObject> create(QPDF* qpdf, QPDFObjGen const& og); std::shared_ptr<QPDFObject> 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: QPDF_Unresolved(QPDF* qpdf, QPDFObjGen const& og); |