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.