20#include <xrpl/basics/ToString.h>
21#include <xrpl/json/Output.h>
22#include <xrpl/json/Writer.h>
47static size_t const jsonEscapeLength = 2;
50const char closeBrace =
'}';
51const char closeBracket =
']';
52const char colon =
':';
53const char comma =
',';
54const char openBrace =
'{';
55const char openBracket =
'[';
56const char quote =
'"';
58static auto const integralFloatsBecomeInts =
false;
63 auto dotPos = s.
find(
'.');
64 if (dotPos == std::string::npos)
68 auto hasDecimals = dotPos != lastNonZero;
71 return lastNonZero + 1;
73 if (integralFloatsBecomeInts || lastNonZero + 2 > s.
size())
76 return lastNonZero + 2;
102 char ch = (ct ==
array) ? openBracket : openBrace;
109 output(boost::beast::string_view
const& bytes)
122 auto data = bytes.data();
123 for (; position < bytes.size(); ++position)
125 auto i = jsonSpecialCharacterEscape.
find(data[position]);
126 if (i != jsonSpecialCharacterEscape.
end())
128 if (writtenUntil < position)
130 output_({data + writtenUntil, position - writtenUntil});
132 output_({i->second, jsonEscapeLength});
133 writtenUntil = position + 1;
136 if (writtenUntil < position)
137 output_({data + writtenUntil, position - writtenUntil});
159 ((type ==
array ?
"array: " :
"object: ") + message));
173 check(tags.find(tag) == tags.end(),
"Already seen tag " + tag);
193 auto ch = isArray ? closeBracket : closeBrace;
253 impl_ = std::move(w.impl_);
259 impl_ = std::move(w.impl_);
266 impl_->stringOutput(s);
272 impl_->stringOutput(s);
278 impl_->markStarted();
286 impl_->output({s.
data(), lengthWithoutTrailingZeros(s)});
293 impl_->output({s.
data(), lengthWithoutTrailingZeros(s)});
299 impl_->output(
"null");
305 impl_->output(b ?
"true" :
"false");
332 impl_->nextCollectionEntry(
object,
"set");
333 impl_->writeObjectTag(tag);
345 impl_->nextCollectionEntry(
array,
"startAppend");
352 impl_->nextCollectionEntry(
object,
"startSet");
353 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?