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)
144 char formatString[6];
145 sprintf(formatString,
"%%.%dg", precision);
151 len =
snprintf(buffer,
sizeof(buffer), formatString, value);
154 if (value != value) {
155 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"NaN" :
"null");
156 }
else if (value < 0) {
157 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"-Infinity" :
"-1e+9999");
159 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"Infinity" :
"1e+9999");
176 if (strpbrk(value,
"\"\\\b\f\n\r\t") == NULL &&
182 JSONCPP_STRING::size_type maxsize =
183 strlen(value) * 2 + 3;
185 result.reserve(maxsize);
187 for (
const char* c = value; *c != 0; ++c) {
221 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
222 << std::setw(4) <<
static_cast<int>(*c);
235 static char const*
strnpbrk(
char const* s,
char const* accept,
size_t n) {
236 assert((s || !n) && accept);
238 char const*
const end = s + n;
239 for (
char const* cur = s; cur < end; ++cur) {
241 for (
char const* a = accept; *a; ++a) {
253 if (
strnpbrk(value,
"\"\\\b\f\n\r\t", length) == NULL &&
259 JSONCPP_STRING::size_type maxsize =
262 result.reserve(maxsize);
264 char const* end = value + length;
265 for (
const char* c = value; c != end; ++c) {
299 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
300 << std::setw(4) <<
static_cast<int>(*c);
320 : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
321 omitEndingLineFeed_(false) {}
332 if (!omitEndingLineFeed_)
337 void FastWriter::writeValue(
const Value& value) {
338 switch (value.
type()) {
340 if (!dropNullPlaceholders_)
367 for (
ArrayIndex index = 0; index < size; ++index) {
370 writeValue(value[index]);
377 for (Value::Members::iterator it = members.begin(); it != members.end();
380 if (it != members.begin())
383 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
384 writeValue(value[name]);
395 : rightMargin_(74), indentSize_(3), addChildValues_() {}
399 addChildValues_ =
false;
401 writeCommentBeforeValue(root);
403 writeCommentAfterValueOnSameLine(root);
408 void StyledWriter::writeValue(
const Value& value) {
409 switch (value.
type()) {
436 writeArrayValue(value);
443 writeWithIndent(
"{");
445 Value::Members::iterator it = members.begin();
448 const Value& childValue = value[name];
449 writeCommentBeforeValue(childValue);
452 writeValue(childValue);
453 if (++it == members.end()) {
454 writeCommentAfterValueOnSameLine(childValue);
458 writeCommentAfterValueOnSameLine(childValue);
461 writeWithIndent(
"}");
467 void StyledWriter::writeArrayValue(
const Value& value) {
468 unsigned size = value.size();
472 bool isArrayMultiLine = isMultineArray(value);
473 if (isArrayMultiLine) {
474 writeWithIndent(
"[");
476 bool hasChildValue = !childValues_.empty();
479 const Value& childValue = value[index];
480 writeCommentBeforeValue(childValue);
482 writeWithIndent(childValues_[index]);
485 writeValue(childValue);
487 if (++index == size) {
488 writeCommentAfterValueOnSameLine(childValue);
492 writeCommentAfterValueOnSameLine(childValue);
495 writeWithIndent(
"]");
498 assert(childValues_.size() == size);
500 for (
unsigned index = 0; index < size; ++index) {
503 document_ += childValues_[index];
510 bool StyledWriter::isMultineArray(
const Value& value) {
512 bool isMultiLine = size * 3 >= rightMargin_;
513 childValues_.clear();
514 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
515 const Value& childValue = value[index];
516 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
517 childValue.size() > 0);
521 childValues_.reserve(size);
522 addChildValues_ =
true;
524 for (
ArrayIndex index = 0; index < size; ++index) {
525 if (hasCommentForValue(value[index])) {
528 writeValue(value[index]);
529 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
531 addChildValues_ =
false;
532 isMultiLine = isMultiLine || lineLength >= rightMargin_;
539 childValues_.push_back(value);
544 void StyledWriter::writeIndent() {
545 if (!document_.empty()) {
546 char last = document_[document_.length() - 1];
552 document_ += indentString_;
560 void StyledWriter::indent() { indentString_ +=
JSONCPP_STRING(indentSize_,
' '); }
562 void StyledWriter::unindent() {
563 assert(indentString_.size() >= indentSize_);
564 indentString_.resize(indentString_.size() - indentSize_);
567 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
574 JSONCPP_STRING::const_iterator iter = comment.begin();
575 while (iter != comment.end()) {
578 (iter != comment.end() && *(iter + 1) ==
'/'))
587 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
598 bool StyledWriter::hasCommentForValue(
const Value& value) {
608 : document_(NULL), rightMargin_(74), indentation_(indentation),
613 addChildValues_ =
false;
616 writeCommentBeforeValue(root);
617 if (!indented_) writeIndent();
620 writeCommentAfterValueOnSameLine(root);
625 void StyledStreamWriter::writeValue(
const Value& value) {
626 switch (value.
type()) {
653 writeArrayValue(value);
660 writeWithIndent(
"{");
662 Value::Members::iterator it = members.begin();
665 const Value& childValue = value[name];
666 writeCommentBeforeValue(childValue);
669 writeValue(childValue);
670 if (++it == members.end()) {
671 writeCommentAfterValueOnSameLine(childValue);
675 writeCommentAfterValueOnSameLine(childValue);
678 writeWithIndent(
"}");
684 void StyledStreamWriter::writeArrayValue(
const Value& value) {
685 unsigned size = value.size();
689 bool isArrayMultiLine = isMultineArray(value);
690 if (isArrayMultiLine) {
691 writeWithIndent(
"[");
693 bool hasChildValue = !childValues_.empty();
696 const Value& childValue = value[index];
697 writeCommentBeforeValue(childValue);
699 writeWithIndent(childValues_[index]);
701 if (!indented_) writeIndent();
703 writeValue(childValue);
706 if (++index == size) {
707 writeCommentAfterValueOnSameLine(childValue);
711 writeCommentAfterValueOnSameLine(childValue);
714 writeWithIndent(
"]");
717 assert(childValues_.size() == size);
719 for (
unsigned index = 0; index < size; ++index) {
722 *document_ << childValues_[index];
729 bool StyledStreamWriter::isMultineArray(
const Value& value) {
731 bool isMultiLine = size * 3 >= rightMargin_;
732 childValues_.clear();
733 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
734 const Value& childValue = value[index];
735 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
736 childValue.size() > 0);
740 childValues_.reserve(size);
741 addChildValues_ =
true;
743 for (
ArrayIndex index = 0; index < size; ++index) {
744 if (hasCommentForValue(value[index])) {
747 writeValue(value[index]);
748 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
750 addChildValues_ =
false;
751 isMultiLine = isMultiLine || lineLength >= rightMargin_;
758 childValues_.push_back(value);
763 void StyledStreamWriter::writeIndent() {
768 *document_ <<
'\n' << indentString_;
771 void StyledStreamWriter::writeWithIndent(
const JSONCPP_STRING& value) {
772 if (!indented_) writeIndent();
777 void StyledStreamWriter::indent() { indentString_ += indentation_; }
779 void StyledStreamWriter::unindent() {
780 assert(indentString_.size() >= indentation_.size());
781 indentString_.resize(indentString_.size() - indentation_.size());
784 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
788 if (!indented_) writeIndent();
790 JSONCPP_STRING::const_iterator iter = comment.begin();
791 while (iter != comment.end()) {
794 (iter != comment.end() && *(iter + 1) ==
'/'))
796 *document_ << indentString_;
802 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
813 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
823 struct CommentStyle {
832 struct BuiltStyledStreamWriter :
public StreamWriter
834 BuiltStyledStreamWriter(
836 CommentStyle::Enum cs,
840 bool useSpecialFloats,
841 unsigned int precision);
844 void writeValue(Value
const& value);
845 void writeArrayValue(Value
const& value);
846 bool isMultineArray(Value
const& value);
852 void writeCommentBeforeValue(Value
const& root);
853 void writeCommentAfterValueOnSameLine(Value
const& root);
854 static bool hasCommentForValue(
const Value& value);
856 typedef std::vector<JSONCPP_STRING> ChildValues;
858 ChildValues childValues_;
860 unsigned int rightMargin_;
862 CommentStyle::Enum cs_;
866 bool addChildValues_ : 1;
868 bool useSpecialFloats_ : 1;
869 unsigned int precision_;
871 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
873 CommentStyle::Enum cs,
877 bool useSpecialFloats,
878 unsigned int precision)
880 , indentation_(indentation)
882 , colonSymbol_(colonSymbol)
883 , nullSymbol_(nullSymbol)
884 , endingLineFeedSymbol_(endingLineFeedSymbol)
885 , addChildValues_(false)
887 , useSpecialFloats_(useSpecialFloats)
888 , precision_(precision)
891 int BuiltStyledStreamWriter::write(Value
const& root,
JSONCPP_OSTREAM* sout)
894 addChildValues_ =
false;
897 writeCommentBeforeValue(root);
898 if (!indented_) writeIndent();
901 writeCommentAfterValueOnSameLine(root);
902 *sout_ << endingLineFeedSymbol_;
906 void BuiltStyledStreamWriter::writeValue(Value
const& value) {
907 switch (value.type()) {
909 pushValue(nullSymbol_);
918 pushValue(
valueToString(value.asDouble(), useSpecialFloats_, precision_));
925 bool ok = value.getString(&str, &end);
934 writeArrayValue(value);
941 writeWithIndent(
"{");
943 Value::Members::iterator it = members.begin();
946 Value
const& childValue = value[name];
947 writeCommentBeforeValue(childValue);
949 *sout_ << colonSymbol_;
950 writeValue(childValue);
951 if (++it == members.end()) {
952 writeCommentAfterValueOnSameLine(childValue);
956 writeCommentAfterValueOnSameLine(childValue);
959 writeWithIndent(
"}");
965 void BuiltStyledStreamWriter::writeArrayValue(Value
const& value) {
966 unsigned size = value.size();
970 bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
972 writeWithIndent(
"[");
974 bool hasChildValue = !childValues_.empty();
977 Value
const& childValue = value[index];
978 writeCommentBeforeValue(childValue);
980 writeWithIndent(childValues_[index]);
982 if (!indented_) writeIndent();
984 writeValue(childValue);
987 if (++index == size) {
988 writeCommentAfterValueOnSameLine(childValue);
992 writeCommentAfterValueOnSameLine(childValue);
995 writeWithIndent(
"]");
998 assert(childValues_.size() == size);
1000 if (!indentation_.empty()) *sout_ <<
" ";
1001 for (
unsigned index = 0; index < size; ++index) {
1004 *sout_ << childValues_[index];
1006 if (!indentation_.empty()) *sout_ <<
" ";
1012 bool BuiltStyledStreamWriter::isMultineArray(Value
const& value) {
1014 bool isMultiLine = size * 3 >= rightMargin_;
1015 childValues_.clear();
1016 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
1017 Value
const& childValue = value[index];
1018 isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
1019 childValue.size() > 0);
1023 childValues_.reserve(size);
1024 addChildValues_ =
true;
1026 for (
ArrayIndex index = 0; index < size; ++index) {
1027 if (hasCommentForValue(value[index])) {
1030 writeValue(value[index]);
1031 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
1033 addChildValues_ =
false;
1034 isMultiLine = isMultiLine || lineLength >= rightMargin_;
1039 void BuiltStyledStreamWriter::pushValue(
JSONCPP_STRING const& value) {
1040 if (addChildValues_)
1041 childValues_.push_back(value);
1046 void BuiltStyledStreamWriter::writeIndent() {
1052 if (!indentation_.empty()) {
1054 *sout_ <<
'\n' << indentString_;
1058 void BuiltStyledStreamWriter::writeWithIndent(
JSONCPP_STRING const& value) {
1059 if (!indented_) writeIndent();
1064 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1066 void BuiltStyledStreamWriter::unindent() {
1067 assert(indentString_.size() >= indentation_.size());
1068 indentString_.resize(indentString_.size() - indentation_.size());
1071 void BuiltStyledStreamWriter::writeCommentBeforeValue(Value
const& root) {
1072 if (cs_ == CommentStyle::None)
return;
1076 if (!indented_) writeIndent();
1078 JSONCPP_STRING::const_iterator iter = comment.begin();
1079 while (iter != comment.end()) {
1081 if (*iter ==
'\n' &&
1082 (iter != comment.end() && *(iter + 1) ==
'/'))
1084 *sout_ << indentString_;
1090 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value
const& root) {
1091 if (cs_ == CommentStyle::None)
return;
1102 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1122 setDefaults(&settings_);
1128 JSONCPP_STRING indentation = settings_[
"indentation"].asString();
1130 bool eyc = settings_[
"enableYAMLCompatibility"].asBool();
1131 bool dnp = settings_[
"dropNullPlaceholders"].asBool();
1132 bool usf = settings_[
"useSpecialFloats"].asBool();
1133 unsigned int pre = settings_[
"precision"].asUInt();
1134 CommentStyle::Enum cs = CommentStyle::All;
1135 if (cs_str ==
"All") {
1136 cs = CommentStyle::All;
1137 }
else if (cs_str ==
"None") {
1138 cs = CommentStyle::None;
1140 throwRuntimeError(
"commentStyle must be 'All' or 'None'");
1145 }
else if (indentation.empty()) {
1152 if (pre > 17) pre = 17;
1154 return new BuiltStyledStreamWriter(
1156 colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
1160 valid_keys->clear();
1161 valid_keys->insert(
"indentation");
1162 valid_keys->insert(
"commentStyle");
1163 valid_keys->insert(
"enableYAMLCompatibility");
1164 valid_keys->insert(
"dropNullPlaceholders");
1165 valid_keys->insert(
"useSpecialFloats");
1166 valid_keys->insert(
"precision");
1171 if (!invalid) invalid = &my_invalid;
1173 std::set<JSONCPP_STRING> valid_keys;
1176 size_t n = keys.size();
1177 for (
size_t i = 0; i < n; ++i) {
1179 if (valid_keys.find(key) == valid_keys.end()) {
1180 inv[key] = settings_[key];
1183 return 0u == inv.
size();
1187 return settings_[key];
1193 (*settings)[
"commentStyle"] =
"All";
1194 (*settings)[
"indentation"] =
"\t";
1195 (*settings)[
"enableYAMLCompatibility"] =
false;
1196 (*settings)[
"dropNullPlaceholders"] =
false;
1197 (*settings)[
"useSpecialFloats"] =
false;
1198 (*settings)[
"precision"] = 17;
1205 writer->write(root, &sout);
1212 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.