20#include <xrpl/json/Output.h>
21#include <xrpl/json/Writer.h>
39static size_t const jsonEscapeLength = 2;
42const char closeBrace =
'}';
43const char closeBracket =
']';
44const char colon =
':';
45const char comma =
',';
46const char openBrace =
'{';
47const char openBracket =
'[';
48const char quote =
'"';
50static auto const integralFloatsBecomeInts =
false;
55 auto dotPos = s.
find(
'.');
56 if (dotPos == std::string::npos)
60 auto hasDecimals = dotPos != lastNonZero;
63 return lastNonZero + 1;
65 if (integralFloatsBecomeInts || lastNonZero + 2 > s.
size())
68 return lastNonZero + 2;
94 char ch = (ct ==
array) ? openBracket : openBrace;
101 output(boost::beast::string_view
const& bytes)
114 auto data = bytes.data();
115 for (; position < bytes.size(); ++position)
117 auto i = jsonSpecialCharacterEscape.
find(data[position]);
118 if (i != jsonSpecialCharacterEscape.
end())
120 if (writtenUntil < position)
122 output_({data + writtenUntil, position - writtenUntil});
124 output_({i->second, jsonEscapeLength});
125 writtenUntil = position + 1;
128 if (writtenUntil < position)
129 output_({data + writtenUntil, position - writtenUntil});
151 ((type ==
array ?
"array: " :
"object: ") + message));
165 check(tags.find(tag) == tags.end(),
"Already seen tag " + tag);
185 auto ch = isArray ? closeBracket : closeBrace;
245 impl_ = std::move(w.impl_);
251 impl_ = std::move(w.impl_);
258 impl_->stringOutput(s);
264 impl_->stringOutput(s);
270 impl_->markStarted();
278 impl_->output({s.
data(), lengthWithoutTrailingZeros(s)});
285 impl_->output({s.
data(), lengthWithoutTrailingZeros(s)});
291 impl_->output(
"null");
297 impl_->output(b ?
"true" :
"false");
324 impl_->nextCollectionEntry(
object,
"set");
325 impl_->writeObjectTag(tag);
337 impl_->nextCollectionEntry(
array,
"startAppend");
344 impl_->nextCollectionEntry(
object,
"startSet");
345 impl_->writeObjectTag(key);
void nextCollectionEntry(CollectionType type, std::string const &message)
void stringOutput(boost::beast::string_view const &bytes)
void writeObjectTag(std::string const &tag)
Impl & operator=(Impl &&)=delete
Output const & getOutput() const
void output(boost::beast::string_view const &bytes)
Impl(Output const &output)
void start(CollectionType ct)
Writer implements an O(1)-space, O(1)-granular output JSON writer.
Writer & operator=(Writer &&) noexcept
void finish()
Finish the collection most recently started.
void output(std::string const &)
void implOutput(std::string const &)
void startRoot(CollectionType)
Start a new collection at the root level.
void rawAppend()
Add a comma before this next item if not the first item in an array.
void rawSet(std::string const &key)
Emit just "tag": as part of an object.
void finishAll()
Finish all objects and arrays.
Writer(Output const &output)
void startAppend(CollectionType)
Start a new collection inside an array.
void startSet(CollectionType, std::string const &key)
Start a new collection inside an object.
std::unique_ptr< Impl > impl_
T find_last_not_of(T... args)
JSON (JavaScript Object Notation).
void outputJson(Json::Value const &, Output const &)
Writes a minimal representation of a Json value to an Output in O(n) time.
void check(bool condition, std::string const &message)
std::string to_string(base_uint< Bits, Tag > const &a)
std::set< std::string > tags
What tags have we already seen in this collection?
bool isFirst
Is this the first entry in a collection? If false, we have to emit a , before we write the next entry...
Writer::CollectionType type
What type of collection are we in?