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 (value != value) {
156 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"NaN" :
"null");
157 }
else if (value < 0) {
158 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"-Infinity" :
"-1e+9999");
160 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"Infinity" :
"1e+9999");
178 if (strpbrk(value,
"\"\\\b\f\n\r\t") == NULL &&
184 JSONCPP_STRING::size_type maxsize =
185 strlen(value) * 2 + 3;
187 result.reserve(maxsize);
189 for (
const char* c = value; *c != 0; ++c) {
223 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
224 << std::setw(4) <<
static_cast<int>(*c);
237 static char const*
strnpbrk(
char const* s,
char const* accept,
size_t n) {
238 assert((s || !n) && accept);
240 char const*
const end = s + n;
241 for (
char const* cur = s; cur < end; ++cur) {
243 for (
char const* a = accept; *a; ++a) {
255 if (
strnpbrk(value,
"\"\\\b\f\n\r\t", length) == NULL &&
261 JSONCPP_STRING::size_type maxsize =
264 result.reserve(maxsize);
266 char const* end = value + length;
267 for (
const char* c = value; c != end; ++c) {
301 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
302 << std::setw(4) <<
static_cast<int>(*c);
322 : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
323 omitEndingLineFeed_(false) {}
334 if (!omitEndingLineFeed_)
339 void FastWriter::writeValue(
const Value& value) {
340 switch (value.
type()) {
342 if (!dropNullPlaceholders_)
369 for (
ArrayIndex index = 0; index < size; ++index) {
372 writeValue(value[index]);
379 for (Value::Members::iterator it = members.begin(); it != members.end();
382 if (it != members.begin())
385 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
386 writeValue(value[name]);
397 : rightMargin_(74), indentSize_(3), addChildValues_() {}
401 addChildValues_ =
false;
403 writeCommentBeforeValue(root);
405 writeCommentAfterValueOnSameLine(root);
410 void StyledWriter::writeValue(
const Value& value) {
411 switch (value.
type()) {
438 writeArrayValue(value);
445 writeWithIndent(
"{");
447 Value::Members::iterator it = members.begin();
450 const Value& childValue = value[name];
451 writeCommentBeforeValue(childValue);
454 writeValue(childValue);
455 if (++it == members.end()) {
456 writeCommentAfterValueOnSameLine(childValue);
460 writeCommentAfterValueOnSameLine(childValue);
463 writeWithIndent(
"}");
469 void StyledWriter::writeArrayValue(
const Value& value) {
470 unsigned size = value.
size();
474 bool isArrayMultiLine = isMultineArray(value);
475 if (isArrayMultiLine) {
476 writeWithIndent(
"[");
478 bool hasChildValue = !childValues_.empty();
481 const Value& childValue = value[index];
482 writeCommentBeforeValue(childValue);
484 writeWithIndent(childValues_[index]);
487 writeValue(childValue);
489 if (++index == size) {
490 writeCommentAfterValueOnSameLine(childValue);
494 writeCommentAfterValueOnSameLine(childValue);
497 writeWithIndent(
"]");
500 assert(childValues_.size() == size);
502 for (
unsigned index = 0; index < size; ++index) {
505 document_ += childValues_[index];
512 bool StyledWriter::isMultineArray(
const Value& value) {
514 bool isMultiLine = size * 3 >= rightMargin_;
515 childValues_.clear();
516 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
517 const Value& childValue = value[index];
519 childValue.
size() > 0);
523 childValues_.reserve(size);
524 addChildValues_ =
true;
526 for (
ArrayIndex index = 0; index < size; ++index) {
527 if (hasCommentForValue(value[index])) {
530 writeValue(value[index]);
531 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
533 addChildValues_ =
false;
534 isMultiLine = isMultiLine || lineLength >= rightMargin_;
541 childValues_.push_back(value);
546 void StyledWriter::writeIndent() {
547 if (!document_.empty()) {
548 char last = document_[document_.length() - 1];
554 document_ += indentString_;
562 void StyledWriter::indent() { indentString_ +=
JSONCPP_STRING(indentSize_,
' '); }
564 void StyledWriter::unindent() {
565 assert(indentString_.size() >= indentSize_);
566 indentString_.resize(indentString_.size() - indentSize_);
569 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
576 JSONCPP_STRING::const_iterator iter = comment.begin();
577 while (iter != comment.end()) {
580 (iter != comment.end() && *(iter + 1) ==
'/'))
589 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
600 bool StyledWriter::hasCommentForValue(
const Value& value) {
610 : document_(NULL), rightMargin_(74), indentation_(indentation),
615 addChildValues_ =
false;
618 writeCommentBeforeValue(root);
619 if (!indented_) writeIndent();
622 writeCommentAfterValueOnSameLine(root);
627 void StyledStreamWriter::writeValue(
const Value& value) {
628 switch (value.
type()) {
655 writeArrayValue(value);
662 writeWithIndent(
"{");
664 Value::Members::iterator it = members.begin();
667 const Value& childValue = value[name];
668 writeCommentBeforeValue(childValue);
671 writeValue(childValue);
672 if (++it == members.end()) {
673 writeCommentAfterValueOnSameLine(childValue);
677 writeCommentAfterValueOnSameLine(childValue);
680 writeWithIndent(
"}");
686 void StyledStreamWriter::writeArrayValue(
const Value& value) {
687 unsigned size = value.
size();
691 bool isArrayMultiLine = isMultineArray(value);
692 if (isArrayMultiLine) {
693 writeWithIndent(
"[");
695 bool hasChildValue = !childValues_.empty();
698 const Value& childValue = value[index];
699 writeCommentBeforeValue(childValue);
701 writeWithIndent(childValues_[index]);
703 if (!indented_) writeIndent();
705 writeValue(childValue);
708 if (++index == size) {
709 writeCommentAfterValueOnSameLine(childValue);
713 writeCommentAfterValueOnSameLine(childValue);
716 writeWithIndent(
"]");
719 assert(childValues_.size() == size);
721 for (
unsigned index = 0; index < size; ++index) {
724 *document_ << childValues_[index];
731 bool StyledStreamWriter::isMultineArray(
const Value& value) {
733 bool isMultiLine = size * 3 >= rightMargin_;
734 childValues_.clear();
735 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
736 const Value& childValue = value[index];
738 childValue.
size() > 0);
742 childValues_.reserve(size);
743 addChildValues_ =
true;
745 for (
ArrayIndex index = 0; index < size; ++index) {
746 if (hasCommentForValue(value[index])) {
749 writeValue(value[index]);
750 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
752 addChildValues_ =
false;
753 isMultiLine = isMultiLine || lineLength >= rightMargin_;
760 childValues_.push_back(value);
765 void StyledStreamWriter::writeIndent() {
770 *document_ <<
'\n' << indentString_;
773 void StyledStreamWriter::writeWithIndent(
const JSONCPP_STRING& value) {
774 if (!indented_) writeIndent();
779 void StyledStreamWriter::indent() { indentString_ += indentation_; }
781 void StyledStreamWriter::unindent() {
782 assert(indentString_.size() >= indentation_.size());
783 indentString_.resize(indentString_.size() - indentation_.size());
786 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
790 if (!indented_) writeIndent();
792 JSONCPP_STRING::const_iterator iter = comment.begin();
793 while (iter != comment.end()) {
796 (iter != comment.end() && *(iter + 1) ==
'/'))
798 *document_ << indentString_;
804 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
815 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
825 struct CommentStyle {
836 BuiltStyledStreamWriter(
838 CommentStyle::Enum cs,
842 bool useSpecialFloats,
843 unsigned int precision);
846 void writeValue(
Value const& value);
847 void writeArrayValue(
Value const& value);
848 bool isMultineArray(
Value const& value);
854 void writeCommentBeforeValue(
Value const& root);
855 void writeCommentAfterValueOnSameLine(
Value const& root);
856 static bool hasCommentForValue(
const Value& value);
858 typedef std::vector<JSONCPP_STRING> ChildValues;
860 ChildValues childValues_;
862 unsigned int rightMargin_;
864 CommentStyle::Enum cs_;
868 bool addChildValues_ : 1;
870 bool useSpecialFloats_ : 1;
871 unsigned int precision_;
873 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
875 CommentStyle::Enum cs,
879 bool useSpecialFloats,
880 unsigned int precision)
882 , indentation_(indentation)
884 , colonSymbol_(colonSymbol)
885 , nullSymbol_(nullSymbol)
886 , endingLineFeedSymbol_(endingLineFeedSymbol)
887 , addChildValues_(
false)
889 , useSpecialFloats_(useSpecialFloats)
890 , precision_(precision)
896 addChildValues_ =
false;
899 writeCommentBeforeValue(root);
900 if (!indented_) writeIndent();
903 writeCommentAfterValueOnSameLine(root);
904 *sout_ << endingLineFeedSymbol_;
908 void BuiltStyledStreamWriter::writeValue(
Value const& value) {
909 switch (value.
type()) {
911 pushValue(nullSymbol_);
936 writeArrayValue(value);
943 writeWithIndent(
"{");
945 Value::Members::iterator it = members.begin();
948 Value const& childValue = value[name];
949 writeCommentBeforeValue(childValue);
951 *sout_ << colonSymbol_;
952 writeValue(childValue);
953 if (++it == members.end()) {
954 writeCommentAfterValueOnSameLine(childValue);
958 writeCommentAfterValueOnSameLine(childValue);
961 writeWithIndent(
"}");
967 void BuiltStyledStreamWriter::writeArrayValue(
Value const& value) {
968 unsigned size = value.
size();
972 bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
974 writeWithIndent(
"[");
976 bool hasChildValue = !childValues_.empty();
979 Value const& childValue = value[index];
980 writeCommentBeforeValue(childValue);
982 writeWithIndent(childValues_[index]);
984 if (!indented_) writeIndent();
986 writeValue(childValue);
989 if (++index == size) {
990 writeCommentAfterValueOnSameLine(childValue);
994 writeCommentAfterValueOnSameLine(childValue);
997 writeWithIndent(
"]");
1000 assert(childValues_.size() == size);
1002 if (!indentation_.empty()) *sout_ <<
" ";
1003 for (
unsigned index = 0; index < size; ++index) {
1006 *sout_ << childValues_[index];
1008 if (!indentation_.empty()) *sout_ <<
" ";
1014 bool BuiltStyledStreamWriter::isMultineArray(
Value const& value) {
1016 bool isMultiLine = size * 3 >= rightMargin_;
1017 childValues_.clear();
1018 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
1019 Value const& childValue = value[index];
1021 childValue.
size() > 0);
1025 childValues_.reserve(size);
1026 addChildValues_ =
true;
1028 for (
ArrayIndex index = 0; index < size; ++index) {
1029 if (hasCommentForValue(value[index])) {
1032 writeValue(value[index]);
1033 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
1035 addChildValues_ =
false;
1036 isMultiLine = isMultiLine || lineLength >= rightMargin_;
1041 void BuiltStyledStreamWriter::pushValue(
JSONCPP_STRING const& value) {
1042 if (addChildValues_)
1043 childValues_.push_back(value);
1048 void BuiltStyledStreamWriter::writeIndent() {
1054 if (!indentation_.empty()) {
1056 *sout_ <<
'\n' << indentString_;
1060 void BuiltStyledStreamWriter::writeWithIndent(
JSONCPP_STRING const& value) {
1061 if (!indented_) writeIndent();
1066 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1068 void BuiltStyledStreamWriter::unindent() {
1069 assert(indentString_.size() >= indentation_.size());
1070 indentString_.resize(indentString_.size() - indentation_.size());
1073 void BuiltStyledStreamWriter::writeCommentBeforeValue(
Value const& root) {
1074 if (cs_ == CommentStyle::None)
return;
1078 if (!indented_) writeIndent();
1080 JSONCPP_STRING::const_iterator iter = comment.begin();
1081 while (iter != comment.end()) {
1083 if (*iter ==
'\n' &&
1084 (iter != comment.end() && *(iter + 1) ==
'/'))
1086 *sout_ << indentString_;
1092 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(
Value const& root) {
1093 if (cs_ == CommentStyle::None)
return;
1104 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1124 setDefaults(&settings_);
1130 JSONCPP_STRING indentation = settings_[
"indentation"].asString();
1132 bool eyc = settings_[
"enableYAMLCompatibility"].asBool();
1133 bool dnp = settings_[
"dropNullPlaceholders"].asBool();
1134 bool usf = settings_[
"useSpecialFloats"].asBool();
1135 unsigned int pre = settings_[
"precision"].asUInt();
1136 CommentStyle::Enum cs = CommentStyle::All;
1137 if (cs_str ==
"All") {
1138 cs = CommentStyle::All;
1139 }
else if (cs_str ==
"None") {
1140 cs = CommentStyle::None;
1142 throwRuntimeError(
"commentStyle must be 'All' or 'None'");
1147 }
else if (indentation.empty()) {
1154 if (pre > 17) pre = 17;
1156 return new BuiltStyledStreamWriter(
1158 colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
1162 valid_keys->clear();
1163 valid_keys->insert(
"indentation");
1164 valid_keys->insert(
"commentStyle");
1165 valid_keys->insert(
"enableYAMLCompatibility");
1166 valid_keys->insert(
"dropNullPlaceholders");
1167 valid_keys->insert(
"useSpecialFloats");
1168 valid_keys->insert(
"precision");
1173 if (!invalid) invalid = &my_invalid;
1175 std::set<JSONCPP_STRING> valid_keys;
1178 size_t n = keys.size();
1179 for (
size_t i = 0; i < n; ++i) {
1181 if (valid_keys.find(key) == valid_keys.end()) {
1182 inv[key] = settings_[key];
1185 return 0u == inv.
size();
1189 return settings_[key];
1195 (*settings)[
"commentStyle"] =
"All";
1196 (*settings)[
"indentation"] =
"\t";
1197 (*settings)[
"enableYAMLCompatibility"] =
false;
1198 (*settings)[
"dropNullPlaceholders"] =
false;
1199 (*settings)[
"useSpecialFloats"] =
false;
1200 (*settings)[
"precision"] = 17;
1207 writer->write(root, &sout);
1214 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 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 getComment(CommentPlacement placement) const
Include delimiters and embedded newlines.
StyledStreamWriter(std::string indentation="\)
ArrayIndex size() const
Number of values in array or object.
LargestInt asLargestInt() const
std::string valueToString(Int value)
std::string write(const Value &root)
Serialize a Value in JSON format.
JSON (JavaScript Object Notation).
std::auto_ptr< StreamWriter > StreamWriterPtr
static std::string valueToQuotedStringN(const char *value, unsigned length)
static bool containsControlCharacter0(const char *str, unsigned len)
a comment on the line after a value (only make sense for
bool hasComment(CommentPlacement placement) 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.