1#include <xrpl/basics/ToString.h>
2#include <xrpl/json/Output.h>
3#include <xrpl/json/Writer.h>
28static size_t const jsonEscapeLength = 2;
31char const closeBrace =
'}';
32char const closeBracket =
']';
33char const colon =
':';
34char const comma =
',';
35char const openBrace =
'{';
36char const openBracket =
'[';
37char const quote =
'"';
39static auto const integralFloatsBecomeInts =
false;
44 auto dotPos = s.
find(
'.');
45 if (dotPos == std::string::npos)
49 auto hasDecimals = dotPos != lastNonZero;
52 return lastNonZero + 1;
54 if (integralFloatsBecomeInts || lastNonZero + 2 > s.
size())
57 return lastNonZero + 2;
83 char ch = (ct ==
array) ? openBracket : openBrace;
90 output(boost::beast::string_view
const& bytes)
103 auto data = bytes.data();
104 for (; position < bytes.size(); ++position)
106 auto i = jsonSpecialCharacterEscape.
find(data[position]);
107 if (i != jsonSpecialCharacterEscape.
end())
109 if (writtenUntil < position)
111 output_({data + writtenUntil, position - writtenUntil});
113 output_({i->second, jsonEscapeLength});
114 writtenUntil = position + 1;
117 if (writtenUntil < position)
118 output_({data + writtenUntil, position - writtenUntil});
140 ((type ==
array ?
"array: " :
"object: ") + message));
154 check(tags.find(tag) == tags.end(),
"Already seen tag " + tag);
174 auto ch = isArray ? closeBracket : closeBrace;
234 impl_ = std::move(w.impl_);
240 impl_ = std::move(w.impl_);
247 impl_->stringOutput(s);
253 impl_->stringOutput(s);
259 impl_->markStarted();
267 impl_->output({s.
data(), lengthWithoutTrailingZeros(s)});
274 impl_->output({s.
data(), lengthWithoutTrailingZeros(s)});
280 impl_->output(
"null");
286 impl_->output(b ?
"true" :
"false");
313 impl_->nextCollectionEntry(
object,
"set");
314 impl_->writeObjectTag(tag);
326 impl_->nextCollectionEntry(
array,
"startAppend");
333 impl_->nextCollectionEntry(
object,
"startSet");
334 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?