6 #if !defined(JSON_IS_AMALGAMATION) 9 #endif // if !defined(JSON_IS_AMALGAMATION) 19 #if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0 21 #define isfinite _finite 22 #elif defined(__sun) && defined(__SVR4) //Solaris 23 #if !defined(isfinite) 25 #define isfinite finite 28 #if !defined(isfinite) 30 #define isfinite finite 33 #if !defined(isfinite) 34 #if defined(__ia64) && !defined(finite) 35 #define isfinite(x) ((sizeof(x) == sizeof(float) ? \ 36 _Isfinitef(x) : _IsFinite(x))) 39 #define isfinite finite 44 #if !(defined(__QNXNTO__)) // QNX already defines isfinite 45 #define isfinite std::isfinite 50 #if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above 51 #define snprintf sprintf_s 52 #elif _MSC_VER >= 1900 // VC++ 14.0 and above 53 #define snprintf std::snprintf 55 #define snprintf _snprintf 57 #elif defined(__ANDROID__) || defined(__QNXNTO__) 58 #define snprintf snprintf 59 #elif __cplusplus >= 201103L 60 #if !defined(__MINGW32__) && !defined(__CYGWIN__) 61 #define snprintf std::snprintf 65 #if defined(__BORLANDC__) 67 #define isfinite _finite 68 #define snprintf _snprintf 71 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 73 #pragma warning(disable : 4996) 78 #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) 86 char* current = buffer +
sizeof(buffer);
90 }
else if (value < 0) {
96 assert(current >= buffer);
102 char* current = buffer +
sizeof(buffer);
104 assert(current >= buffer);
108 #if defined(JSON_HAS_INT64) 118 #endif // # if defined(JSON_HAS_INT64) 127 char formatString[15];
128 snprintf(formatString,
sizeof(formatString),
"%%.%ug", precision);
134 len =
snprintf(buffer,
sizeof(buffer), formatString, value);
138 if (!strchr(buffer,
'.') && !strchr(buffer,
'e')) {
139 strcat(buffer,
".0");
144 if (value != value) {
145 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"NaN" :
"null");
146 }
else if (value < 0) {
147 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"-Infinity" :
"-1e+9999");
149 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"Infinity" :
"1e+9999");
164 char const*
const end = s + n;
165 for (
char const* cur = s; cur < end; ++cur) {
166 if (*cur ==
'\\' || *cur ==
'\"' || *cur <
' ' 167 || static_cast<unsigned char>(*cur) < 0x80)
174 const unsigned int REPLACEMENT_CHARACTER = 0xFFFD;
176 unsigned int firstByte =
static_cast<unsigned char>(*s);
178 if (firstByte < 0x80)
181 if (firstByte < 0xE0) {
183 return REPLACEMENT_CHARACTER;
185 unsigned int calculated = ((firstByte & 0x1F) << 6)
186 | (
static_cast<unsigned int>(s[1]) & 0x3F);
189 return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated;
192 if (firstByte < 0xF0) {
194 return REPLACEMENT_CHARACTER;
196 unsigned int calculated = ((firstByte & 0x0F) << 12)
197 | ((
static_cast<unsigned int>(s[1]) & 0x3F) << 6)
198 | (static_cast<unsigned int>(s[2]) & 0x3F);
202 if (calculated >= 0xD800 && calculated <= 0xDFFF)
203 return REPLACEMENT_CHARACTER;
205 return calculated < 0x800 ? REPLACEMENT_CHARACTER : calculated;
208 if (firstByte < 0xF8) {
210 return REPLACEMENT_CHARACTER;
212 unsigned int calculated = ((firstByte & 0x07) << 24)
213 | ((
static_cast<unsigned int>(s[1]) & 0x3F) << 12)
214 | ((static_cast<unsigned int>(s[2]) & 0x3F) << 6)
215 | (
static_cast<unsigned int>(s[3]) & 0x3F);
218 return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated;
221 return REPLACEMENT_CHARACTER;
225 "000102030405060708090a0b0c0d0e0f" 226 "101112131415161718191a1b1c1d1e1f" 227 "202122232425262728292a2b2c2d2e2f" 228 "303132333435363738393a3b3c3d3e3f" 229 "404142434445464748494a4b4c4d4e4f" 230 "505152535455565758595a5b5c5d5e5f" 231 "606162636465666768696a6b6c6d6e6f" 232 "707172737475767778797a7b7c7d7e7f" 233 "808182838485868788898a8b8c8d8e8f" 234 "909192939495969798999a9b9c9d9e9f" 235 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" 236 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" 237 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" 238 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" 239 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" 240 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
243 const unsigned int hi = (x >> 8) & 0xff;
244 const unsigned int lo = x & 0xff;
246 result[0] =
hex2[2 * hi];
247 result[1] =
hex2[2 * hi + 1];
248 result[2] =
hex2[2 * lo];
249 result[3] =
hex2[2 * lo + 1];
262 JSONCPP_STRING::size_type maxsize =
265 result.reserve(maxsize);
267 char const* end = value + length;
268 for (
const char* c = value; c != end; ++c) {
303 if (cp < 0x80 && cp >= 0x20)
304 result +=
static_cast<char>(cp);
305 else if (cp < 0x10000) {
337 : yamlCompatibilityEnabled_(false), dropNullPlaceholders_(false),
338 omitEndingLineFeed_(false) {}
349 if (!omitEndingLineFeed_)
354 void FastWriter::writeValue(
const Value& value) {
355 switch (value.
type()) {
357 if (!dropNullPlaceholders_)
384 for (
ArrayIndex index = 0; index < size; ++index) {
387 writeValue(value[index]);
394 for (Value::Members::iterator it = members.begin(); it != members.end();
397 if (it != members.begin())
400 document_ += yamlCompatibilityEnabled_ ?
": " :
":";
401 writeValue(value[name]);
412 : rightMargin_(74), indentSize_(3), addChildValues_() {}
416 addChildValues_ =
false;
417 indentString_.clear();
418 writeCommentBeforeValue(root);
420 writeCommentAfterValueOnSameLine(root);
425 void StyledWriter::writeValue(
const Value& value) {
426 switch (value.
type()) {
453 writeArrayValue(value);
460 writeWithIndent(
"{");
462 Value::Members::iterator it = members.begin();
465 const Value& childValue = value[name];
466 writeCommentBeforeValue(childValue);
469 writeValue(childValue);
470 if (++it == members.end()) {
471 writeCommentAfterValueOnSameLine(childValue);
475 writeCommentAfterValueOnSameLine(childValue);
478 writeWithIndent(
"}");
484 void StyledWriter::writeArrayValue(
const Value& value) {
485 unsigned size = value.size();
489 bool isArrayMultiLine = isMultilineArray(value);
490 if (isArrayMultiLine) {
491 writeWithIndent(
"[");
493 bool hasChildValue = !childValues_.empty();
496 const Value& childValue = value[index];
497 writeCommentBeforeValue(childValue);
499 writeWithIndent(childValues_[index]);
502 writeValue(childValue);
504 if (++index == size) {
505 writeCommentAfterValueOnSameLine(childValue);
509 writeCommentAfterValueOnSameLine(childValue);
512 writeWithIndent(
"]");
515 assert(childValues_.size() == size);
517 for (
unsigned index = 0; index < size; ++index) {
520 document_ += childValues_[index];
527 bool StyledWriter::isMultilineArray(
const Value& value) {
529 bool isMultiLine = size * 3 >= rightMargin_;
530 childValues_.clear();
531 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
532 const Value& childValue = value[index];
533 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
534 childValue.size() > 0);
538 childValues_.reserve(size);
539 addChildValues_ =
true;
541 for (
ArrayIndex index = 0; index < size; ++index) {
542 if (hasCommentForValue(value[index])) {
545 writeValue(value[index]);
546 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
548 addChildValues_ =
false;
549 isMultiLine = isMultiLine || lineLength >= rightMargin_;
556 childValues_.push_back(value);
561 void StyledWriter::writeIndent() {
562 if (!document_.empty()) {
563 char last = document_[document_.length() - 1];
569 document_ += indentString_;
577 void StyledWriter::indent() { indentString_ +=
JSONCPP_STRING(indentSize_,
' '); }
579 void StyledWriter::unindent() {
580 assert(indentString_.size() >= indentSize_);
581 indentString_.resize(indentString_.size() - indentSize_);
584 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
591 JSONCPP_STRING::const_iterator iter = comment.begin();
592 while (iter != comment.end()) {
595 ((iter+1) != comment.end() && *(iter + 1) ==
'/'))
604 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
615 bool StyledWriter::hasCommentForValue(
const Value& value) {
625 : document_(NULL), rightMargin_(74), indentation_(indentation),
630 addChildValues_ =
false;
631 indentString_.clear();
633 writeCommentBeforeValue(root);
634 if (!indented_) writeIndent();
637 writeCommentAfterValueOnSameLine(root);
642 void StyledStreamWriter::writeValue(
const Value& value) {
643 switch (value.
type()) {
670 writeArrayValue(value);
677 writeWithIndent(
"{");
679 Value::Members::iterator it = members.begin();
682 const Value& childValue = value[name];
683 writeCommentBeforeValue(childValue);
686 writeValue(childValue);
687 if (++it == members.end()) {
688 writeCommentAfterValueOnSameLine(childValue);
692 writeCommentAfterValueOnSameLine(childValue);
695 writeWithIndent(
"}");
701 void StyledStreamWriter::writeArrayValue(
const Value& value) {
702 unsigned size = value.size();
706 bool isArrayMultiLine = isMultilineArray(value);
707 if (isArrayMultiLine) {
708 writeWithIndent(
"[");
710 bool hasChildValue = !childValues_.empty();
713 const Value& childValue = value[index];
714 writeCommentBeforeValue(childValue);
716 writeWithIndent(childValues_[index]);
718 if (!indented_) writeIndent();
720 writeValue(childValue);
723 if (++index == size) {
724 writeCommentAfterValueOnSameLine(childValue);
728 writeCommentAfterValueOnSameLine(childValue);
731 writeWithIndent(
"]");
734 assert(childValues_.size() == size);
736 for (
unsigned index = 0; index < size; ++index) {
739 *document_ << childValues_[index];
746 bool StyledStreamWriter::isMultilineArray(
const Value& value) {
748 bool isMultiLine = size * 3 >= rightMargin_;
749 childValues_.clear();
750 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
751 const Value& childValue = value[index];
752 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
753 childValue.size() > 0);
757 childValues_.reserve(size);
758 addChildValues_ =
true;
760 for (
ArrayIndex index = 0; index < size; ++index) {
761 if (hasCommentForValue(value[index])) {
764 writeValue(value[index]);
765 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
767 addChildValues_ =
false;
768 isMultiLine = isMultiLine || lineLength >= rightMargin_;
775 childValues_.push_back(value);
780 void StyledStreamWriter::writeIndent() {
785 *document_ <<
'\n' << indentString_;
788 void StyledStreamWriter::writeWithIndent(
const JSONCPP_STRING& value) {
789 if (!indented_) writeIndent();
794 void StyledStreamWriter::indent() { indentString_ += indentation_; }
796 void StyledStreamWriter::unindent() {
797 assert(indentString_.size() >= indentation_.size());
798 indentString_.resize(indentString_.size() - indentation_.size());
801 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
805 if (!indented_) writeIndent();
807 JSONCPP_STRING::const_iterator iter = comment.begin();
808 while (iter != comment.end()) {
811 ((iter+1) != comment.end() && *(iter + 1) ==
'/'))
813 *document_ << indentString_;
819 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
830 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
840 struct CommentStyle {
849 struct BuiltStyledStreamWriter :
public StreamWriter
851 BuiltStyledStreamWriter(
853 CommentStyle::Enum cs,
857 bool useSpecialFloats,
858 unsigned int precision);
861 void writeValue(Value
const& value);
862 void writeArrayValue(Value
const& value);
863 bool isMultilineArray(Value
const& value);
869 void writeCommentBeforeValue(Value
const& root);
870 void writeCommentAfterValueOnSameLine(Value
const& root);
871 static bool hasCommentForValue(
const Value& value);
873 typedef std::vector<JSONCPP_STRING> ChildValues;
875 ChildValues childValues_;
877 unsigned int rightMargin_;
879 CommentStyle::Enum cs_;
883 bool addChildValues_ : 1;
885 bool useSpecialFloats_ : 1;
886 unsigned int precision_;
888 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
890 CommentStyle::Enum cs,
894 bool useSpecialFloats,
895 unsigned int precision)
897 , indentation_(indentation)
899 , colonSymbol_(colonSymbol)
900 , nullSymbol_(nullSymbol)
901 , endingLineFeedSymbol_(endingLineFeedSymbol)
902 , addChildValues_(false)
904 , useSpecialFloats_(useSpecialFloats)
905 , precision_(precision)
908 int BuiltStyledStreamWriter::write(Value
const& root,
JSONCPP_OSTREAM* sout)
911 addChildValues_ =
false;
913 indentString_.clear();
914 writeCommentBeforeValue(root);
915 if (!indented_) writeIndent();
918 writeCommentAfterValueOnSameLine(root);
919 *sout_ << endingLineFeedSymbol_;
923 void BuiltStyledStreamWriter::writeValue(Value
const& value) {
924 switch (value.type()) {
926 pushValue(nullSymbol_);
935 pushValue(
valueToString(value.asDouble(), useSpecialFloats_, precision_));
942 bool ok = value.getString(&str, &end);
951 writeArrayValue(value);
958 writeWithIndent(
"{");
960 Value::Members::iterator it = members.begin();
963 Value
const& childValue = value[name];
964 writeCommentBeforeValue(childValue);
966 *sout_ << colonSymbol_;
967 writeValue(childValue);
968 if (++it == members.end()) {
969 writeCommentAfterValueOnSameLine(childValue);
973 writeCommentAfterValueOnSameLine(childValue);
976 writeWithIndent(
"}");
982 void BuiltStyledStreamWriter::writeArrayValue(Value
const& value) {
983 unsigned size = value.size();
987 bool isMultiLine = (cs_ == CommentStyle::All) || isMultilineArray(value);
989 writeWithIndent(
"[");
991 bool hasChildValue = !childValues_.empty();
994 Value
const& childValue = value[index];
995 writeCommentBeforeValue(childValue);
997 writeWithIndent(childValues_[index]);
999 if (!indented_) writeIndent();
1001 writeValue(childValue);
1004 if (++index == size) {
1005 writeCommentAfterValueOnSameLine(childValue);
1009 writeCommentAfterValueOnSameLine(childValue);
1012 writeWithIndent(
"]");
1015 assert(childValues_.size() == size);
1017 if (!indentation_.empty()) *sout_ <<
" ";
1018 for (
unsigned index = 0; index < size; ++index) {
1020 *sout_ << ((!indentation_.empty()) ?
", " :
",");
1021 *sout_ << childValues_[index];
1023 if (!indentation_.empty()) *sout_ <<
" ";
1029 bool BuiltStyledStreamWriter::isMultilineArray(Value
const& value) {
1031 bool isMultiLine = size * 3 >= rightMargin_;
1032 childValues_.clear();
1033 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
1034 Value
const& childValue = value[index];
1035 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
1036 childValue.size() > 0);
1040 childValues_.reserve(size);
1041 addChildValues_ =
true;
1043 for (
ArrayIndex index = 0; index < size; ++index) {
1044 if (hasCommentForValue(value[index])) {
1047 writeValue(value[index]);
1048 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
1050 addChildValues_ =
false;
1051 isMultiLine = isMultiLine || lineLength >= rightMargin_;
1056 void BuiltStyledStreamWriter::pushValue(
JSONCPP_STRING const& value) {
1057 if (addChildValues_)
1058 childValues_.push_back(value);
1063 void BuiltStyledStreamWriter::writeIndent() {
1069 if (!indentation_.empty()) {
1071 *sout_ <<
'\n' << indentString_;
1075 void BuiltStyledStreamWriter::writeWithIndent(
JSONCPP_STRING const& value) {
1076 if (!indented_) writeIndent();
1081 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1083 void BuiltStyledStreamWriter::unindent() {
1084 assert(indentString_.size() >= indentation_.size());
1085 indentString_.resize(indentString_.size() - indentation_.size());
1088 void BuiltStyledStreamWriter::writeCommentBeforeValue(Value
const& root) {
1089 if (cs_ == CommentStyle::None)
return;
1093 if (!indented_) writeIndent();
1095 JSONCPP_STRING::const_iterator iter = comment.begin();
1096 while (iter != comment.end()) {
1098 if (*iter ==
'\n' &&
1099 ((iter+1) != comment.end() && *(iter + 1) ==
'/'))
1101 *sout_ << indentString_;
1107 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value
const& root) {
1108 if (cs_ == CommentStyle::None)
return;
1119 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1139 setDefaults(&settings_);
1145 JSONCPP_STRING indentation = settings_[
"indentation"].asString();
1147 bool eyc = settings_[
"enableYAMLCompatibility"].asBool();
1148 bool dnp = settings_[
"dropNullPlaceholders"].asBool();
1149 bool usf = settings_[
"useSpecialFloats"].asBool();
1150 unsigned int pre = settings_[
"precision"].asUInt();
1151 CommentStyle::Enum cs = CommentStyle::All;
1152 if (cs_str ==
"All") {
1153 cs = CommentStyle::All;
1154 }
else if (cs_str ==
"None") {
1155 cs = CommentStyle::None;
1157 throwRuntimeError(
"commentStyle must be 'All' or 'None'");
1162 }
else if (indentation.empty()) {
1169 if (pre > 17) pre = 17;
1171 return new BuiltStyledStreamWriter(
1173 colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
1177 valid_keys->clear();
1178 valid_keys->insert(
"indentation");
1179 valid_keys->insert(
"commentStyle");
1180 valid_keys->insert(
"enableYAMLCompatibility");
1181 valid_keys->insert(
"dropNullPlaceholders");
1182 valid_keys->insert(
"useSpecialFloats");
1183 valid_keys->insert(
"precision");
1188 if (!invalid) invalid = &my_invalid;
1190 std::set<JSONCPP_STRING> valid_keys;
1193 size_t n = keys.size();
1194 for (
size_t i = 0; i < n; ++i) {
1196 if (valid_keys.find(key) == valid_keys.end()) {
1197 inv[key] = settings_[key];
1200 return 0u == inv.
size();
1204 return settings_[key];
1210 (*settings)[
"commentStyle"] =
"All";
1211 (*settings)[
"indentation"] =
"\t";
1212 (*settings)[
"enableYAMLCompatibility"] =
false;
1213 (*settings)[
"dropNullPlaceholders"] =
false;
1214 (*settings)[
"useSpecialFloats"] =
false;
1215 (*settings)[
"precision"] = 17;
1222 writer->write(root, &sout);
1229 writer->write(root, &sout);
Value & operator[](std::string key)
A simple way to update a specific setting.
#define JSONCPP_OSTRINGSTREAM
A simple abstract factory.
void omitEndingLineFeed()
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_.
LargestUInt asLargestUInt() const
StreamWriter * newStreamWriter() const
array value (ordered list)
std::string valueToQuotedString(const char *value)
Members getMemberNames() const
Return a list of the member names.
object value (collection of name/value pairs).
std::string write(const Value &root)
bool getString(char const **begin, char const **end) const
Get raw char* of string-value.
void enableYAMLCompatibility()
void write(std::ostream &out, const Value &root)
Serialize a Value in JSON format.
char UIntToStringBuffer[uintToStringBufferSize]
static void fixNumericLocale(char *begin, char *end)
Change ',' to '.
static void getValidWriterKeys(std::set< std::string > *valid_keys)
static const LargestInt minLargestInt
Minimum signed integer value that can be stored in a Json::Value.
StyledStreamWriter(std::string indentation="\)
ArrayIndex size() const
Number of values in array or object.
LargestInt asLargestInt() const
std::string valueToString(Int value)
static std::string toHex16Bit(unsigned int x)
std::string write(const Value &root)
Serialize a Value in JSON format.
JSON (JavaScript Object Notation).
static bool isAnyCharRequiredQuoting(char const *s, size_t n)
std::auto_ptr< StreamWriter > StreamWriterPtr
static std::string valueToQuotedStringN(const char *value, unsigned length)
static unsigned int utf8ToCodepoint(const char *&s, const char *e)
a comment on the line after a value (only make sense for
void dropNullPlaceholders()
Drop the "null" string from the writer's output for nullValues.
std::vector< std::string > Members
std::string writeString(StreamWriter::Factory const &factory, Value const &root)
Write into stringstream, then return string, for convenience.
a comment placed on the line before a value
a comment just after a value on the same line
std::ostream & operator<<(std::ostream &, const Value &root)
Output using the StyledStreamWriter.
Build a StreamWriter implementation.
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.