6 #if !defined(JSON_IS_AMALGAMATION) 9 #endif // if !defined(JSON_IS_AMALGAMATION) 18 #if __cplusplus >= 201103L 23 #define isnan std::isnan 26 #if !defined(isfinite) 27 #define isfinite std::isfinite 40 #if !defined(isfinite) 42 #define isfinite _finite 45 #if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) 46 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 47 #endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 51 #if defined(__sun) && defined(__SVR4) // Solaris 52 #if !defined(isfinite) 54 #define isfinite finite 59 #if !defined(isfinite) 60 #if defined(__ia64) && !defined(finite) 62 ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x))) 69 #define isnan(x) (x != x) 72 #if !defined(__APPLE__) 73 #if !defined(isfinite) 74 #define isfinite finite 81 #pragma warning(disable : 4996) 86 #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) 94 char* current = buffer +
sizeof(buffer);
98 }
else if (value < 0) {
104 assert(current >= buffer);
110 char* current = buffer +
sizeof(buffer);
112 assert(current >= buffer);
116 #if defined(JSON_HAS_INT64) 122 #endif // # if defined(JSON_HAS_INT64) 126 bool useSpecialFloats,
127 unsigned int precision,
133 static const char*
const reps[2][3] = {{
"NaN",
"-Infinity",
"Infinity"},
134 {
"null",
"-1e+9999",
"1e+9999"}};
135 return reps[useSpecialFloats ? 0 : 1]
136 [
isnan(value) ? 0 : (value < 0) ? 1 : 2];
139 String buffer(
size_t(36),
'\0');
142 &*buffer.begin(), buffer.size(),
146 auto wouldPrint =
static_cast<size_t>(len);
147 if (wouldPrint >= buffer.size()) {
148 buffer.resize(wouldPrint + 1);
151 buffer.resize(wouldPrint);
164 if (buffer.find(
'.') == buffer.npos && buffer.find(
'e') == buffer.npos) {
172 unsigned int precision,
174 return valueToString(value,
false, precision, precisionType);
182 char const*
const end = s + n;
183 for (
char const* cur = s; cur < end; ++cur) {
184 if (*cur ==
'\\' || *cur ==
'\"' || *cur <
' ' ||
185 static_cast<unsigned char>(*cur) < 0x80)
192 const unsigned int REPLACEMENT_CHARACTER = 0xFFFD;
194 unsigned int firstByte =
static_cast<unsigned char>(*s);
196 if (firstByte < 0x80)
199 if (firstByte < 0xE0) {
201 return REPLACEMENT_CHARACTER;
203 unsigned int calculated =
204 ((firstByte & 0x1F) << 6) | (
static_cast<unsigned int>(s[1]) & 0x3F);
207 return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated;
210 if (firstByte < 0xF0) {
212 return REPLACEMENT_CHARACTER;
214 unsigned int calculated = ((firstByte & 0x0F) << 12) |
215 ((
static_cast<unsigned int>(s[1]) & 0x3F) << 6) |
216 (static_cast<unsigned int>(s[2]) & 0x3F);
220 if (calculated >= 0xD800 && calculated <= 0xDFFF)
221 return REPLACEMENT_CHARACTER;
223 return calculated < 0x800 ? REPLACEMENT_CHARACTER : calculated;
226 if (firstByte < 0xF8) {
228 return REPLACEMENT_CHARACTER;
230 unsigned int calculated = ((firstByte & 0x07) << 18) |
231 ((
static_cast<unsigned int>(s[1]) & 0x3F) << 12) |
232 ((static_cast<unsigned int>(s[2]) & 0x3F) << 6) |
233 (
static_cast<unsigned int>(s[3]) & 0x3F);
236 return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated;
239 return REPLACEMENT_CHARACTER;
242 static const char hex2[] =
"000102030405060708090a0b0c0d0e0f" 243 "101112131415161718191a1b1c1d1e1f" 244 "202122232425262728292a2b2c2d2e2f" 245 "303132333435363738393a3b3c3d3e3f" 246 "404142434445464748494a4b4c4d4e4f" 247 "505152535455565758595a5b5c5d5e5f" 248 "606162636465666768696a6b6c6d6e6f" 249 "707172737475767778797a7b7c7d7e7f" 250 "808182838485868788898a8b8c8d8e8f" 251 "909192939495969798999a9b9c9d9e9f" 252 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" 253 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" 254 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" 255 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" 256 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" 257 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
260 const unsigned int hi = (x >> 8) & 0xff;
261 const unsigned int lo = x & 0xff;
263 result[0] =
hex2[2 * hi];
264 result[1] =
hex2[2 * hi + 1];
265 result[2] =
hex2[2 * lo];
266 result[3] =
hex2[2 * lo + 1];
271 if (value ==
nullptr)
275 return String(
"\"") + value +
"\"";
279 String::size_type maxsize = length * 2 + 3;
281 result.reserve(maxsize);
283 char const* end = value + length;
284 for (
const char* c = value; c != end; ++c) {
319 if (cp < 0x80 && cp >= 0x20)
320 result +=
static_cast<char>(cp);
321 else if (cp < 0x10000) {
345 Writer::~Writer() =
default;
350 FastWriter::FastWriter()
354 void FastWriter::enableYAMLCompatibility() { yamlCompatibilityEnabled_ =
true; }
356 void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ =
true; }
358 void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ =
true; }
360 String FastWriter::write(
const Value& root) {
363 if (!omitEndingLineFeed_)
368 void FastWriter::writeValue(
const Value& value) {
369 switch (value.type()) {
371 if (!dropNullPlaceholders_)
387 bool ok = value.getString(&str, &end);
398 for (
ArrayIndex index = 0; index < size; ++index) {
401 writeValue(value[index]);
408 for (
auto it = members.begin(); it != members.end(); ++it) {
410 if (it != members.begin())
413 static_cast<unsigned>(name.length()));
414 document_ += yamlCompatibilityEnabled_ ?
": " :
":";
415 writeValue(value[name]);
425 StyledWriter::StyledWriter() =
default;
427 String StyledWriter::write(
const Value& root) {
429 addChildValues_ =
false;
430 indentString_.clear();
431 writeCommentBeforeValue(root);
433 writeCommentAfterValueOnSameLine(root);
438 void StyledWriter::writeValue(
const Value& value) {
439 switch (value.type()) {
456 bool ok = value.getString(&str, &end);
467 writeArrayValue(value);
474 writeWithIndent(
"{");
476 auto it = members.begin();
479 const Value& childValue = value[name];
480 writeCommentBeforeValue(childValue);
483 writeValue(childValue);
484 if (++it == members.end()) {
485 writeCommentAfterValueOnSameLine(childValue);
489 writeCommentAfterValueOnSameLine(childValue);
492 writeWithIndent(
"}");
498 void StyledWriter::writeArrayValue(
const Value& value) {
499 unsigned size = value.size();
503 bool isArrayMultiLine = isMultilineArray(value);
504 if (isArrayMultiLine) {
505 writeWithIndent(
"[");
507 bool hasChildValue = !childValues_.empty();
510 const Value& childValue = value[index];
511 writeCommentBeforeValue(childValue);
513 writeWithIndent(childValues_[index]);
516 writeValue(childValue);
518 if (++index == size) {
519 writeCommentAfterValueOnSameLine(childValue);
523 writeCommentAfterValueOnSameLine(childValue);
526 writeWithIndent(
"]");
529 assert(childValues_.size() == size);
531 for (
unsigned index = 0; index < size; ++index) {
534 document_ += childValues_[index];
541 bool StyledWriter::isMultilineArray(
const Value& value) {
543 bool isMultiLine = size * 3 >= rightMargin_;
544 childValues_.clear();
545 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
546 const Value& childValue = value[index];
547 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
548 !childValue.empty());
552 childValues_.reserve(size);
553 addChildValues_ =
true;
555 for (
ArrayIndex index = 0; index < size; ++index) {
556 if (hasCommentForValue(value[index])) {
559 writeValue(value[index]);
560 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
562 addChildValues_ =
false;
563 isMultiLine = isMultiLine || lineLength >= rightMargin_;
568 void StyledWriter::pushValue(
const String& value) {
570 childValues_.push_back(value);
575 void StyledWriter::writeIndent() {
576 if (!document_.empty()) {
577 char last = document_[document_.length() - 1];
583 document_ += indentString_;
586 void StyledWriter::writeWithIndent(
const String& value) {
591 void StyledWriter::indent() { indentString_ +=
String(indentSize_,
' '); }
593 void StyledWriter::unindent() {
594 assert(indentString_.size() >= indentSize_);
595 indentString_.resize(indentString_.size() - indentSize_);
598 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
605 String::const_iterator iter = comment.begin();
606 while (iter != comment.end()) {
608 if (*iter ==
'\n' && ((iter + 1) != comment.end() && *(iter + 1) ==
'/'))
617 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
628 bool StyledWriter::hasCommentForValue(
const Value& value) {
637 StyledStreamWriter::StyledStreamWriter(
String indentation)
638 : document_(nullptr), indentation_(
std::move(indentation)),
639 addChildValues_(), indented_(false) {}
641 void StyledStreamWriter::write(
OStream& out,
const Value& root) {
643 addChildValues_ =
false;
644 indentString_.clear();
646 writeCommentBeforeValue(root);
651 writeCommentAfterValueOnSameLine(root);
656 void StyledStreamWriter::writeValue(
const Value& value) {
657 switch (value.type()) {
674 bool ok = value.getString(&str, &end);
685 writeArrayValue(value);
688 Value::Members members(value.getMemberNames());
692 writeWithIndent(
"{");
694 auto it = members.begin();
697 const Value& childValue = value[name];
698 writeCommentBeforeValue(childValue);
701 writeValue(childValue);
702 if (++it == members.end()) {
703 writeCommentAfterValueOnSameLine(childValue);
707 writeCommentAfterValueOnSameLine(childValue);
710 writeWithIndent(
"}");
716 void StyledStreamWriter::writeArrayValue(
const Value& value) {
717 unsigned size = value.size();
721 bool isArrayMultiLine = isMultilineArray(value);
722 if (isArrayMultiLine) {
723 writeWithIndent(
"[");
725 bool hasChildValue = !childValues_.empty();
728 const Value& childValue = value[index];
729 writeCommentBeforeValue(childValue);
731 writeWithIndent(childValues_[index]);
736 writeValue(childValue);
739 if (++index == size) {
740 writeCommentAfterValueOnSameLine(childValue);
744 writeCommentAfterValueOnSameLine(childValue);
747 writeWithIndent(
"]");
750 assert(childValues_.size() == size);
752 for (
unsigned index = 0; index < size; ++index) {
755 *document_ << childValues_[index];
762 bool StyledStreamWriter::isMultilineArray(
const Value& value) {
764 bool isMultiLine = size * 3 >= rightMargin_;
765 childValues_.clear();
766 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
767 const Value& childValue = value[index];
768 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
769 !childValue.empty());
773 childValues_.reserve(size);
774 addChildValues_ =
true;
776 for (
ArrayIndex index = 0; index < size; ++index) {
777 if (hasCommentForValue(value[index])) {
780 writeValue(value[index]);
781 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
783 addChildValues_ =
false;
784 isMultiLine = isMultiLine || lineLength >= rightMargin_;
789 void StyledStreamWriter::pushValue(
const String& value) {
791 childValues_.push_back(value);
796 void StyledStreamWriter::writeIndent() {
801 *document_ <<
'\n' << indentString_;
804 void StyledStreamWriter::writeWithIndent(
const String& value) {
811 void StyledStreamWriter::indent() { indentString_ += indentation_; }
813 void StyledStreamWriter::unindent() {
814 assert(indentString_.size() >= indentation_.size());
815 indentString_.resize(indentString_.size() - indentation_.size());
818 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
825 String::const_iterator iter = comment.begin();
826 while (iter != comment.end()) {
828 if (*iter ==
'\n' && ((iter + 1) != comment.end() && *(iter + 1) ==
'/'))
830 *document_ << indentString_;
836 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
847 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
857 struct CommentStyle {
866 struct BuiltStyledStreamWriter :
public StreamWriter {
867 BuiltStyledStreamWriter(
String indentation,
868 CommentStyle::Enum cs,
871 String endingLineFeedSymbol,
872 bool useSpecialFloats,
873 unsigned int precision,
875 int write(Value
const& root,
OStream* sout)
override;
878 void writeValue(Value
const& value);
879 void writeArrayValue(Value
const& value);
880 bool isMultilineArray(Value
const& value);
881 void pushValue(
String const& value);
883 void writeWithIndent(
String const& value);
886 void writeCommentBeforeValue(Value
const& root);
887 void writeCommentAfterValueOnSameLine(Value
const& root);
888 static bool hasCommentForValue(
const Value& value);
890 typedef std::vector<String> ChildValues;
892 ChildValues childValues_;
894 unsigned int rightMargin_;
896 CommentStyle::Enum cs_;
899 String endingLineFeedSymbol_;
900 bool addChildValues_ : 1;
902 bool useSpecialFloats_ : 1;
903 unsigned int precision_;
906 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
String indentation,
907 CommentStyle::Enum cs,
910 String endingLineFeedSymbol,
911 bool useSpecialFloats,
912 unsigned int precision,
914 : rightMargin_(74), indentation_(
std::move(indentation)), cs_(cs),
915 colonSymbol_(
std::move(colonSymbol)), nullSymbol_(
std::move(nullSymbol)),
916 endingLineFeedSymbol_(
std::move(endingLineFeedSymbol)),
917 addChildValues_(false), indented_(false),
918 useSpecialFloats_(useSpecialFloats), precision_(precision),
919 precisionType_(precisionType) {}
920 int BuiltStyledStreamWriter::write(Value
const& root,
OStream* sout) {
922 addChildValues_ =
false;
924 indentString_.clear();
925 writeCommentBeforeValue(root);
930 writeCommentAfterValueOnSameLine(root);
931 *sout_ << endingLineFeedSymbol_;
935 void BuiltStyledStreamWriter::writeValue(Value
const& value) {
936 switch (value.type()) {
938 pushValue(nullSymbol_);
947 pushValue(
valueToString(value.asDouble(), useSpecialFloats_, precision_,
954 bool ok = value.getString(&str, &end);
965 writeArrayValue(value);
968 Value::Members members(value.getMemberNames());
972 writeWithIndent(
"{");
974 auto it = members.begin();
977 Value
const& childValue = value[name];
978 writeCommentBeforeValue(childValue);
980 name.data(),
static_cast<unsigned>(name.length())));
981 *sout_ << colonSymbol_;
982 writeValue(childValue);
983 if (++it == members.end()) {
984 writeCommentAfterValueOnSameLine(childValue);
988 writeCommentAfterValueOnSameLine(childValue);
991 writeWithIndent(
"}");
997 void BuiltStyledStreamWriter::writeArrayValue(Value
const& value) {
998 unsigned size = value.size();
1002 bool isMultiLine = (cs_ == CommentStyle::All) || isMultilineArray(value);
1004 writeWithIndent(
"[");
1006 bool hasChildValue = !childValues_.empty();
1009 Value
const& childValue = value[index];
1010 writeCommentBeforeValue(childValue);
1012 writeWithIndent(childValues_[index]);
1017 writeValue(childValue);
1020 if (++index == size) {
1021 writeCommentAfterValueOnSameLine(childValue);
1025 writeCommentAfterValueOnSameLine(childValue);
1028 writeWithIndent(
"]");
1031 assert(childValues_.size() == size);
1033 if (!indentation_.empty())
1035 for (
unsigned index = 0; index < size; ++index) {
1037 *sout_ << ((!indentation_.empty()) ?
", " :
",");
1038 *sout_ << childValues_[index];
1040 if (!indentation_.empty())
1047 bool BuiltStyledStreamWriter::isMultilineArray(Value
const& value) {
1049 bool isMultiLine = size * 3 >= rightMargin_;
1050 childValues_.clear();
1051 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
1052 Value
const& childValue = value[index];
1053 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
1054 !childValue.empty());
1058 childValues_.reserve(size);
1059 addChildValues_ =
true;
1061 for (
ArrayIndex index = 0; index < size; ++index) {
1062 if (hasCommentForValue(value[index])) {
1065 writeValue(value[index]);
1066 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
1068 addChildValues_ =
false;
1069 isMultiLine = isMultiLine || lineLength >= rightMargin_;
1074 void BuiltStyledStreamWriter::pushValue(
String const& value) {
1075 if (addChildValues_)
1076 childValues_.push_back(value);
1081 void BuiltStyledStreamWriter::writeIndent() {
1087 if (!indentation_.empty()) {
1089 *sout_ <<
'\n' << indentString_;
1093 void BuiltStyledStreamWriter::writeWithIndent(
String const& value) {
1100 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1102 void BuiltStyledStreamWriter::unindent() {
1103 assert(indentString_.size() >= indentation_.size());
1104 indentString_.resize(indentString_.size() - indentation_.size());
1107 void BuiltStyledStreamWriter::writeCommentBeforeValue(Value
const& root) {
1108 if (cs_ == CommentStyle::None)
1116 String::const_iterator iter = comment.begin();
1117 while (iter != comment.end()) {
1119 if (*iter ==
'\n' && ((iter + 1) != comment.end() && *(iter + 1) ==
'/'))
1121 *sout_ << indentString_;
1127 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(
1128 Value
const& root) {
1129 if (cs_ == CommentStyle::None)
1141 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1150 StreamWriter::StreamWriter() : sout_(nullptr) {}
1163 CommentStyle::Enum cs = CommentStyle::All;
1164 if (cs_str ==
"All") {
1165 cs = CommentStyle::All;
1166 }
else if (cs_str ==
"None") {
1167 cs = CommentStyle::None;
1169 throwRuntimeError(
"commentStyle must be 'All' or 'None'");
1172 if (pt_str ==
"significant") {
1174 }
else if (pt_str ==
"decimal") {
1177 throwRuntimeError(
"precisionType must be 'significant' or 'decimal'");
1179 String colonSymbol =
" : ";
1182 }
else if (indentation.empty()) {
1185 String nullSymbol =
"null";
1191 String endingLineFeedSymbol;
1192 return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol,
1193 endingLineFeedSymbol, usf, pre,
1197 valid_keys->clear();
1198 valid_keys->insert(
"indentation");
1199 valid_keys->insert(
"commentStyle");
1200 valid_keys->insert(
"enableYAMLCompatibility");
1201 valid_keys->insert(
"dropNullPlaceholders");
1202 valid_keys->insert(
"useSpecialFloats");
1203 valid_keys->insert(
"precision");
1204 valid_keys->insert(
"precisionType");
1209 invalid = &my_invalid;
1211 std::set<String> valid_keys;
1214 size_t n = keys.size();
1215 for (
size_t i = 0; i < n; ++i) {
1216 String const& key = keys[i];
1217 if (valid_keys.find(key) == valid_keys.end()) {
1229 (*settings)[
"commentStyle"] =
"All";
1230 (*settings)[
"indentation"] =
"\t";
1231 (*settings)[
"enableYAMLCompatibility"] =
false;
1232 (*settings)[
"dropNullPlaceholders"] =
false;
1233 (*settings)[
"useSpecialFloats"] =
false;
1234 (*settings)[
"precision"] = 17;
1235 (*settings)[
"precisionType"] =
"significant";
1242 writer->write(root, &sout);
1249 writer->write(root, &sout);
A simple abstract factory.
std::vector< String > Members
bool validate(Json::Value *invalid) const
static void uintToString(LargestUInt value, char *¤t)
Converts an unsigned integer to string.
static void setDefaults(Json::Value *settings)
Called by ctor, but you can use this to reset settings_.
PrecisionType
Type of precision for formatting of real values.
Iter fixZerosInTheEnd(Iter begin, Iter end)
Return iterator that would be the new end of the range [begin,end), if we were to delete zeros in the...
array value (ordered list)
String valueToString(Int value)
bool empty() const
Return true if empty array, empty object, or null; otherwise, false.
Members getMemberNames() const
Return a list of the member names.
object value (collection of name/value pairs).
StreamWriter * newStreamWriter() const override
char UIntToStringBuffer[uintToStringBufferSize]
Iter fixNumericLocale(Iter begin, Iter end)
Change ',' to '.
static const LargestInt minLargestInt
Minimum signed integer value that can be stored in a Json::Value.
static void getValidWriterKeys(std::set< String > *valid_keys)
std::basic_ostringstream< String::value_type, String::traits_type, String::allocator_type > OStringStream
String writeString(StreamWriter::Factory const &factory, Value const &root)
Write into stringstream, then return string, for convenience.
~StreamWriterBuilder() override
String asString() const
Embedded zeroes are possible.
JSON (JavaScript Object Notation).
Value & operator[](const String &key)
A simple way to update a specific setting.
we set max number of digits after "." in string
static bool isAnyCharRequiredQuoting(char const *s, size_t n)
std::auto_ptr< StreamWriter > StreamWriterPtr
static unsigned int utf8ToCodepoint(const char *&s, const char *e)
Json::Value settings_
Configuration of this builder.
static String valueToQuotedStringN(const char *value, unsigned length)
a comment on the line after a value (only make sense for
String valueToQuotedString(const char *value)
we set max number of significant digits in string
static String toHex16Bit(unsigned int x)
a comment placed on the line before a value
a comment just after a value on the same line
Build a StreamWriter implementation.
std::basic_string< char, std::char_traits< char >, Allocator< char > > String
OStream & operator<<(OStream &, const Value &root)
Output using the StyledStreamWriter.
virtual StreamWriter * newStreamWriter() const =0
Allocate a CharReader via operator new().
static const LargestInt maxLargestInt
Maximum signed integer value that can be stored in a Json::Value.