aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/qpdf
diff options
context:
space:
mode:
Diffstat (limited to 'libqpdf/qpdf')
-rw-r--r--libqpdf/qpdf/JSON_writer.hh137
-rw-r--r--libqpdf/qpdf/QPDFObject_private.hh6
-rw-r--r--libqpdf/qpdf/QPDFValue.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Array.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Bool.hh3
-rw-r--r--libqpdf/qpdf/QPDF_Destroyed.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Dictionary.hh2
-rw-r--r--libqpdf/qpdf/QPDF_InlineImage.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Integer.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Name.hh7
-rw-r--r--libqpdf/qpdf/QPDF_Null.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Operator.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Real.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Reserved.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Stream.hh10
-rw-r--r--libqpdf/qpdf/QPDF_String.hh2
-rw-r--r--libqpdf/qpdf/QPDF_Unresolved.hh2
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);