20 #include <ripple/json/Output.h>
21 #include <ripple/json/Writer.h>
39 static size_t const jsonEscapeLength = 2;
42 const char closeBrace =
'}';
43 const char closeBracket =
']';
44 const char colon =
':';
45 const char comma =
',';
46 const char openBrace =
'{';
47 const char openBracket =
'[';
48 const char quote =
'"';
52 static auto const integralFloatsBecomeInts =
false;
57 auto dotPos = s.
find(
'.');
58 if (dotPos == std::string::npos)
62 auto hasDecimals = dotPos != lastNonZero;
65 return lastNonZero + 1;
67 if (integralFloatsBecomeInts || lastNonZero + 2 > s.
size())
70 return lastNonZero + 2;
96 char ch = (ct ==
array) ? openBracket : openBrace;
103 output(boost::beast::string_view
const& bytes)
116 auto data = bytes.data();
117 for (; position < bytes.size(); ++position)
119 auto i = jsonSpecialCharacterEscape.
find(data[position]);
120 if (i != jsonSpecialCharacterEscape.
end())
122 if (writtenUntil < position)
124 output_({data + writtenUntil, position - writtenUntil});
126 output_({i->second, jsonEscapeLength});
127 writtenUntil = position + 1;
130 if (writtenUntil < position)
131 output_({data + writtenUntil, position - writtenUntil});
153 ((type ==
array ?
"array: " :
"object: ") + message));
167 check(tags.find(tag) == tags.end(),
"Already seen tag " + tag);
187 auto ch = isArray ? closeBracket : closeBrace;
247 impl_ = std::move(w.impl_);
253 impl_ = std::move(w.impl_);
260 impl_->stringOutput(s);
266 impl_->stringOutput(s);
272 impl_->markStarted();
280 impl_->output({s.
data(), lengthWithoutTrailingZeros(s)});
287 impl_->output({s.
data(), lengthWithoutTrailingZeros(s)});
292 impl_->output(
"null");
298 impl_->output(b ?
"true" :
"false");
325 impl_->nextCollectionEntry(
object,
"set");
326 impl_->writeObjectTag(tag);
338 impl_->nextCollectionEntry(
array,
"startAppend");
345 impl_->nextCollectionEntry(
object,
"startSet");
346 impl_->writeObjectTag(key);
void nextCollectionEntry(CollectionType type, std::string const &message)
void rawAppend()
Add a comma before this next item if not the first item in an array.
void implOutput(std::string const &)
Output const & getOutput() const
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...
T find_last_not_of(T... args)
Impl(Output const &output)
void finish()
Finish the collection most recently started.
Impl & operator=(Impl &&)=delete
void writeObjectTag(std::string const &tag)
void check(bool condition, std::string const &message)
void startAppend(CollectionType)
Start a new collection inside an array.
void startRoot(CollectionType)
Start a new collection at the root level.
Writer::CollectionType type
What type of collection are we in?
void finishAll()
Finish all objects and arrays.
void outputJson(Json::Value const &value, Output const &out)
Writes a minimal representation of a Json value to an Output in O(n) time.
JSON (JavaScript Object Notation).
std::unique_ptr< Impl > impl_
void start(CollectionType ct)
void startSet(CollectionType, std::string const &key)
Start a new collection inside an object.
Writer & operator=(Writer &&) noexcept
void rawSet(std::string const &key)
Emit just "tag": as part of an object.
Writer(Output const &output)
void output(std::string const &)
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
void output(boost::beast::string_view const &bytes)
void stringOutput(boost::beast::string_view const &bytes)
Writer implements an O(1)-space, O(1)-granular output JSON writer.