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[15];
146 snprintf(formatString,
sizeof(formatString),
"%%.%dg", precision);
152 len =
snprintf(buffer,
sizeof(buffer), formatString, value);
156 if (!strstr(buffer,
".") && !strstr(buffer,
"e")) {
157 strcat(buffer,
".0");
162 if (value != value) {
163 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"NaN" :
"null");
164 }
else if (value < 0) {
165 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"-Infinity" :
"-1e+9999");
167 len =
snprintf(buffer,
sizeof(buffer), useSpecialFloats ?
"Infinity" :
"1e+9999");
183 if (strpbrk(value,
"\"\\\b\f\n\r\t") == NULL &&
189 JSONCPP_STRING::size_type maxsize =
190 strlen(value) * 2 + 3;
192 result.reserve(maxsize);
194 for (
const char* c = value; *c != 0; ++c) {
228 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
229 << std::setw(4) <<
static_cast<int>(*c);
242 static char const*
strnpbrk(
char const* s,
char const* accept,
size_t n) {
243 assert((s || !n) && accept);
245 char const*
const end = s + n;
246 for (
char const* cur = s; cur < end; ++cur) {
248 for (
char const* a = accept; *a; ++a) {
260 if (
strnpbrk(value,
"\"\\\b\f\n\r\t", length) == NULL &&
266 JSONCPP_STRING::size_type maxsize =
269 result.reserve(maxsize);
271 char const* end = value + length;
272 for (
const char* c = value; c != end; ++c) {
306 oss <<
"\\u" << std::hex << std::uppercase << std::setfill(
'0')
307 << std::setw(4) <<
static_cast<int>(*c);
327 : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
328 omitEndingLineFeed_(false) {}
339 if (!omitEndingLineFeed_)
344 void FastWriter::writeValue(
const Value& value) {
345 switch (value.
type()) {
347 if (!dropNullPlaceholders_)
374 for (
ArrayIndex index = 0; index < size; ++index) {
377 writeValue(value[index]);
384 for (Value::Members::iterator it = members.begin(); it != members.end();
387 if (it != members.begin())
390 document_ += yamlCompatiblityEnabled_ ?
": " :
":";
391 writeValue(value[name]);
402 : rightMargin_(74), indentSize_(3), addChildValues_() {}
406 addChildValues_ =
false;
407 indentString_.clear();
408 writeCommentBeforeValue(root);
410 writeCommentAfterValueOnSameLine(root);
415 void StyledWriter::writeValue(
const Value& value) {
416 switch (value.
type()) {
443 writeArrayValue(value);
450 writeWithIndent(
"{");
452 Value::Members::iterator it = members.begin();
455 const Value& childValue = value[name];
456 writeCommentBeforeValue(childValue);
459 writeValue(childValue);
460 if (++it == members.end()) {
461 writeCommentAfterValueOnSameLine(childValue);
465 writeCommentAfterValueOnSameLine(childValue);
468 writeWithIndent(
"}");
474 void StyledWriter::writeArrayValue(
const Value& value) {
475 unsigned size = value.
size();
479 bool isArrayMultiLine = isMultineArray(value);
480 if (isArrayMultiLine) {
481 writeWithIndent(
"[");
483 bool hasChildValue = !childValues_.empty();
486 const Value& childValue = value[index];
487 writeCommentBeforeValue(childValue);
489 writeWithIndent(childValues_[index]);
492 writeValue(childValue);
494 if (++index == size) {
495 writeCommentAfterValueOnSameLine(childValue);
499 writeCommentAfterValueOnSameLine(childValue);
502 writeWithIndent(
"]");
505 assert(childValues_.size() == size);
507 for (
unsigned index = 0; index < size; ++index) {
510 document_ += childValues_[index];
517 bool StyledWriter::isMultineArray(
const Value& value) {
519 bool isMultiLine = size * 3 >= rightMargin_;
520 childValues_.clear();
521 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
522 const Value& childValue = value[index];
524 childValue.
size() > 0);
528 childValues_.reserve(size);
529 addChildValues_ =
true;
531 for (
ArrayIndex index = 0; index < size; ++index) {
532 if (hasCommentForValue(value[index])) {
535 writeValue(value[index]);
536 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
538 addChildValues_ =
false;
539 isMultiLine = isMultiLine || lineLength >= rightMargin_;
546 childValues_.push_back(value);
551 void StyledWriter::writeIndent() {
552 if (!document_.empty()) {
553 char last = document_[document_.length() - 1];
559 document_ += indentString_;
567 void StyledWriter::indent() { indentString_ +=
JSONCPP_STRING(indentSize_,
' '); }
569 void StyledWriter::unindent() {
570 assert(indentString_.size() >= indentSize_);
571 indentString_.resize(indentString_.size() - indentSize_);
574 void StyledWriter::writeCommentBeforeValue(
const Value& root) {
581 JSONCPP_STRING::const_iterator iter = comment.begin();
582 while (iter != comment.end()) {
585 (iter != comment.end() && *(iter + 1) ==
'/'))
594 void StyledWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
605 bool StyledWriter::hasCommentForValue(
const Value& value) {
615 : document_(NULL), rightMargin_(74), indentation_(indentation),
620 addChildValues_ =
false;
621 indentString_.clear();
623 writeCommentBeforeValue(root);
624 if (!indented_) writeIndent();
627 writeCommentAfterValueOnSameLine(root);
632 void StyledStreamWriter::writeValue(
const Value& value) {
633 switch (value.
type()) {
660 writeArrayValue(value);
667 writeWithIndent(
"{");
669 Value::Members::iterator it = members.begin();
672 const Value& childValue = value[name];
673 writeCommentBeforeValue(childValue);
676 writeValue(childValue);
677 if (++it == members.end()) {
678 writeCommentAfterValueOnSameLine(childValue);
682 writeCommentAfterValueOnSameLine(childValue);
685 writeWithIndent(
"}");
691 void StyledStreamWriter::writeArrayValue(
const Value& value) {
692 unsigned size = value.
size();
696 bool isArrayMultiLine = isMultineArray(value);
697 if (isArrayMultiLine) {
698 writeWithIndent(
"[");
700 bool hasChildValue = !childValues_.empty();
703 const Value& childValue = value[index];
704 writeCommentBeforeValue(childValue);
706 writeWithIndent(childValues_[index]);
708 if (!indented_) writeIndent();
710 writeValue(childValue);
713 if (++index == size) {
714 writeCommentAfterValueOnSameLine(childValue);
718 writeCommentAfterValueOnSameLine(childValue);
721 writeWithIndent(
"]");
724 assert(childValues_.size() == size);
726 for (
unsigned index = 0; index < size; ++index) {
729 *document_ << childValues_[index];
736 bool StyledStreamWriter::isMultineArray(
const Value& value) {
738 bool isMultiLine = size * 3 >= rightMargin_;
739 childValues_.clear();
740 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
741 const Value& childValue = value[index];
743 childValue.
size() > 0);
747 childValues_.reserve(size);
748 addChildValues_ =
true;
750 for (
ArrayIndex index = 0; index < size; ++index) {
751 if (hasCommentForValue(value[index])) {
754 writeValue(value[index]);
755 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
757 addChildValues_ =
false;
758 isMultiLine = isMultiLine || lineLength >= rightMargin_;
765 childValues_.push_back(value);
770 void StyledStreamWriter::writeIndent() {
775 *document_ <<
'\n' << indentString_;
778 void StyledStreamWriter::writeWithIndent(
const JSONCPP_STRING& value) {
779 if (!indented_) writeIndent();
784 void StyledStreamWriter::indent() { indentString_ += indentation_; }
786 void StyledStreamWriter::unindent() {
787 assert(indentString_.size() >= indentation_.size());
788 indentString_.resize(indentString_.size() - indentation_.size());
791 void StyledStreamWriter::writeCommentBeforeValue(
const Value& root) {
795 if (!indented_) writeIndent();
797 JSONCPP_STRING::const_iterator iter = comment.begin();
798 while (iter != comment.end()) {
801 (iter != comment.end() && *(iter + 1) ==
'/'))
803 *document_ << indentString_;
809 void StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value& root) {
820 bool StyledStreamWriter::hasCommentForValue(
const Value& value) {
830 struct CommentStyle {
841 BuiltStyledStreamWriter(
843 CommentStyle::Enum cs,
847 bool useSpecialFloats,
848 unsigned int precision);
851 void writeValue(
Value const& value);
852 void writeArrayValue(
Value const& value);
853 bool isMultineArray(
Value const& value);
859 void writeCommentBeforeValue(
Value const& root);
860 void writeCommentAfterValueOnSameLine(
Value const& root);
861 static bool hasCommentForValue(
const Value& value);
863 typedef std::vector<JSONCPP_STRING> ChildValues;
865 ChildValues childValues_;
867 unsigned int rightMargin_;
869 CommentStyle::Enum cs_;
873 bool addChildValues_ : 1;
875 bool useSpecialFloats_ : 1;
876 unsigned int precision_;
878 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
880 CommentStyle::Enum cs,
884 bool useSpecialFloats,
885 unsigned int precision)
887 , indentation_(indentation)
889 , colonSymbol_(colonSymbol)
890 , nullSymbol_(nullSymbol)
891 , endingLineFeedSymbol_(endingLineFeedSymbol)
892 , addChildValues_(
false)
894 , useSpecialFloats_(useSpecialFloats)
895 , precision_(precision)
901 addChildValues_ =
false;
903 indentString_.clear();
904 writeCommentBeforeValue(root);
905 if (!indented_) writeIndent();
908 writeCommentAfterValueOnSameLine(root);
909 *sout_ << endingLineFeedSymbol_;
913 void BuiltStyledStreamWriter::writeValue(
Value const& value) {
914 switch (value.
type()) {
916 pushValue(nullSymbol_);
941 writeArrayValue(value);
948 writeWithIndent(
"{");
950 Value::Members::iterator it = members.begin();
953 Value const& childValue = value[name];
954 writeCommentBeforeValue(childValue);
956 *sout_ << colonSymbol_;
957 writeValue(childValue);
958 if (++it == members.end()) {
959 writeCommentAfterValueOnSameLine(childValue);
963 writeCommentAfterValueOnSameLine(childValue);
966 writeWithIndent(
"}");
972 void BuiltStyledStreamWriter::writeArrayValue(
Value const& value) {
973 unsigned size = value.
size();
977 bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
979 writeWithIndent(
"[");
981 bool hasChildValue = !childValues_.empty();
984 Value const& childValue = value[index];
985 writeCommentBeforeValue(childValue);
987 writeWithIndent(childValues_[index]);
989 if (!indented_) writeIndent();
991 writeValue(childValue);
994 if (++index == size) {
995 writeCommentAfterValueOnSameLine(childValue);
999 writeCommentAfterValueOnSameLine(childValue);
1002 writeWithIndent(
"]");
1005 assert(childValues_.size() == size);
1007 if (!indentation_.empty()) *sout_ <<
" ";
1008 for (
unsigned index = 0; index < size; ++index) {
1010 *sout_ << ((!indentation_.empty()) ?
", " :
",");
1011 *sout_ << childValues_[index];
1013 if (!indentation_.empty()) *sout_ <<
" ";
1019 bool BuiltStyledStreamWriter::isMultineArray(
Value const& value) {
1021 bool isMultiLine = size * 3 >= rightMargin_;
1022 childValues_.clear();
1023 for (
ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
1024 Value const& childValue = value[index];
1026 childValue.
size() > 0);
1030 childValues_.reserve(size);
1031 addChildValues_ =
true;
1033 for (
ArrayIndex index = 0; index < size; ++index) {
1034 if (hasCommentForValue(value[index])) {
1037 writeValue(value[index]);
1038 lineLength +=
static_cast<ArrayIndex>(childValues_[index].length());
1040 addChildValues_ =
false;
1041 isMultiLine = isMultiLine || lineLength >= rightMargin_;
1046 void BuiltStyledStreamWriter::pushValue(
JSONCPP_STRING const& value) {
1047 if (addChildValues_)
1048 childValues_.push_back(value);
1053 void BuiltStyledStreamWriter::writeIndent() {
1059 if (!indentation_.empty()) {
1061 *sout_ <<
'\n' << indentString_;
1065 void BuiltStyledStreamWriter::writeWithIndent(
JSONCPP_STRING const& value) {
1066 if (!indented_) writeIndent();
1071 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
1073 void BuiltStyledStreamWriter::unindent() {
1074 assert(indentString_.size() >= indentation_.size());
1075 indentString_.resize(indentString_.size() - indentation_.size());
1078 void BuiltStyledStreamWriter::writeCommentBeforeValue(
Value const& root) {
1079 if (cs_ == CommentStyle::None)
return;
1083 if (!indented_) writeIndent();
1085 JSONCPP_STRING::const_iterator iter = comment.begin();
1086 while (iter != comment.end()) {
1088 if (*iter ==
'\n' &&
1089 (iter != comment.end() && *(iter + 1) ==
'/'))
1091 *sout_ << indentString_;
1097 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(
Value const& root) {
1098 if (cs_ == CommentStyle::None)
return;
1109 bool BuiltStyledStreamWriter::hasCommentForValue(
const Value& value) {
1129 setDefaults(&settings_);
1135 JSONCPP_STRING indentation = settings_[
"indentation"].asString();
1137 bool eyc = settings_[
"enableYAMLCompatibility"].asBool();
1138 bool dnp = settings_[
"dropNullPlaceholders"].asBool();
1139 bool usf = settings_[
"useSpecialFloats"].asBool();
1140 unsigned int pre = settings_[
"precision"].asUInt();
1141 CommentStyle::Enum cs = CommentStyle::All;
1142 if (cs_str ==
"All") {
1143 cs = CommentStyle::All;
1144 }
else if (cs_str ==
"None") {
1145 cs = CommentStyle::None;
1147 throwRuntimeError(
"commentStyle must be 'All' or 'None'");
1152 }
else if (indentation.empty()) {
1159 if (pre > 17) pre = 17;
1161 return new BuiltStyledStreamWriter(
1163 colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
1167 valid_keys->clear();
1168 valid_keys->insert(
"indentation");
1169 valid_keys->insert(
"commentStyle");
1170 valid_keys->insert(
"enableYAMLCompatibility");
1171 valid_keys->insert(
"dropNullPlaceholders");
1172 valid_keys->insert(
"useSpecialFloats");
1173 valid_keys->insert(
"precision");
1178 if (!invalid) invalid = &my_invalid;
1180 std::set<JSONCPP_STRING> valid_keys;
1183 size_t n = keys.size();
1184 for (
size_t i = 0; i < n; ++i) {
1186 if (valid_keys.find(key) == valid_keys.end()) {
1187 inv[key] = settings_[key];
1190 return 0u == inv.
size();
1194 return settings_[key];
1200 (*settings)[
"commentStyle"] =
"All";
1201 (*settings)[
"indentation"] =
"\t";
1202 (*settings)[
"enableYAMLCompatibility"] =
false;
1203 (*settings)[
"dropNullPlaceholders"] =
false;
1204 (*settings)[
"useSpecialFloats"] =
false;
1205 (*settings)[
"precision"] = 17;
1212 writer->write(root, &sout);
1219 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.