From e259635986a799f0b72b6040aba8c1ed870e552a Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Wed, 4 May 2022 08:32:54 -0400 Subject: JSON: add write methods and implement unparse() in terms of those --- libqpdf/JSON.cc | 165 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 51 deletions(-) (limited to 'libqpdf/JSON.cc') diff --git a/libqpdf/JSON.cc b/libqpdf/JSON.cc index 0f589804..3c5ddafd 100644 --- a/libqpdf/JSON.cc +++ b/libqpdf/JSON.cc @@ -1,5 +1,7 @@ #include +#include +#include #include #include #include @@ -18,51 +20,103 @@ JSON::JSON(std::shared_ptr value) : { } -std::string -JSON::JSON_dictionary::unparse(size_t depth) const +void +JSON::writeClose(Pipeline* p, bool first, size_t depth, char const* delimiter) +{ + if (!first) { + *p << "\n"; + writeIndent(p, depth); + } + *p << delimiter; +} + +void +JSON::writeIndent(Pipeline* p, size_t depth) +{ + for (size_t i = 0; i < depth; ++i) { + *p << " "; + } +} + +void +JSON::writeNext(Pipeline* p, bool& first, size_t depth) +{ + if (first) { + first = false; + } else { + *p << ","; + } + *p << "\n"; + writeIndent(p, 1 + depth); +} + +void +JSON::writeDictionaryOpen(Pipeline* p, bool& first, size_t depth) +{ + *p << "{"; + first = true; +} + +void +JSON::writeArrayOpen(Pipeline* p, bool& first, size_t depth) +{ + *p << "["; + first = true; +} + +void +JSON::writeDictionaryClose(Pipeline* p, bool first, size_t depth) +{ + writeClose(p, first, depth, "}"); +} + +void +JSON::writeArrayClose(Pipeline* p, bool first, size_t depth) +{ + writeClose(p, first, depth, "]"); +} + +void +JSON::writeDictionaryItem( + Pipeline* p, + bool& first, + std::string const& key, + JSON const& value, + size_t depth) +{ + writeNext(p, first, depth); + *p << "\"" << key << "\": "; + value.write(p, 1 + depth); +} + +void +JSON::writeArrayItem( + Pipeline* p, bool& first, JSON const& element, size_t depth) +{ + writeNext(p, first, depth); + element.write(p, 1 + depth); +} + +void +JSON::JSON_dictionary::write(Pipeline* p, size_t depth) const { - std::string result = "{"; bool first = true; + writeDictionaryOpen(p, first, depth); for (auto const& iter: members) { - if (first) { - first = false; - } else { - result.append(1, ','); - } - result.append(1, '\n'); - result.append(2 * (1 + depth), ' '); - result += - ("\"" + iter.first + "\": " + iter.second->unparse(1 + depth)); + writeDictionaryItem(p, first, iter.first, iter.second, depth); } - if (!first) { - result.append(1, '\n'); - result.append(2 * depth, ' '); - } - result.append(1, '}'); - return result; + writeDictionaryClose(p, first, depth); } -std::string -JSON::JSON_array::unparse(size_t depth) const +void +JSON::JSON_array::write(Pipeline* p, size_t depth) const { - std::string result = "["; bool first = true; + writeArrayOpen(p, first, depth); for (auto const& element: elements) { - if (first) { - first = false; - } else { - result.append(1, ','); - } - result.append(1, '\n'); - result.append(2 * (1 + depth), ' '); - result += element->unparse(1 + depth); - } - if (!first) { - result.append(1, '\n'); - result.append(2 * depth, ' '); + writeArrayItem(p, first, element, depth); } - result.append(1, ']'); - return result; + writeArrayClose(p, first, depth); } JSON::JSON_string::JSON_string(std::string const& utf8) : @@ -71,10 +125,10 @@ JSON::JSON_string::JSON_string(std::string const& utf8) : { } -std::string -JSON::JSON_string::unparse(size_t) const +void +JSON::JSON_string::write(Pipeline* p, size_t) const { - return "\"" + encoded + "\""; + *p << "\"" << encoded << "\""; } JSON::JSON_number::JSON_number(long long value) : @@ -92,10 +146,10 @@ JSON::JSON_number::JSON_number(std::string const& value) : { } -std::string -JSON::JSON_number::unparse(size_t) const +void +JSON::JSON_number::write(Pipeline* p, size_t) const { - return encoded; + *p << encoded; } JSON::JSON_bool::JSON_bool(bool val) : @@ -103,28 +157,37 @@ JSON::JSON_bool::JSON_bool(bool val) : { } -std::string -JSON::JSON_bool::unparse(size_t) const +void +JSON::JSON_bool::write(Pipeline* p, size_t) const { - return value ? "true" : "false"; + *p << (value ? "true" : "false"); } -std::string -JSON::JSON_null::unparse(size_t) const +void +JSON::JSON_null::write(Pipeline* p, size_t) const { - return "null"; + *p << "null"; } -std::string -JSON::unparse() const +void +JSON::write(Pipeline* p, size_t depth) const { if (0 == this->m->value.get()) { - return "null"; + *p << "null"; } else { - return this->m->value->unparse(0); + this->m->value->write(p, depth); } } +std::string +JSON::unparse() const +{ + std::string s; + Pl_String p("unparse", s); + write(&p, 0); + return s; +} + std::string JSON::encode_string(std::string const& str) { -- cgit v1.2.3-54-g00ecf