20 #include <ripple/json/Output.h>
21 #include <ripple/json/Writer.h>
40 static size_t const jsonEscapeLength = 2;
43 const char closeBrace =
'}';
44 const char closeBracket =
']';
45 const char colon =
':';
46 const char comma =
',';
47 const char openBrace =
'{';
48 const char openBracket =
'[';
49 const char quote =
'"';
53 static auto const integralFloatsBecomeInts =
false;
55 size_t lengthWithoutTrailingZeros (
std::string const& s)
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;
89 char ch = (ct ==
array) ? openBracket : openBrace;
95 void output (boost::beast::string_view
const& bytes)
107 auto data = bytes.data();
108 for (; position < bytes.size(); ++position)
110 auto i = jsonSpecialCharacterEscape.
find (data[position]);
111 if (i != jsonSpecialCharacterEscape.
end ())
113 if (writtenUntil < position)
115 output_ ({data + writtenUntil, position - writtenUntil});
117 output_ ({i->second, jsonEscapeLength});
118 writtenUntil = position + 1;
121 if (writtenUntil < position)
122 output_ ({data + writtenUntil, position - writtenUntil});
139 check (
false,
"Not an " +
140 ((type ==
array ?
"array: " :
"object: ") + message));
153 check (tags.find (tag) == tags.end (),
"Already seen tag " + tag);
171 auto ch = isArray ? closeBracket : closeBrace;
215 : impl_(
std::make_unique <
Impl> (output))
227 impl_ = std::move (w.impl_);
232 impl_ = std::move (w.impl_);
238 impl_->stringOutput (s);
243 impl_->stringOutput (s);
248 impl_->markStarted();
255 impl_->output ({s.
data (), lengthWithoutTrailingZeros (s)});
261 impl_->output ({s.
data (), lengthWithoutTrailingZeros (s)});
266 impl_->output (
"null");
271 impl_->output (b ?
"true" :
"false");
294 impl_->nextCollectionEntry (
object,
"set");
295 impl_->writeObjectTag (tag);
305 impl_->nextCollectionEntry (
array,
"startAppend");
311 impl_->nextCollectionEntry (
object,
"startSet");
312 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.
std::string to_string(ListDisposition disposition)
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 &)
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.