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)
93 char const* end = str + len;
104 char* current = buffer +
sizeof(buffer);
108 }
else if (value < 0) {
114 assert(current >= buffer);
120 char* current = buffer +
sizeof(buffer);
122 assert(current >= buffer);
126 #if defined(JSON_HAS_INT64)
136 #endif // # if defined(JSON_HAS_INT64)
145 char formatString[6];
146 sprintf(formatString,
"%%.%dg", precision);
152 len =
snprintf(buffer,
sizeof(buffer), formatString, value);
155 if (!strstr(buffer,
".") && !strstr(buffer,
"e")) {
156 strcat(buffer,
".0");
161 if (value != value) {
162 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"NaN" :
"null");
163 }
else if (value < 0) {
164 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"-Infinity" :
"-1e+9999");
166 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"Infinity" :
"1e+9999");
184 if (strpbrk(value,
"\"\\\b\f\n\r\t") == NULL &&
190 JSONCPP_STRING::size_type maxsize =
191 strlen(value) * 2 + 3;
193 result.reserve(maxsize);
195 for (
const char* c = value; *c != 0; ++c) {
229 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
230 << std::setw(4) <<
static_cast<int>(*c);
243 static char const*
strnpbrk(
char const* s,
char const* accept,
size_t n) {
244 assert((s || !n) && accept);
246 char const*
const end = s + n;
247 for (
char const* cur = s; cur < end; ++cur) {
249 for (
char const* a = accept; *a; ++a) {
261 if (
strnpbrk(value,
"\"\\\b\f\n\r\t", length) == NULL &&
267 JSONCPP_STRING::size_type maxsize =
270 result.reserve(maxsize);
272 char const* end = value + length;
273 for (
const char* c = value; c != end; ++c) {
307 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
308 << std::setw(4) <<
static_cast<int>(*c);
328 : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
329 omitEndingLineFeed_(false) {}
340 if (!omitEndingLineFeed_)
345 void FastWriter::writeValue(
const Value& value) {
346 switch (value.
type()) {
348 if (!dropNullPlaceholders_)
375 for (
ArrayIndex index = 0; index < size; ++index) {
378 writeValue(value[index]);
385 for (Value::Members::iterator it = members.begin(); it != members.end();
388 if (it != members.begin())
391 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
392 writeValue(value[name]);
403 : rightMargin_(74), indentSize_(3), addChildValues_() {}
407 addChildValues_ =
false;
409 writeCommentBeforeValue(root);
411 writeCommentAfterValueOnSameLine(root);
416 void StyledWriter::writeValue(
const Value& value) {
417 switch (value.
type()) {
444 writeArrayValue(value);
451 writeWithIndent(
"{");
453 Value::Members::iterator it = members.begin();
456 const Value& childValue = value[name];
457 writeCommentBeforeValue(childValue);
460 writeValue(childValue);
461 if (++it == members.end()) {
462 writeCommentAfterValueOnSameLine(childValue);
466 writeCommentAfterValueOnSameLine(childValue);
469 writeWithIndent(
"}");
475 void StyledWriter::writeArrayValue(
const Value& value) {
476 unsigned size = value.size();
480 bool isArrayMultiLine = isMultineArray(value);
481 if (isArrayMultiLine) {
482 writeWithIndent(
"[");
484 bool hasChildValue = !childValues_.empty();
487 const Value& childValue = value[index];
488 writeCommentBeforeValue(childValue);
490 writeWithIndent(childValues_[index]);
493 writeValue(childValue);
495 if (++index == size) {
496 writeCommentAfterValueOnSameLine(childValue);
500 writeCommentAfterValueOnSameLine(childValue);
503 writeWithIndent(
"]");
506 assert(childValues_.size() == size);
508 for (
unsigned index = 0; index < size; ++index) {
511 document_ += childValues_[index];
518 bool StyledWriter::isMultineArray(
const Value& value) {
520 bool isMultiLine = size * 3 >= rightMargin_;
521 childValues_.clear();
522 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
523 const Value& childValue = value[index];
524 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
525 childValue.size() > 0);
529 childValues_.reserve(size);
530 addChildValues_ =
true;
532 for (
ArrayIndex index = 0; index < size; ++index) {
533 if (hasCommentForValue(value[index])) {
536 writeValue(value[index]);
537 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
539 addChildValues_ =
false;
540 isMultiLine = isMultiLine || lineLength >= rightMargin_;
547 childValues_.push_back(value);
552 void StyledWriter::writeIndent() {
553 if (!document_.empty()) {
554 char last = document_[document_.length() - 1];
560 document_ += indentString_;
568 void StyledWriter::indent() { indentString_ +=
JSONCPP_STRING(indentSize_,
' '); }
570 void StyledWriter::unindent() {
571 assert(indentString_.size() >= indentSize_);
572 indentString_.resize(indentString_.size() - indentSize_);
575 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
582 JSONCPP_STRING::const_iterator iter = comment.begin();
583 while (iter != comment.end()) {
586 (iter != comment.end() && *(iter + 1) ==
'/'))
595 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
606 bool StyledWriter::hasCommentForValue(
const Value& value) {
616 : document_(NULL), rightMargin_(74), indentation_(indentation),
621 addChildValues_ =
false;
624 writeCommentBeforeValue(root);
625 if (!indented_) writeIndent();
628 writeCommentAfterValueOnSameLine(root);
633 void StyledStreamWriter::writeValue(
const Value& value) {
634 switch (value.
type()) {
661 writeArrayValue(value);
668 writeWithIndent(
"{");
670 Value::Members::iterator it = members.begin();
673 const Value& childValue = value[name];
674 writeCommentBeforeValue(childValue);
677 writeValue(childValue);
678 if (++it == members.end()) {
679 writeCommentAfterValueOnSameLine(childValue);
683 writeCommentAfterValueOnSameLine(childValue);
686 writeWithIndent(
"}");
692 void StyledStreamWriter::writeArrayValue(
const Value& value) {
693 unsigned size = value.size();
697 bool isArrayMultiLine = isMultineArray(value);
698 if (isArrayMultiLine) {
699 writeWithIndent(
"[");
701 bool hasChildValue = !childValues_.empty();
704 const Value& childValue = value[index];
705 writeCommentBeforeValue(childValue);
707 writeWithIndent(childValues_[index]);
709 if (!indented_) writeIndent();
711 writeValue(childValue);
714 if (++index == size) {
715 writeCommentAfterValueOnSameLine(childValue);
719 writeCommentAfterValueOnSameLine(childValue);
722 writeWithIndent(
"]");
725 assert(childValues_.size() == size);
727 for (
unsigned index = 0; index < size; ++index) {
730 *document_ << childValues_[index];
737 bool StyledStreamWriter::isMultineArray(
const Value& value) {
739 bool isMultiLine = size * 3 >= rightMargin_;
740 childValues_.clear();
741 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
742 const Value& childValue = value[index];
743 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
744 childValue.size() > 0);
748 childValues_.reserve(size);
749 addChildValues_ =
true;
751 for (
ArrayIndex index = 0; index < size; ++index) {
752 if (hasCommentForValue(value[index])) {
755 writeValue(value[index]);
756 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
758 addChildValues_ =
false;
759 isMultiLine = isMultiLine || lineLength >= rightMargin_;
766 childValues_.push_back(value);
771 void StyledStreamWriter::writeIndent() {
776 *document_ <<
'\n' << indentString_;
779 void StyledStreamWriter::writeWithIndent(
const JSONCPP_STRING& value) {
780 if (!indented_) writeIndent();
785 void StyledStreamWriter::indent() { indentString_ += indentation_; }
787 void StyledStreamWriter::unindent() {
788 assert(indentString_.size() >= indentation_.size());
789 indentString_.resize(indentString_.size() - indentation_.size());
792 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
796 if (!indented_) writeIndent();
798 JSONCPP_STRING::const_iterator iter = comment.begin();
799 while (iter != comment.end()) {
802 (iter != comment.end() && *(iter + 1) ==
'/'))
804 *document_ << indentString_;
810 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
821 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
831 struct CommentStyle {
840 struct BuiltStyledStreamWriter :
public StreamWriter
842 BuiltStyledStreamWriter(
844 CommentStyle::Enum cs,
848 bool useSpecialFloats,
849 unsigned int precision);
852 void writeValue(Value
const& value);
853 void writeArrayValue(Value
const& value);
854 bool isMultineArray(Value
const& value);
860 void writeCommentBeforeValue(Value
const& root);
861 void writeCommentAfterValueOnSameLine(Value
const& root);
862 static bool hasCommentForValue(
const Value& value);
864 typedef std::vector<JSONCPP_STRING> ChildValues;
866 ChildValues childValues_;
868 unsigned int rightMargin_;
870 CommentStyle::Enum cs_;
874 bool addChildValues_ : 1;
876 bool useSpecialFloats_ : 1;
877 unsigned int precision_;
879 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
881 CommentStyle::Enum cs,
885 bool useSpecialFloats,
886 unsigned int precision)
888 , indentation_(indentation)
890 , colonSymbol_(colonSymbol)
891 , nullSymbol_(nullSymbol)
892 , endingLineFeedSymbol_(endingLineFeedSymbol)
893 , addChildValues_(false)
895 , useSpecialFloats_(useSpecialFloats)
896 , precision_(precision)
899 int BuiltStyledStreamWriter::write(Value
const& root,
JSONCPP_OSTREAM* sout)
902 addChildValues_ =
false;
905 writeCommentBeforeValue(root);
906 if (!indented_) writeIndent();
909 writeCommentAfterValueOnSameLine(root);
910 *sout_ << endingLineFeedSymbol_;
914 void BuiltStyledStreamWriter::writeValue(Value
const& value) {
915 switch (value.type()) {
917 pushValue(nullSymbol_);
926 pushValue(
valueToString(value.asDouble(), useSpecialFloats_, precision_));
933 bool ok = value.getString(&str, &end);
942 writeArrayValue(value);
949 writeWithIndent(
"{");
951 Value::Members::iterator it = members.begin();
954 Value
const& childValue = value[name];
955 writeCommentBeforeValue(childValue);
957 *sout_ << colonSymbol_;
958 writeValue(childValue);
959 if (++it == members.end()) {
960 writeCommentAfterValueOnSameLine(childValue);
964 writeCommentAfterValueOnSameLine(childValue);
967 writeWithIndent(
"}");
973 void BuiltStyledStreamWriter::writeArrayValue(Value
const& value) {
974 unsigned size = value.size();
978 bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
980 writeWithIndent(
"[");
982 bool hasChildValue = !childValues_.empty();
985 Value
const& childValue = value[index];
986 writeCommentBeforeValue(childValue);
988 writeWithIndent(childValues_[index]);
990 if (!indented_) writeIndent();
992 writeValue(childValue);
995 if (++index == size) {
996 writeCommentAfterValueOnSameLine(childValue);
1000 writeCommentAfterValueOnSameLine(childValue);
1003 writeWithIndent(
"]");
1006 assert(childValues_.size() == size);
1008 if (!indentation_.empty()) *sout_ <<
" ";
1009 for (
unsigned index = 0; index < size; ++index) {
1011 *sout_ << ((!indentation_.empty()) ?
", " :
",");
1012 *sout_ << childValues_[index];
1014 if (!indentation_.empty()) *sout_ <<
" ";
1020 bool BuiltStyledStreamWriter::isMultineArray(Value
const& value) {
1022 bool isMultiLine = size * 3 >= rightMargin_;
1023 childValues_.clear();
1024 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
1025 Value
const& childValue = value[index];
1026 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
1027 childValue.size() > 0);
1031 childValues_.reserve(size);
1032 addChildValues_ =
true;
1034 for (
ArrayIndex index = 0; index < size; ++index) {
1035 if (hasCommentForValue(value[index])) {
1038 writeValue(value[index]);
1039 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
1041 addChildValues_ =
false;
1042 isMultiLine = isMultiLine || lineLength >= rightMargin_;
1047 void BuiltStyledStreamWriter::pushValue(
JSONCPP_STRING const& value) {
1048 if (addChildValues_)
1049 childValues_.push_back(value);
1054 void BuiltStyledStreamWriter::writeIndent() {
1060 if (!indentation_.empty()) {
1062 *sout_ <<
'\n' << indentString_;
1066 void BuiltStyledStreamWriter::writeWithIndent(
JSONCPP_STRING const& value) {
1067 if (!indented_) writeIndent();
1072 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1074 void BuiltStyledStreamWriter::unindent() {
1075 assert(indentString_.size() >= indentation_.size());
1076 indentString_.resize(indentString_.size() - indentation_.size());
1079 void BuiltStyledStreamWriter::writeCommentBeforeValue(Value
const& root) {
1080 if (cs_ == CommentStyle::None)
return;
1084 if (!indented_) writeIndent();
1086 JSONCPP_STRING::const_iterator iter = comment.begin();
1087 while (iter != comment.end()) {
1089 if (*iter ==
'\n' &&
1090 (iter != comment.end() && *(iter + 1) ==
'/'))
1092 *sout_ << indentString_;
1098 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value
const& root) {
1099 if (cs_ == CommentStyle::None)
return;
1110 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1130 setDefaults(&settings_);
1136 JSONCPP_STRING indentation = settings_[
"indentation"].asString();
1138 bool eyc = settings_[
"enableYAMLCompatibility"].asBool();
1139 bool dnp = settings_[
"dropNullPlaceholders"].asBool();
1140 bool usf = settings_[
"useSpecialFloats"].asBool();
1141 unsigned int pre = settings_[
"precision"].asUInt();
1142 CommentStyle::Enum cs = CommentStyle::All;
1143 if (cs_str ==
"All") {
1144 cs = CommentStyle::All;
1145 }
else if (cs_str ==
"None") {
1146 cs = CommentStyle::None;
1148 throwRuntimeError(
"commentStyle must be 'All' or 'None'");
1153 }
else if (indentation.empty()) {
1160 if (pre > 17) pre = 17;
1162 return new BuiltStyledStreamWriter(
1164 colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
1168 valid_keys->clear();
1169 valid_keys->insert(
"indentation");
1170 valid_keys->insert(
"commentStyle");
1171 valid_keys->insert(
"enableYAMLCompatibility");
1172 valid_keys->insert(
"dropNullPlaceholders");
1173 valid_keys->insert(
"useSpecialFloats");
1174 valid_keys->insert(
"precision");
1179 if (!invalid) invalid = &my_invalid;
1181 std::set<JSONCPP_STRING> valid_keys;
1184 size_t n = keys.size();
1185 for (
size_t i = 0; i < n; ++i) {
1187 if (valid_keys.find(key) == valid_keys.end()) {
1188 inv[key] = settings_[key];
1191 return 0u == inv.
size();
1195 return settings_[key];
1201 (*settings)[
"commentStyle"] =
"All";
1202 (*settings)[
"indentation"] =
"\t";
1203 (*settings)[
"enableYAMLCompatibility"] =
false;
1204 (*settings)[
"dropNullPlaceholders"] =
false;
1205 (*settings)[
"useSpecialFloats"] =
false;
1206 (*settings)[
"precision"] = 17;
1213 writer->write(root, &sout);
1220 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()
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_.
array value (ordered list)
LargestUInt asLargestUInt() const
std::string valueToQuotedString(const char *value)
StreamWriter * newStreamWriter() const
object value (collection of name/value pairs).
std::string write(const Value &root)
void enableYAMLCompatibility()
StyledStreamWriter(std::string indentation="\t")
void write(std::ostream &out, const Value &root)
Serialize a Value in JSON format.
char UIntToStringBuffer[uintToStringBufferSize]
static bool isControlCharacter(char ch)
Returns true if ch is a control character (in range [1,31]).
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.
std::string valueToString(Int value)
bool validate(Json::Value *invalid) const
std::string write(const Value &root)
Serialize a Value in JSON format.
JSON (JavaScript Object Notation).
Members getMemberNames() const
Return a list of the member names.
std::auto_ptr< StreamWriter > StreamWriterPtr
static std::string valueToQuotedStringN(const char *value, unsigned length)
ArrayIndex size() const
Number of values in array or object.
static bool containsControlCharacter0(const char *str, unsigned len)
a comment on the line after a value (only make sense for
LargestInt asLargestInt() const
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.
static char const * strnpbrk(char const *s, char const *accept, size_t n)
static bool containsControlCharacter(const char *str)
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.
bool getString(char const **begin, char const **end) const
Get raw char* of string-value.