Home | History | Annotate | Download | only in dist
      1 /// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).
      2 /// It is intended to be used with #include "json/json.h"
      3 
      4 // //////////////////////////////////////////////////////////////////////
      5 // Beginning of content of file: LICENSE
      6 // //////////////////////////////////////////////////////////////////////
      7 
      8 /*
      9 The JsonCpp library's source code, including accompanying documentation,
     10 tests and demonstration applications, are licensed under the following
     11 conditions...
     12 
     13 The author (Baptiste Lepilleur) explicitly disclaims copyright in all
     14 jurisdictions which recognize such a disclaimer. In such jurisdictions,
     15 this software is released into the Public Domain.
     16 
     17 In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
     18 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
     19 released under the terms of the MIT License (see below).
     20 
     21 In jurisdictions which recognize Public Domain property, the user of this
     22 software may choose to accept it either as 1) Public Domain, 2) under the
     23 conditions of the MIT License (see below), or 3) under the terms of dual
     24 Public Domain/MIT License conditions described here, as they choose.
     25 
     26 The MIT License is about as close to Public Domain as a license can get, and is
     27 described in clear, concise terms at:
     28 
     29    http://en.wikipedia.org/wiki/MIT_License
     30 
     31 The full text of the MIT License follows:
     32 
     33 ========================================================================
     34 Copyright (c) 2007-2010 Baptiste Lepilleur
     35 
     36 Permission is hereby granted, free of charge, to any person
     37 obtaining a copy of this software and associated documentation
     38 files (the "Software"), to deal in the Software without
     39 restriction, including without limitation the rights to use, copy,
     40 modify, merge, publish, distribute, sublicense, and/or sell copies
     41 of the Software, and to permit persons to whom the Software is
     42 furnished to do so, subject to the following conditions:
     43 
     44 The above copyright notice and this permission notice shall be
     45 included in all copies or substantial portions of the Software.
     46 
     47 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     48 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     49 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     50 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     51 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     52 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     53 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     54 SOFTWARE.
     55 ========================================================================
     56 (END LICENSE TEXT)
     57 
     58 The MIT license is compatible with both the GPL and commercial
     59 software, affording one all of the rights of Public Domain with the
     60 minor nuisance of being required to keep the above copyright notice
     61 and license text in the source code. Note also that by accepting the
     62 Public Domain "license" you can re-license your copy using whatever
     63 license you like.
     64 
     65 */
     66 
     67 // //////////////////////////////////////////////////////////////////////
     68 // End of content of file: LICENSE
     69 // //////////////////////////////////////////////////////////////////////
     70 
     71 
     72 
     73 
     74 
     75 
     76 #include "json/json.h"
     77 
     78 #ifndef JSON_IS_AMALGAMATION
     79 #error "Compile with -I PATH_TO_JSON_DIRECTORY"
     80 #endif
     81 
     82 
     83 // //////////////////////////////////////////////////////////////////////
     84 // Beginning of content of file: src/lib_json/json_tool.h
     85 // //////////////////////////////////////////////////////////////////////
     86 
     87 // Copyright 2007-2010 Baptiste Lepilleur
     88 // Distributed under MIT license, or public domain if desired and
     89 // recognized in your jurisdiction.
     90 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
     91 
     92 #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
     93 #define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
     94 
     95 /* This header provides common string manipulation support, such as UTF-8,
     96  * portable conversion from/to string...
     97  *
     98  * It is an internal header that must not be exposed.
     99  */
    100 
    101 namespace Json {
    102 
    103 /// Converts a unicode code-point to UTF-8.
    104 static inline std::string codePointToUTF8(unsigned int cp) {
    105   std::string result;
    106 
    107   // based on description from http://en.wikipedia.org/wiki/UTF-8
    108 
    109   if (cp <= 0x7f) {
    110     result.resize(1);
    111     result[0] = static_cast<char>(cp);
    112   } else if (cp <= 0x7FF) {
    113     result.resize(2);
    114     result[1] = static_cast<char>(0x80 | (0x3f & cp));
    115     result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
    116   } else if (cp <= 0xFFFF) {
    117     result.resize(3);
    118     result[2] = static_cast<char>(0x80 | (0x3f & cp));
    119     result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6)));
    120     result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12)));
    121   } else if (cp <= 0x10FFFF) {
    122     result.resize(4);
    123     result[3] = static_cast<char>(0x80 | (0x3f & cp));
    124     result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
    125     result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
    126     result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
    127   }
    128 
    129   return result;
    130 }
    131 
    132 /// Returns true if ch is a control character (in range [0,32[).
    133 static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; }
    134 
    135 enum {
    136   /// Constant that specify the size of the buffer that must be passed to
    137   /// uintToString.
    138   uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1
    139 };
    140 
    141 // Defines a char buffer for use with uintToString().
    142 typedef char UIntToStringBuffer[uintToStringBufferSize];
    143 
    144 /** Converts an unsigned integer to string.
    145  * @param value Unsigned interger to convert to string
    146  * @param current Input/Output string buffer.
    147  *        Must have at least uintToStringBufferSize chars free.
    148  */
    149 static inline void uintToString(LargestUInt value, char*& current) {
    150   *--current = 0;
    151   do {
    152     *--current = char(value % 10) + '0';
    153     value /= 10;
    154   } while (value != 0);
    155 }
    156 
    157 /** Change ',' to '.' everywhere in buffer.
    158  *
    159  * We had a sophisticated way, but it did not work in WinCE.
    160  * @see https://github.com/open-source-parsers/jsoncpp/pull/9
    161  */
    162 static inline void fixNumericLocale(char* begin, char* end) {
    163   while (begin < end) {
    164     if (*begin == ',') {
    165       *begin = '.';
    166     }
    167     ++begin;
    168   }
    169 }
    170 
    171 } // namespace Json {
    172 
    173 #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
    174 
    175 // //////////////////////////////////////////////////////////////////////
    176 // End of content of file: src/lib_json/json_tool.h
    177 // //////////////////////////////////////////////////////////////////////
    178 
    179 
    180 
    181 
    182 
    183 
    184 // //////////////////////////////////////////////////////////////////////
    185 // Beginning of content of file: src/lib_json/json_reader.cpp
    186 // //////////////////////////////////////////////////////////////////////
    187 
    188 // Copyright 2007-2011 Baptiste Lepilleur
    189 // Distributed under MIT license, or public domain if desired and
    190 // recognized in your jurisdiction.
    191 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
    192 
    193 #if !defined(JSON_IS_AMALGAMATION)
    194 #include <json/assertions.h>
    195 #include <json/reader.h>
    196 #include <json/value.h>
    197 #include "json_tool.h"
    198 #endif // if !defined(JSON_IS_AMALGAMATION)
    199 #include <utility>
    200 #include <cstdio>
    201 #include <cassert>
    202 #include <cstring>
    203 #include <istream>
    204 #include <sstream>
    205 #include <memory>
    206 #include <set>
    207 
    208 #if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
    209 #define snprintf _snprintf
    210 #endif
    211 
    212 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
    213 // Disable warning about strdup being deprecated.
    214 #pragma warning(disable : 4996)
    215 #endif
    216 
    217 static int const stackLimit_g = 1000;
    218 static int       stackDepth_g = 0;  // see readValue()
    219 
    220 namespace Json {
    221 
    222 #if __cplusplus >= 201103L
    223 typedef std::unique_ptr<CharReader> CharReaderPtr;
    224 #else
    225 typedef std::auto_ptr<CharReader>   CharReaderPtr;
    226 #endif
    227 
    228 // Implementation of class Features
    229 // ////////////////////////////////
    230 
    231 Features::Features()
    232     : allowComments_(true), strictRoot_(false),
    233       allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}
    234 
    235 Features Features::all() { return Features(); }
    236 
    237 Features Features::strictMode() {
    238   Features features;
    239   features.allowComments_ = false;
    240   features.strictRoot_ = true;
    241   features.allowDroppedNullPlaceholders_ = false;
    242   features.allowNumericKeys_ = false;
    243   return features;
    244 }
    245 
    246 // Implementation of class Reader
    247 // ////////////////////////////////
    248 
    249 static bool containsNewLine(Reader::Location begin, Reader::Location end) {
    250   for (; begin < end; ++begin)
    251     if (*begin == '\n' || *begin == '\r')
    252       return true;
    253   return false;
    254 }
    255 
    256 // Class Reader
    257 // //////////////////////////////////////////////////////////////////
    258 
    259 Reader::Reader()
    260     : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
    261       lastValue_(), commentsBefore_(), features_(Features::all()),
    262       collectComments_() {}
    263 
    264 Reader::Reader(const Features& features)
    265     : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
    266       lastValue_(), commentsBefore_(), features_(features), collectComments_() {
    267 }
    268 
    269 bool
    270 Reader::parse(const std::string& document, Value& root, bool collectComments) {
    271   document_ = document;
    272   const char* begin = document_.c_str();
    273   const char* end = begin + document_.length();
    274   return parse(begin, end, root, collectComments);
    275 }
    276 
    277 bool Reader::parse(std::istream& sin, Value& root, bool collectComments) {
    278   // std::istream_iterator<char> begin(sin);
    279   // std::istream_iterator<char> end;
    280   // Those would allow streamed input from a file, if parse() were a
    281   // template function.
    282 
    283   // Since std::string is reference-counted, this at least does not
    284   // create an extra copy.
    285   std::string doc;
    286   std::getline(sin, doc, (char)EOF);
    287   return parse(doc, root, collectComments);
    288 }
    289 
    290 bool Reader::parse(const char* beginDoc,
    291                    const char* endDoc,
    292                    Value& root,
    293                    bool collectComments) {
    294   if (!features_.allowComments_) {
    295     collectComments = false;
    296   }
    297 
    298   begin_ = beginDoc;
    299   end_ = endDoc;
    300   collectComments_ = collectComments;
    301   current_ = begin_;
    302   lastValueEnd_ = 0;
    303   lastValue_ = 0;
    304   commentsBefore_ = "";
    305   errors_.clear();
    306   while (!nodes_.empty())
    307     nodes_.pop();
    308   nodes_.push(&root);
    309 
    310   stackDepth_g = 0;  // Yes, this is bad coding, but options are limited.
    311   bool successful = readValue();
    312   Token token;
    313   skipCommentTokens(token);
    314   if (collectComments_ && !commentsBefore_.empty())
    315     root.setComment(commentsBefore_, commentAfter);
    316   if (features_.strictRoot_) {
    317     if (!root.isArray() && !root.isObject()) {
    318       // Set error location to start of doc, ideally should be first token found
    319       // in doc
    320       token.type_ = tokenError;
    321       token.start_ = beginDoc;
    322       token.end_ = endDoc;
    323       addError(
    324           "A valid JSON document must be either an array or an object value.",
    325           token);
    326       return false;
    327     }
    328   }
    329   return successful;
    330 }
    331 
    332 bool Reader::readValue() {
    333   // This is a non-reentrant way to support a stackLimit. Terrible!
    334   // But this deprecated class has a security problem: Bad input can
    335   // cause a seg-fault. This seems like a fair, binary-compatible way
    336   // to prevent the problem.
    337   if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
    338   ++stackDepth_g;
    339 
    340   Token token;
    341   skipCommentTokens(token);
    342   bool successful = true;
    343 
    344   if (collectComments_ && !commentsBefore_.empty()) {
    345     currentValue().setComment(commentsBefore_, commentBefore);
    346     commentsBefore_ = "";
    347   }
    348 
    349   switch (token.type_) {
    350   case tokenObjectBegin:
    351     successful = readObject(token);
    352     currentValue().setOffsetLimit(current_ - begin_);
    353     break;
    354   case tokenArrayBegin:
    355     successful = readArray(token);
    356     currentValue().setOffsetLimit(current_ - begin_);
    357     break;
    358   case tokenNumber:
    359     successful = decodeNumber(token);
    360     break;
    361   case tokenString:
    362     successful = decodeString(token);
    363     break;
    364   case tokenTrue:
    365     {
    366     Value v(true);
    367     currentValue().swapPayload(v);
    368     currentValue().setOffsetStart(token.start_ - begin_);
    369     currentValue().setOffsetLimit(token.end_ - begin_);
    370     }
    371     break;
    372   case tokenFalse:
    373     {
    374     Value v(false);
    375     currentValue().swapPayload(v);
    376     currentValue().setOffsetStart(token.start_ - begin_);
    377     currentValue().setOffsetLimit(token.end_ - begin_);
    378     }
    379     break;
    380   case tokenNull:
    381     {
    382     Value v;
    383     currentValue().swapPayload(v);
    384     currentValue().setOffsetStart(token.start_ - begin_);
    385     currentValue().setOffsetLimit(token.end_ - begin_);
    386     }
    387     break;
    388   case tokenArraySeparator:
    389   case tokenObjectEnd:
    390   case tokenArrayEnd:
    391     if (features_.allowDroppedNullPlaceholders_) {
    392       // "Un-read" the current token and mark the current value as a null
    393       // token.
    394       current_--;
    395       Value v;
    396       currentValue().swapPayload(v);
    397       currentValue().setOffsetStart(current_ - begin_ - 1);
    398       currentValue().setOffsetLimit(current_ - begin_);
    399       break;
    400     } // Else, fall through...
    401   default:
    402     currentValue().setOffsetStart(token.start_ - begin_);
    403     currentValue().setOffsetLimit(token.end_ - begin_);
    404     return addError("Syntax error: value, object or array expected.", token);
    405   }
    406 
    407   if (collectComments_) {
    408     lastValueEnd_ = current_;
    409     lastValue_ = &currentValue();
    410   }
    411 
    412   --stackDepth_g;
    413   return successful;
    414 }
    415 
    416 void Reader::skipCommentTokens(Token& token) {
    417   if (features_.allowComments_) {
    418     do {
    419       readToken(token);
    420     } while (token.type_ == tokenComment);
    421   } else {
    422     readToken(token);
    423   }
    424 }
    425 
    426 bool Reader::readToken(Token& token) {
    427   skipSpaces();
    428   token.start_ = current_;
    429   Char c = getNextChar();
    430   bool ok = true;
    431   switch (c) {
    432   case '{':
    433     token.type_ = tokenObjectBegin;
    434     break;
    435   case '}':
    436     token.type_ = tokenObjectEnd;
    437     break;
    438   case '[':
    439     token.type_ = tokenArrayBegin;
    440     break;
    441   case ']':
    442     token.type_ = tokenArrayEnd;
    443     break;
    444   case '"':
    445     token.type_ = tokenString;
    446     ok = readString();
    447     break;
    448   case '/':
    449     token.type_ = tokenComment;
    450     ok = readComment();
    451     break;
    452   case '0':
    453   case '1':
    454   case '2':
    455   case '3':
    456   case '4':
    457   case '5':
    458   case '6':
    459   case '7':
    460   case '8':
    461   case '9':
    462   case '-':
    463     token.type_ = tokenNumber;
    464     readNumber();
    465     break;
    466   case 't':
    467     token.type_ = tokenTrue;
    468     ok = match("rue", 3);
    469     break;
    470   case 'f':
    471     token.type_ = tokenFalse;
    472     ok = match("alse", 4);
    473     break;
    474   case 'n':
    475     token.type_ = tokenNull;
    476     ok = match("ull", 3);
    477     break;
    478   case ',':
    479     token.type_ = tokenArraySeparator;
    480     break;
    481   case ':':
    482     token.type_ = tokenMemberSeparator;
    483     break;
    484   case 0:
    485     token.type_ = tokenEndOfStream;
    486     break;
    487   default:
    488     ok = false;
    489     break;
    490   }
    491   if (!ok)
    492     token.type_ = tokenError;
    493   token.end_ = current_;
    494   return true;
    495 }
    496 
    497 void Reader::skipSpaces() {
    498   while (current_ != end_) {
    499     Char c = *current_;
    500     if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
    501       ++current_;
    502     else
    503       break;
    504   }
    505 }
    506 
    507 bool Reader::match(Location pattern, int patternLength) {
    508   if (end_ - current_ < patternLength)
    509     return false;
    510   int index = patternLength;
    511   while (index--)
    512     if (current_[index] != pattern[index])
    513       return false;
    514   current_ += patternLength;
    515   return true;
    516 }
    517 
    518 bool Reader::readComment() {
    519   Location commentBegin = current_ - 1;
    520   Char c = getNextChar();
    521   bool successful = false;
    522   if (c == '*')
    523     successful = readCStyleComment();
    524   else if (c == '/')
    525     successful = readCppStyleComment();
    526   if (!successful)
    527     return false;
    528 
    529   if (collectComments_) {
    530     CommentPlacement placement = commentBefore;
    531     if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
    532       if (c != '*' || !containsNewLine(commentBegin, current_))
    533         placement = commentAfterOnSameLine;
    534     }
    535 
    536     addComment(commentBegin, current_, placement);
    537   }
    538   return true;
    539 }
    540 
    541 static std::string normalizeEOL(Reader::Location begin, Reader::Location end) {
    542   std::string normalized;
    543   normalized.reserve(end - begin);
    544   Reader::Location current = begin;
    545   while (current != end) {
    546     char c = *current++;
    547     if (c == '\r') {
    548       if (current != end && *current == '\n')
    549          // convert dos EOL
    550          ++current;
    551       // convert Mac EOL
    552       normalized += '\n';
    553     } else {
    554       normalized += c;
    555     }
    556   }
    557   return normalized;
    558 }
    559 
    560 void
    561 Reader::addComment(Location begin, Location end, CommentPlacement placement) {
    562   assert(collectComments_);
    563   const std::string& normalized = normalizeEOL(begin, end);
    564   if (placement == commentAfterOnSameLine) {
    565     assert(lastValue_ != 0);
    566     lastValue_->setComment(normalized, placement);
    567   } else {
    568     commentsBefore_ += normalized;
    569   }
    570 }
    571 
    572 bool Reader::readCStyleComment() {
    573   while (current_ != end_) {
    574     Char c = getNextChar();
    575     if (c == '*' && *current_ == '/')
    576       break;
    577   }
    578   return getNextChar() == '/';
    579 }
    580 
    581 bool Reader::readCppStyleComment() {
    582   while (current_ != end_) {
    583     Char c = getNextChar();
    584     if (c == '\n')
    585       break;
    586     if (c == '\r') {
    587       // Consume DOS EOL. It will be normalized in addComment.
    588       if (current_ != end_ && *current_ == '\n')
    589         getNextChar();
    590       // Break on Moc OS 9 EOL.
    591       break;
    592     }
    593   }
    594   return true;
    595 }
    596 
    597 void Reader::readNumber() {
    598   const char *p = current_;
    599   char c = '0'; // stopgap for already consumed character
    600   // integral part
    601   while (c >= '0' && c <= '9')
    602     c = (current_ = p) < end_ ? *p++ : 0;
    603   // fractional part
    604   if (c == '.') {
    605     c = (current_ = p) < end_ ? *p++ : 0;
    606     while (c >= '0' && c <= '9')
    607       c = (current_ = p) < end_ ? *p++ : 0;
    608   }
    609   // exponential part
    610   if (c == 'e' || c == 'E') {
    611     c = (current_ = p) < end_ ? *p++ : 0;
    612     if (c == '+' || c == '-')
    613       c = (current_ = p) < end_ ? *p++ : 0;
    614     while (c >= '0' && c <= '9')
    615       c = (current_ = p) < end_ ? *p++ : 0;
    616   }
    617 }
    618 
    619 bool Reader::readString() {
    620   Char c = 0;
    621   while (current_ != end_) {
    622     c = getNextChar();
    623     if (c == '\\')
    624       getNextChar();
    625     else if (c == '"')
    626       break;
    627   }
    628   return c == '"';
    629 }
    630 
    631 bool Reader::readObject(Token& tokenStart) {
    632   Token tokenName;
    633   std::string name;
    634   Value init(objectValue);
    635   currentValue().swapPayload(init);
    636   currentValue().setOffsetStart(tokenStart.start_ - begin_);
    637   while (readToken(tokenName)) {
    638     bool initialTokenOk = true;
    639     while (tokenName.type_ == tokenComment && initialTokenOk)
    640       initialTokenOk = readToken(tokenName);
    641     if (!initialTokenOk)
    642       break;
    643     if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
    644       return true;
    645     name = "";
    646     if (tokenName.type_ == tokenString) {
    647       if (!decodeString(tokenName, name))
    648         return recoverFromError(tokenObjectEnd);
    649     } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
    650       Value numberName;
    651       if (!decodeNumber(tokenName, numberName))
    652         return recoverFromError(tokenObjectEnd);
    653       name = numberName.asString();
    654     } else {
    655       break;
    656     }
    657 
    658     Token colon;
    659     if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
    660       return addErrorAndRecover(
    661           "Missing ':' after object member name", colon, tokenObjectEnd);
    662     }
    663     Value& value = currentValue()[name];
    664     nodes_.push(&value);
    665     bool ok = readValue();
    666     nodes_.pop();
    667     if (!ok) // error already set
    668       return recoverFromError(tokenObjectEnd);
    669 
    670     Token comma;
    671     if (!readToken(comma) ||
    672         (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
    673          comma.type_ != tokenComment)) {
    674       return addErrorAndRecover(
    675           "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
    676     }
    677     bool finalizeTokenOk = true;
    678     while (comma.type_ == tokenComment && finalizeTokenOk)
    679       finalizeTokenOk = readToken(comma);
    680     if (comma.type_ == tokenObjectEnd)
    681       return true;
    682   }
    683   return addErrorAndRecover(
    684       "Missing '}' or object member name", tokenName, tokenObjectEnd);
    685 }
    686 
    687 bool Reader::readArray(Token& tokenStart) {
    688   Value init(arrayValue);
    689   currentValue().swapPayload(init);
    690   currentValue().setOffsetStart(tokenStart.start_ - begin_);
    691   skipSpaces();
    692   if (*current_ == ']') // empty array
    693   {
    694     Token endArray;
    695     readToken(endArray);
    696     return true;
    697   }
    698   int index = 0;
    699   for (;;) {
    700     Value& value = currentValue()[index++];
    701     nodes_.push(&value);
    702     bool ok = readValue();
    703     nodes_.pop();
    704     if (!ok) // error already set
    705       return recoverFromError(tokenArrayEnd);
    706 
    707     Token token;
    708     // Accept Comment after last item in the array.
    709     ok = readToken(token);
    710     while (token.type_ == tokenComment && ok) {
    711       ok = readToken(token);
    712     }
    713     bool badTokenType =
    714         (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
    715     if (!ok || badTokenType) {
    716       return addErrorAndRecover(
    717           "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
    718     }
    719     if (token.type_ == tokenArrayEnd)
    720       break;
    721   }
    722   return true;
    723 }
    724 
    725 bool Reader::decodeNumber(Token& token) {
    726   Value decoded;
    727   if (!decodeNumber(token, decoded))
    728     return false;
    729   currentValue().swapPayload(decoded);
    730   currentValue().setOffsetStart(token.start_ - begin_);
    731   currentValue().setOffsetLimit(token.end_ - begin_);
    732   return true;
    733 }
    734 
    735 bool Reader::decodeNumber(Token& token, Value& decoded) {
    736   // Attempts to parse the number as an integer. If the number is
    737   // larger than the maximum supported value of an integer then
    738   // we decode the number as a double.
    739   Location current = token.start_;
    740   bool isNegative = *current == '-';
    741   if (isNegative)
    742     ++current;
    743   // TODO: Help the compiler do the div and mod at compile time or get rid of them.
    744   Value::LargestUInt maxIntegerValue =
    745       isNegative ? Value::LargestUInt(-Value::minLargestInt)
    746                  : Value::maxLargestUInt;
    747   Value::LargestUInt threshold = maxIntegerValue / 10;
    748   Value::LargestUInt value = 0;
    749   while (current < token.end_) {
    750     Char c = *current++;
    751     if (c < '0' || c > '9')
    752       return decodeDouble(token, decoded);
    753     Value::UInt digit(c - '0');
    754     if (value >= threshold) {
    755       // We've hit or exceeded the max value divided by 10 (rounded down). If
    756       // a) we've only just touched the limit, b) this is the last digit, and
    757       // c) it's small enough to fit in that rounding delta, we're okay.
    758       // Otherwise treat this number as a double to avoid overflow.
    759       if (value > threshold || current != token.end_ ||
    760           digit > maxIntegerValue % 10) {
    761         return decodeDouble(token, decoded);
    762       }
    763     }
    764     value = value * 10 + digit;
    765   }
    766   if (isNegative)
    767     decoded = -Value::LargestInt(value);
    768   else if (value <= Value::LargestUInt(Value::maxInt))
    769     decoded = Value::LargestInt(value);
    770   else
    771     decoded = value;
    772   return true;
    773 }
    774 
    775 bool Reader::decodeDouble(Token& token) {
    776   Value decoded;
    777   if (!decodeDouble(token, decoded))
    778     return false;
    779   currentValue().swapPayload(decoded);
    780   currentValue().setOffsetStart(token.start_ - begin_);
    781   currentValue().setOffsetLimit(token.end_ - begin_);
    782   return true;
    783 }
    784 
    785 bool Reader::decodeDouble(Token& token, Value& decoded) {
    786   double value = 0;
    787   const int bufferSize = 32;
    788   int count;
    789   int length = int(token.end_ - token.start_);
    790 
    791   // Sanity check to avoid buffer overflow exploits.
    792   if (length < 0) {
    793     return addError("Unable to parse token length", token);
    794   }
    795 
    796   // Avoid using a string constant for the format control string given to
    797   // sscanf, as this can cause hard to debug crashes on OS X. See here for more
    798   // info:
    799   //
    800   //     http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
    801   char format[] = "%lf";
    802 
    803   if (length <= bufferSize) {
    804     Char buffer[bufferSize + 1];
    805     memcpy(buffer, token.start_, length);
    806     buffer[length] = 0;
    807     count = sscanf(buffer, format, &value);
    808   } else {
    809     std::string buffer(token.start_, token.end_);
    810     count = sscanf(buffer.c_str(), format, &value);
    811   }
    812 
    813   if (count != 1)
    814     return addError("'" + std::string(token.start_, token.end_) +
    815                         "' is not a number.",
    816                     token);
    817   decoded = value;
    818   return true;
    819 }
    820 
    821 bool Reader::decodeString(Token& token) {
    822   std::string decoded_string;
    823   if (!decodeString(token, decoded_string))
    824     return false;
    825   Value decoded(decoded_string);
    826   currentValue().swapPayload(decoded);
    827   currentValue().setOffsetStart(token.start_ - begin_);
    828   currentValue().setOffsetLimit(token.end_ - begin_);
    829   return true;
    830 }
    831 
    832 bool Reader::decodeString(Token& token, std::string& decoded) {
    833   decoded.reserve(token.end_ - token.start_ - 2);
    834   Location current = token.start_ + 1; // skip '"'
    835   Location end = token.end_ - 1;       // do not include '"'
    836   while (current != end) {
    837     Char c = *current++;
    838     if (c == '"')
    839       break;
    840     else if (c == '\\') {
    841       if (current == end)
    842         return addError("Empty escape sequence in string", token, current);
    843       Char escape = *current++;
    844       switch (escape) {
    845       case '"':
    846         decoded += '"';
    847         break;
    848       case '/':
    849         decoded += '/';
    850         break;
    851       case '\\':
    852         decoded += '\\';
    853         break;
    854       case 'b':
    855         decoded += '\b';
    856         break;
    857       case 'f':
    858         decoded += '\f';
    859         break;
    860       case 'n':
    861         decoded += '\n';
    862         break;
    863       case 'r':
    864         decoded += '\r';
    865         break;
    866       case 't':
    867         decoded += '\t';
    868         break;
    869       case 'u': {
    870         unsigned int unicode;
    871         if (!decodeUnicodeCodePoint(token, current, end, unicode))
    872           return false;
    873         decoded += codePointToUTF8(unicode);
    874       } break;
    875       default:
    876         return addError("Bad escape sequence in string", token, current);
    877       }
    878     } else {
    879       decoded += c;
    880     }
    881   }
    882   return true;
    883 }
    884 
    885 bool Reader::decodeUnicodeCodePoint(Token& token,
    886                                     Location& current,
    887                                     Location end,
    888                                     unsigned int& unicode) {
    889 
    890   if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
    891     return false;
    892   if (unicode >= 0xD800 && unicode <= 0xDBFF) {
    893     // surrogate pairs
    894     if (end - current < 6)
    895       return addError(
    896           "additional six characters expected to parse unicode surrogate pair.",
    897           token,
    898           current);
    899     unsigned int surrogatePair;
    900     if (*(current++) == '\\' && *(current++) == 'u') {
    901       if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
    902         unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
    903       } else
    904         return false;
    905     } else
    906       return addError("expecting another \\u token to begin the second half of "
    907                       "a unicode surrogate pair",
    908                       token,
    909                       current);
    910   }
    911   return true;
    912 }
    913 
    914 bool Reader::decodeUnicodeEscapeSequence(Token& token,
    915                                          Location& current,
    916                                          Location end,
    917                                          unsigned int& unicode) {
    918   if (end - current < 4)
    919     return addError(
    920         "Bad unicode escape sequence in string: four digits expected.",
    921         token,
    922         current);
    923   unicode = 0;
    924   for (int index = 0; index < 4; ++index) {
    925     Char c = *current++;
    926     unicode *= 16;
    927     if (c >= '0' && c <= '9')
    928       unicode += c - '0';
    929     else if (c >= 'a' && c <= 'f')
    930       unicode += c - 'a' + 10;
    931     else if (c >= 'A' && c <= 'F')
    932       unicode += c - 'A' + 10;
    933     else
    934       return addError(
    935           "Bad unicode escape sequence in string: hexadecimal digit expected.",
    936           token,
    937           current);
    938   }
    939   return true;
    940 }
    941 
    942 bool
    943 Reader::addError(const std::string& message, Token& token, Location extra) {
    944   ErrorInfo info;
    945   info.token_ = token;
    946   info.message_ = message;
    947   info.extra_ = extra;
    948   errors_.push_back(info);
    949   return false;
    950 }
    951 
    952 bool Reader::recoverFromError(TokenType skipUntilToken) {
    953   int errorCount = int(errors_.size());
    954   Token skip;
    955   for (;;) {
    956     if (!readToken(skip))
    957       errors_.resize(errorCount); // discard errors caused by recovery
    958     if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
    959       break;
    960   }
    961   errors_.resize(errorCount);
    962   return false;
    963 }
    964 
    965 bool Reader::addErrorAndRecover(const std::string& message,
    966                                 Token& token,
    967                                 TokenType skipUntilToken) {
    968   addError(message, token);
    969   return recoverFromError(skipUntilToken);
    970 }
    971 
    972 Value& Reader::currentValue() { return *(nodes_.top()); }
    973 
    974 Reader::Char Reader::getNextChar() {
    975   if (current_ == end_)
    976     return 0;
    977   return *current_++;
    978 }
    979 
    980 void Reader::getLocationLineAndColumn(Location location,
    981                                       int& line,
    982                                       int& column) const {
    983   Location current = begin_;
    984   Location lastLineStart = current;
    985   line = 0;
    986   while (current < location && current != end_) {
    987     Char c = *current++;
    988     if (c == '\r') {
    989       if (*current == '\n')
    990         ++current;
    991       lastLineStart = current;
    992       ++line;
    993     } else if (c == '\n') {
    994       lastLineStart = current;
    995       ++line;
    996     }
    997   }
    998   // column & line start at 1
    999   column = int(location - lastLineStart) + 1;
   1000   ++line;
   1001 }
   1002 
   1003 std::string Reader::getLocationLineAndColumn(Location location) const {
   1004   int line, column;
   1005   getLocationLineAndColumn(location, line, column);
   1006   char buffer[18 + 16 + 16 + 1];
   1007 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
   1008 #if defined(WINCE)
   1009   _snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
   1010 #else
   1011   sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
   1012 #endif
   1013 #else
   1014   snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
   1015 #endif
   1016   return buffer;
   1017 }
   1018 
   1019 // Deprecated. Preserved for backward compatibility
   1020 std::string Reader::getFormatedErrorMessages() const {
   1021   return getFormattedErrorMessages();
   1022 }
   1023 
   1024 std::string Reader::getFormattedErrorMessages() const {
   1025   std::string formattedMessage;
   1026   for (Errors::const_iterator itError = errors_.begin();
   1027        itError != errors_.end();
   1028        ++itError) {
   1029     const ErrorInfo& error = *itError;
   1030     formattedMessage +=
   1031         "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
   1032     formattedMessage += "  " + error.message_ + "\n";
   1033     if (error.extra_)
   1034       formattedMessage +=
   1035           "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
   1036   }
   1037   return formattedMessage;
   1038 }
   1039 
   1040 std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
   1041   std::vector<Reader::StructuredError> allErrors;
   1042   for (Errors::const_iterator itError = errors_.begin();
   1043        itError != errors_.end();
   1044        ++itError) {
   1045     const ErrorInfo& error = *itError;
   1046     Reader::StructuredError structured;
   1047     structured.offset_start = error.token_.start_ - begin_;
   1048     structured.offset_limit = error.token_.end_ - begin_;
   1049     structured.message = error.message_;
   1050     allErrors.push_back(structured);
   1051   }
   1052   return allErrors;
   1053 }
   1054 
   1055 bool Reader::pushError(const Value& value, const std::string& message) {
   1056   size_t length = end_ - begin_;
   1057   if(value.getOffsetStart() > length
   1058     || value.getOffsetLimit() > length)
   1059     return false;
   1060   Token token;
   1061   token.type_ = tokenError;
   1062   token.start_ = begin_ + value.getOffsetStart();
   1063   token.end_ = end_ + value.getOffsetLimit();
   1064   ErrorInfo info;
   1065   info.token_ = token;
   1066   info.message_ = message;
   1067   info.extra_ = 0;
   1068   errors_.push_back(info);
   1069   return true;
   1070 }
   1071 
   1072 bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) {
   1073   size_t length = end_ - begin_;
   1074   if(value.getOffsetStart() > length
   1075     || value.getOffsetLimit() > length
   1076     || extra.getOffsetLimit() > length)
   1077     return false;
   1078   Token token;
   1079   token.type_ = tokenError;
   1080   token.start_ = begin_ + value.getOffsetStart();
   1081   token.end_ = begin_ + value.getOffsetLimit();
   1082   ErrorInfo info;
   1083   info.token_ = token;
   1084   info.message_ = message;
   1085   info.extra_ = begin_ + extra.getOffsetStart();
   1086   errors_.push_back(info);
   1087   return true;
   1088 }
   1089 
   1090 bool Reader::good() const {
   1091   return !errors_.size();
   1092 }
   1093 
   1094 // exact copy of Features
   1095 class OurFeatures {
   1096 public:
   1097   static OurFeatures all();
   1098   OurFeatures();
   1099   bool allowComments_;
   1100   bool strictRoot_;
   1101   bool allowDroppedNullPlaceholders_;
   1102   bool allowNumericKeys_;
   1103   bool allowSingleQuotes_;
   1104   bool failIfExtra_;
   1105   bool rejectDupKeys_;
   1106   int stackLimit_;
   1107 };  // OurFeatures
   1108 
   1109 // exact copy of Implementation of class Features
   1110 // ////////////////////////////////
   1111 
   1112 OurFeatures::OurFeatures()
   1113     : allowComments_(true), strictRoot_(false)
   1114     , allowDroppedNullPlaceholders_(false), allowNumericKeys_(false)
   1115     , allowSingleQuotes_(false)
   1116     , failIfExtra_(false)
   1117 {
   1118 }
   1119 
   1120 OurFeatures OurFeatures::all() { return OurFeatures(); }
   1121 
   1122 // Implementation of class Reader
   1123 // ////////////////////////////////
   1124 
   1125 // exact copy of Reader, renamed to OurReader
   1126 class OurReader {
   1127 public:
   1128   typedef char Char;
   1129   typedef const Char* Location;
   1130   struct StructuredError {
   1131     size_t offset_start;
   1132     size_t offset_limit;
   1133     std::string message;
   1134   };
   1135 
   1136   OurReader(OurFeatures const& features);
   1137   bool parse(const char* beginDoc,
   1138              const char* endDoc,
   1139              Value& root,
   1140              bool collectComments = true);
   1141   std::string getFormattedErrorMessages() const;
   1142   std::vector<StructuredError> getStructuredErrors() const;
   1143   bool pushError(const Value& value, const std::string& message);
   1144   bool pushError(const Value& value, const std::string& message, const Value& extra);
   1145   bool good() const;
   1146 
   1147 private:
   1148   OurReader(OurReader const&);  // no impl
   1149   void operator=(OurReader const&);  // no impl
   1150 
   1151   enum TokenType {
   1152     tokenEndOfStream = 0,
   1153     tokenObjectBegin,
   1154     tokenObjectEnd,
   1155     tokenArrayBegin,
   1156     tokenArrayEnd,
   1157     tokenString,
   1158     tokenNumber,
   1159     tokenTrue,
   1160     tokenFalse,
   1161     tokenNull,
   1162     tokenArraySeparator,
   1163     tokenMemberSeparator,
   1164     tokenComment,
   1165     tokenError
   1166   };
   1167 
   1168   class Token {
   1169   public:
   1170     TokenType type_;
   1171     Location start_;
   1172     Location end_;
   1173   };
   1174 
   1175   class ErrorInfo {
   1176   public:
   1177     Token token_;
   1178     std::string message_;
   1179     Location extra_;
   1180   };
   1181 
   1182   typedef std::deque<ErrorInfo> Errors;
   1183 
   1184   bool readToken(Token& token);
   1185   void skipSpaces();
   1186   bool match(Location pattern, int patternLength);
   1187   bool readComment();
   1188   bool readCStyleComment();
   1189   bool readCppStyleComment();
   1190   bool readString();
   1191   bool readStringSingleQuote();
   1192   void readNumber();
   1193   bool readValue();
   1194   bool readObject(Token& token);
   1195   bool readArray(Token& token);
   1196   bool decodeNumber(Token& token);
   1197   bool decodeNumber(Token& token, Value& decoded);
   1198   bool decodeString(Token& token);
   1199   bool decodeString(Token& token, std::string& decoded);
   1200   bool decodeDouble(Token& token);
   1201   bool decodeDouble(Token& token, Value& decoded);
   1202   bool decodeUnicodeCodePoint(Token& token,
   1203                               Location& current,
   1204                               Location end,
   1205                               unsigned int& unicode);
   1206   bool decodeUnicodeEscapeSequence(Token& token,
   1207                                    Location& current,
   1208                                    Location end,
   1209                                    unsigned int& unicode);
   1210   bool addError(const std::string& message, Token& token, Location extra = 0);
   1211   bool recoverFromError(TokenType skipUntilToken);
   1212   bool addErrorAndRecover(const std::string& message,
   1213                           Token& token,
   1214                           TokenType skipUntilToken);
   1215   void skipUntilSpace();
   1216   Value& currentValue();
   1217   Char getNextChar();
   1218   void
   1219   getLocationLineAndColumn(Location location, int& line, int& column) const;
   1220   std::string getLocationLineAndColumn(Location location) const;
   1221   void addComment(Location begin, Location end, CommentPlacement placement);
   1222   void skipCommentTokens(Token& token);
   1223 
   1224   typedef std::stack<Value*> Nodes;
   1225   Nodes nodes_;
   1226   Errors errors_;
   1227   std::string document_;
   1228   Location begin_;
   1229   Location end_;
   1230   Location current_;
   1231   Location lastValueEnd_;
   1232   Value* lastValue_;
   1233   std::string commentsBefore_;
   1234   int stackDepth_;
   1235 
   1236   OurFeatures const features_;
   1237   bool collectComments_;
   1238 };  // OurReader
   1239 
   1240 // complete copy of Read impl, for OurReader
   1241 
   1242 OurReader::OurReader(OurFeatures const& features)
   1243     : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
   1244       lastValue_(), commentsBefore_(), features_(features), collectComments_() {
   1245 }
   1246 
   1247 bool OurReader::parse(const char* beginDoc,
   1248                    const char* endDoc,
   1249                    Value& root,
   1250                    bool collectComments) {
   1251   if (!features_.allowComments_) {
   1252     collectComments = false;
   1253   }
   1254 
   1255   begin_ = beginDoc;
   1256   end_ = endDoc;
   1257   collectComments_ = collectComments;
   1258   current_ = begin_;
   1259   lastValueEnd_ = 0;
   1260   lastValue_ = 0;
   1261   commentsBefore_ = "";
   1262   errors_.clear();
   1263   while (!nodes_.empty())
   1264     nodes_.pop();
   1265   nodes_.push(&root);
   1266 
   1267   stackDepth_ = 0;
   1268   bool successful = readValue();
   1269   Token token;
   1270   skipCommentTokens(token);
   1271   if (features_.failIfExtra_) {
   1272     if (token.type_ != tokenError && token.type_ != tokenEndOfStream) {
   1273       addError("Extra non-whitespace after JSON value.", token);
   1274       return false;
   1275     }
   1276   }
   1277   if (collectComments_ && !commentsBefore_.empty())
   1278     root.setComment(commentsBefore_, commentAfter);
   1279   if (features_.strictRoot_) {
   1280     if (!root.isArray() && !root.isObject()) {
   1281       // Set error location to start of doc, ideally should be first token found
   1282       // in doc
   1283       token.type_ = tokenError;
   1284       token.start_ = beginDoc;
   1285       token.end_ = endDoc;
   1286       addError(
   1287           "A valid JSON document must be either an array or an object value.",
   1288           token);
   1289       return false;
   1290     }
   1291   }
   1292   return successful;
   1293 }
   1294 
   1295 bool OurReader::readValue() {
   1296   if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
   1297   ++stackDepth_;
   1298   Token token;
   1299   skipCommentTokens(token);
   1300   bool successful = true;
   1301 
   1302   if (collectComments_ && !commentsBefore_.empty()) {
   1303     currentValue().setComment(commentsBefore_, commentBefore);
   1304     commentsBefore_ = "";
   1305   }
   1306 
   1307   switch (token.type_) {
   1308   case tokenObjectBegin:
   1309     successful = readObject(token);
   1310     currentValue().setOffsetLimit(current_ - begin_);
   1311     break;
   1312   case tokenArrayBegin:
   1313     successful = readArray(token);
   1314     currentValue().setOffsetLimit(current_ - begin_);
   1315     break;
   1316   case tokenNumber:
   1317     successful = decodeNumber(token);
   1318     break;
   1319   case tokenString:
   1320     successful = decodeString(token);
   1321     break;
   1322   case tokenTrue:
   1323     {
   1324     Value v(true);
   1325     currentValue().swapPayload(v);
   1326     currentValue().setOffsetStart(token.start_ - begin_);
   1327     currentValue().setOffsetLimit(token.end_ - begin_);
   1328     }
   1329     break;
   1330   case tokenFalse:
   1331     {
   1332     Value v(false);
   1333     currentValue().swapPayload(v);
   1334     currentValue().setOffsetStart(token.start_ - begin_);
   1335     currentValue().setOffsetLimit(token.end_ - begin_);
   1336     }
   1337     break;
   1338   case tokenNull:
   1339     {
   1340     Value v;
   1341     currentValue().swapPayload(v);
   1342     currentValue().setOffsetStart(token.start_ - begin_);
   1343     currentValue().setOffsetLimit(token.end_ - begin_);
   1344     }
   1345     break;
   1346   case tokenArraySeparator:
   1347   case tokenObjectEnd:
   1348   case tokenArrayEnd:
   1349     if (features_.allowDroppedNullPlaceholders_) {
   1350       // "Un-read" the current token and mark the current value as a null
   1351       // token.
   1352       current_--;
   1353       Value v;
   1354       currentValue().swapPayload(v);
   1355       currentValue().setOffsetStart(current_ - begin_ - 1);
   1356       currentValue().setOffsetLimit(current_ - begin_);
   1357       break;
   1358     } // else, fall through ...
   1359   default:
   1360     currentValue().setOffsetStart(token.start_ - begin_);
   1361     currentValue().setOffsetLimit(token.end_ - begin_);
   1362     return addError("Syntax error: value, object or array expected.", token);
   1363   }
   1364 
   1365   if (collectComments_) {
   1366     lastValueEnd_ = current_;
   1367     lastValue_ = &currentValue();
   1368   }
   1369 
   1370   --stackDepth_;
   1371   return successful;
   1372 }
   1373 
   1374 void OurReader::skipCommentTokens(Token& token) {
   1375   if (features_.allowComments_) {
   1376     do {
   1377       readToken(token);
   1378     } while (token.type_ == tokenComment);
   1379   } else {
   1380     readToken(token);
   1381   }
   1382 }
   1383 
   1384 bool OurReader::readToken(Token& token) {
   1385   skipSpaces();
   1386   token.start_ = current_;
   1387   Char c = getNextChar();
   1388   bool ok = true;
   1389   switch (c) {
   1390   case '{':
   1391     token.type_ = tokenObjectBegin;
   1392     break;
   1393   case '}':
   1394     token.type_ = tokenObjectEnd;
   1395     break;
   1396   case '[':
   1397     token.type_ = tokenArrayBegin;
   1398     break;
   1399   case ']':
   1400     token.type_ = tokenArrayEnd;
   1401     break;
   1402   case '"':
   1403     token.type_ = tokenString;
   1404     ok = readString();
   1405     break;
   1406   case '\'':
   1407     if (features_.allowSingleQuotes_) {
   1408     token.type_ = tokenString;
   1409     ok = readStringSingleQuote();
   1410     break;
   1411     } // else continue
   1412   case '/':
   1413     token.type_ = tokenComment;
   1414     ok = readComment();
   1415     break;
   1416   case '0':
   1417   case '1':
   1418   case '2':
   1419   case '3':
   1420   case '4':
   1421   case '5':
   1422   case '6':
   1423   case '7':
   1424   case '8':
   1425   case '9':
   1426   case '-':
   1427     token.type_ = tokenNumber;
   1428     readNumber();
   1429     break;
   1430   case 't':
   1431     token.type_ = tokenTrue;
   1432     ok = match("rue", 3);
   1433     break;
   1434   case 'f':
   1435     token.type_ = tokenFalse;
   1436     ok = match("alse", 4);
   1437     break;
   1438   case 'n':
   1439     token.type_ = tokenNull;
   1440     ok = match("ull", 3);
   1441     break;
   1442   case ',':
   1443     token.type_ = tokenArraySeparator;
   1444     break;
   1445   case ':':
   1446     token.type_ = tokenMemberSeparator;
   1447     break;
   1448   case 0:
   1449     token.type_ = tokenEndOfStream;
   1450     break;
   1451   default:
   1452     ok = false;
   1453     break;
   1454   }
   1455   if (!ok)
   1456     token.type_ = tokenError;
   1457   token.end_ = current_;
   1458   return true;
   1459 }
   1460 
   1461 void OurReader::skipSpaces() {
   1462   while (current_ != end_) {
   1463     Char c = *current_;
   1464     if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
   1465       ++current_;
   1466     else
   1467       break;
   1468   }
   1469 }
   1470 
   1471 bool OurReader::match(Location pattern, int patternLength) {
   1472   if (end_ - current_ < patternLength)
   1473     return false;
   1474   int index = patternLength;
   1475   while (index--)
   1476     if (current_[index] != pattern[index])
   1477       return false;
   1478   current_ += patternLength;
   1479   return true;
   1480 }
   1481 
   1482 bool OurReader::readComment() {
   1483   Location commentBegin = current_ - 1;
   1484   Char c = getNextChar();
   1485   bool successful = false;
   1486   if (c == '*')
   1487     successful = readCStyleComment();
   1488   else if (c == '/')
   1489     successful = readCppStyleComment();
   1490   if (!successful)
   1491     return false;
   1492 
   1493   if (collectComments_) {
   1494     CommentPlacement placement = commentBefore;
   1495     if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
   1496       if (c != '*' || !containsNewLine(commentBegin, current_))
   1497         placement = commentAfterOnSameLine;
   1498     }
   1499 
   1500     addComment(commentBegin, current_, placement);
   1501   }
   1502   return true;
   1503 }
   1504 
   1505 void
   1506 OurReader::addComment(Location begin, Location end, CommentPlacement placement) {
   1507   assert(collectComments_);
   1508   const std::string& normalized = normalizeEOL(begin, end);
   1509   if (placement == commentAfterOnSameLine) {
   1510     assert(lastValue_ != 0);
   1511     lastValue_->setComment(normalized, placement);
   1512   } else {
   1513     commentsBefore_ += normalized;
   1514   }
   1515 }
   1516 
   1517 bool OurReader::readCStyleComment() {
   1518   while (current_ != end_) {
   1519     Char c = getNextChar();
   1520     if (c == '*' && *current_ == '/')
   1521       break;
   1522   }
   1523   return getNextChar() == '/';
   1524 }
   1525 
   1526 bool OurReader::readCppStyleComment() {
   1527   while (current_ != end_) {
   1528     Char c = getNextChar();
   1529     if (c == '\n')
   1530       break;
   1531     if (c == '\r') {
   1532       // Consume DOS EOL. It will be normalized in addComment.
   1533       if (current_ != end_ && *current_ == '\n')
   1534         getNextChar();
   1535       // Break on Moc OS 9 EOL.
   1536       break;
   1537     }
   1538   }
   1539   return true;
   1540 }
   1541 
   1542 void OurReader::readNumber() {
   1543   const char *p = current_;
   1544   char c = '0'; // stopgap for already consumed character
   1545   // integral part
   1546   while (c >= '0' && c <= '9')
   1547     c = (current_ = p) < end_ ? *p++ : 0;
   1548   // fractional part
   1549   if (c == '.') {
   1550     c = (current_ = p) < end_ ? *p++ : 0;
   1551     while (c >= '0' && c <= '9')
   1552       c = (current_ = p) < end_ ? *p++ : 0;
   1553   }
   1554   // exponential part
   1555   if (c == 'e' || c == 'E') {
   1556     c = (current_ = p) < end_ ? *p++ : 0;
   1557     if (c == '+' || c == '-')
   1558       c = (current_ = p) < end_ ? *p++ : 0;
   1559     while (c >= '0' && c <= '9')
   1560       c = (current_ = p) < end_ ? *p++ : 0;
   1561   }
   1562 }
   1563 bool OurReader::readString() {
   1564   Char c = 0;
   1565   while (current_ != end_) {
   1566     c = getNextChar();
   1567     if (c == '\\')
   1568       getNextChar();
   1569     else if (c == '"')
   1570       break;
   1571   }
   1572   return c == '"';
   1573 }
   1574 
   1575 
   1576 bool OurReader::readStringSingleQuote() {
   1577   Char c = 0;
   1578   while (current_ != end_) {
   1579     c = getNextChar();
   1580     if (c == '\\')
   1581       getNextChar();
   1582     else if (c == '\'')
   1583       break;
   1584   }
   1585   return c == '\'';
   1586 }
   1587 
   1588 bool OurReader::readObject(Token& tokenStart) {
   1589   Token tokenName;
   1590   std::string name;
   1591   Value init(objectValue);
   1592   currentValue().swapPayload(init);
   1593   currentValue().setOffsetStart(tokenStart.start_ - begin_);
   1594   while (readToken(tokenName)) {
   1595     bool initialTokenOk = true;
   1596     while (tokenName.type_ == tokenComment && initialTokenOk)
   1597       initialTokenOk = readToken(tokenName);
   1598     if (!initialTokenOk)
   1599       break;
   1600     if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
   1601       return true;
   1602     name = "";
   1603     if (tokenName.type_ == tokenString) {
   1604       if (!decodeString(tokenName, name))
   1605         return recoverFromError(tokenObjectEnd);
   1606     } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
   1607       Value numberName;
   1608       if (!decodeNumber(tokenName, numberName))
   1609         return recoverFromError(tokenObjectEnd);
   1610       name = numberName.asString();
   1611     } else {
   1612       break;
   1613     }
   1614 
   1615     Token colon;
   1616     if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
   1617       return addErrorAndRecover(
   1618           "Missing ':' after object member name", colon, tokenObjectEnd);
   1619     }
   1620     if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
   1621     if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
   1622       std::string msg = "Duplicate key: '" + name + "'";
   1623       return addErrorAndRecover(
   1624           msg, tokenName, tokenObjectEnd);
   1625     }
   1626     Value& value = currentValue()[name];
   1627     nodes_.push(&value);
   1628     bool ok = readValue();
   1629     nodes_.pop();
   1630     if (!ok) // error already set
   1631       return recoverFromError(tokenObjectEnd);
   1632 
   1633     Token comma;
   1634     if (!readToken(comma) ||
   1635         (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
   1636          comma.type_ != tokenComment)) {
   1637       return addErrorAndRecover(
   1638           "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
   1639     }
   1640     bool finalizeTokenOk = true;
   1641     while (comma.type_ == tokenComment && finalizeTokenOk)
   1642       finalizeTokenOk = readToken(comma);
   1643     if (comma.type_ == tokenObjectEnd)
   1644       return true;
   1645   }
   1646   return addErrorAndRecover(
   1647       "Missing '}' or object member name", tokenName, tokenObjectEnd);
   1648 }
   1649 
   1650 bool OurReader::readArray(Token& tokenStart) {
   1651   Value init(arrayValue);
   1652   currentValue().swapPayload(init);
   1653   currentValue().setOffsetStart(tokenStart.start_ - begin_);
   1654   skipSpaces();
   1655   if (*current_ == ']') // empty array
   1656   {
   1657     Token endArray;
   1658     readToken(endArray);
   1659     return true;
   1660   }
   1661   int index = 0;
   1662   for (;;) {
   1663     Value& value = currentValue()[index++];
   1664     nodes_.push(&value);
   1665     bool ok = readValue();
   1666     nodes_.pop();
   1667     if (!ok) // error already set
   1668       return recoverFromError(tokenArrayEnd);
   1669 
   1670     Token token;
   1671     // Accept Comment after last item in the array.
   1672     ok = readToken(token);
   1673     while (token.type_ == tokenComment && ok) {
   1674       ok = readToken(token);
   1675     }
   1676     bool badTokenType =
   1677         (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
   1678     if (!ok || badTokenType) {
   1679       return addErrorAndRecover(
   1680           "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
   1681     }
   1682     if (token.type_ == tokenArrayEnd)
   1683       break;
   1684   }
   1685   return true;
   1686 }
   1687 
   1688 bool OurReader::decodeNumber(Token& token) {
   1689   Value decoded;
   1690   if (!decodeNumber(token, decoded))
   1691     return false;
   1692   currentValue().swapPayload(decoded);
   1693   currentValue().setOffsetStart(token.start_ - begin_);
   1694   currentValue().setOffsetLimit(token.end_ - begin_);
   1695   return true;
   1696 }
   1697 
   1698 bool OurReader::decodeNumber(Token& token, Value& decoded) {
   1699   // Attempts to parse the number as an integer. If the number is
   1700   // larger than the maximum supported value of an integer then
   1701   // we decode the number as a double.
   1702   Location current = token.start_;
   1703   bool isNegative = *current == '-';
   1704   if (isNegative)
   1705     ++current;
   1706   // TODO: Help the compiler do the div and mod at compile time or get rid of them.
   1707   Value::LargestUInt maxIntegerValue =
   1708       isNegative ? Value::LargestUInt(-Value::minLargestInt)
   1709                  : Value::maxLargestUInt;
   1710   Value::LargestUInt threshold = maxIntegerValue / 10;
   1711   Value::LargestUInt value = 0;
   1712   while (current < token.end_) {
   1713     Char c = *current++;
   1714     if (c < '0' || c > '9')
   1715       return decodeDouble(token, decoded);
   1716     Value::UInt digit(c - '0');
   1717     if (value >= threshold) {
   1718       // We've hit or exceeded the max value divided by 10 (rounded down). If
   1719       // a) we've only just touched the limit, b) this is the last digit, and
   1720       // c) it's small enough to fit in that rounding delta, we're okay.
   1721       // Otherwise treat this number as a double to avoid overflow.
   1722       if (value > threshold || current != token.end_ ||
   1723           digit > maxIntegerValue % 10) {
   1724         return decodeDouble(token, decoded);
   1725       }
   1726     }
   1727     value = value * 10 + digit;
   1728   }
   1729   if (isNegative)
   1730     decoded = -Value::LargestInt(value);
   1731   else if (value <= Value::LargestUInt(Value::maxInt))
   1732     decoded = Value::LargestInt(value);
   1733   else
   1734     decoded = value;
   1735   return true;
   1736 }
   1737 
   1738 bool OurReader::decodeDouble(Token& token) {
   1739   Value decoded;
   1740   if (!decodeDouble(token, decoded))
   1741     return false;
   1742   currentValue().swapPayload(decoded);
   1743   currentValue().setOffsetStart(token.start_ - begin_);
   1744   currentValue().setOffsetLimit(token.end_ - begin_);
   1745   return true;
   1746 }
   1747 
   1748 bool OurReader::decodeDouble(Token& token, Value& decoded) {
   1749   double value = 0;
   1750   const int bufferSize = 32;
   1751   int count;
   1752   int length = int(token.end_ - token.start_);
   1753 
   1754   // Sanity check to avoid buffer overflow exploits.
   1755   if (length < 0) {
   1756     return addError("Unable to parse token length", token);
   1757   }
   1758 
   1759   // Avoid using a string constant for the format control string given to
   1760   // sscanf, as this can cause hard to debug crashes on OS X. See here for more
   1761   // info:
   1762   //
   1763   //     http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
   1764   char format[] = "%lf";
   1765 
   1766   if (length <= bufferSize) {
   1767     Char buffer[bufferSize + 1];
   1768     memcpy(buffer, token.start_, length);
   1769     buffer[length] = 0;
   1770     count = sscanf(buffer, format, &value);
   1771   } else {
   1772     std::string buffer(token.start_, token.end_);
   1773     count = sscanf(buffer.c_str(), format, &value);
   1774   }
   1775 
   1776   if (count != 1)
   1777     return addError("'" + std::string(token.start_, token.end_) +
   1778                         "' is not a number.",
   1779                     token);
   1780   decoded = value;
   1781   return true;
   1782 }
   1783 
   1784 bool OurReader::decodeString(Token& token) {
   1785   std::string decoded_string;
   1786   if (!decodeString(token, decoded_string))
   1787     return false;
   1788   Value decoded(decoded_string);
   1789   currentValue().swapPayload(decoded);
   1790   currentValue().setOffsetStart(token.start_ - begin_);
   1791   currentValue().setOffsetLimit(token.end_ - begin_);
   1792   return true;
   1793 }
   1794 
   1795 bool OurReader::decodeString(Token& token, std::string& decoded) {
   1796   decoded.reserve(token.end_ - token.start_ - 2);
   1797   Location current = token.start_ + 1; // skip '"'
   1798   Location end = token.end_ - 1;       // do not include '"'
   1799   while (current != end) {
   1800     Char c = *current++;
   1801     if (c == '"')
   1802       break;
   1803     else if (c == '\\') {
   1804       if (current == end)
   1805         return addError("Empty escape sequence in string", token, current);
   1806       Char escape = *current++;
   1807       switch (escape) {
   1808       case '"':
   1809         decoded += '"';
   1810         break;
   1811       case '/':
   1812         decoded += '/';
   1813         break;
   1814       case '\\':
   1815         decoded += '\\';
   1816         break;
   1817       case 'b':
   1818         decoded += '\b';
   1819         break;
   1820       case 'f':
   1821         decoded += '\f';
   1822         break;
   1823       case 'n':
   1824         decoded += '\n';
   1825         break;
   1826       case 'r':
   1827         decoded += '\r';
   1828         break;
   1829       case 't':
   1830         decoded += '\t';
   1831         break;
   1832       case 'u': {
   1833         unsigned int unicode;
   1834         if (!decodeUnicodeCodePoint(token, current, end, unicode))
   1835           return false;
   1836         decoded += codePointToUTF8(unicode);
   1837       } break;
   1838       default:
   1839         return addError("Bad escape sequence in string", token, current);
   1840       }
   1841     } else {
   1842       decoded += c;
   1843     }
   1844   }
   1845   return true;
   1846 }
   1847 
   1848 bool OurReader::decodeUnicodeCodePoint(Token& token,
   1849                                     Location& current,
   1850                                     Location end,
   1851                                     unsigned int& unicode) {
   1852 
   1853   if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
   1854     return false;
   1855   if (unicode >= 0xD800 && unicode <= 0xDBFF) {
   1856     // surrogate pairs
   1857     if (end - current < 6)
   1858       return addError(
   1859           "additional six characters expected to parse unicode surrogate pair.",
   1860           token,
   1861           current);
   1862     unsigned int surrogatePair;
   1863     if (*(current++) == '\\' && *(current++) == 'u') {
   1864       if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
   1865         unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
   1866       } else
   1867         return false;
   1868     } else
   1869       return addError("expecting another \\u token to begin the second half of "
   1870                       "a unicode surrogate pair",
   1871                       token,
   1872                       current);
   1873   }
   1874   return true;
   1875 }
   1876 
   1877 bool OurReader::decodeUnicodeEscapeSequence(Token& token,
   1878                                          Location& current,
   1879                                          Location end,
   1880                                          unsigned int& unicode) {
   1881   if (end - current < 4)
   1882     return addError(
   1883         "Bad unicode escape sequence in string: four digits expected.",
   1884         token,
   1885         current);
   1886   unicode = 0;
   1887   for (int index = 0; index < 4; ++index) {
   1888     Char c = *current++;
   1889     unicode *= 16;
   1890     if (c >= '0' && c <= '9')
   1891       unicode += c - '0';
   1892     else if (c >= 'a' && c <= 'f')
   1893       unicode += c - 'a' + 10;
   1894     else if (c >= 'A' && c <= 'F')
   1895       unicode += c - 'A' + 10;
   1896     else
   1897       return addError(
   1898           "Bad unicode escape sequence in string: hexadecimal digit expected.",
   1899           token,
   1900           current);
   1901   }
   1902   return true;
   1903 }
   1904 
   1905 bool
   1906 OurReader::addError(const std::string& message, Token& token, Location extra) {
   1907   ErrorInfo info;
   1908   info.token_ = token;
   1909   info.message_ = message;
   1910   info.extra_ = extra;
   1911   errors_.push_back(info);
   1912   return false;
   1913 }
   1914 
   1915 bool OurReader::recoverFromError(TokenType skipUntilToken) {
   1916   int errorCount = int(errors_.size());
   1917   Token skip;
   1918   for (;;) {
   1919     if (!readToken(skip))
   1920       errors_.resize(errorCount); // discard errors caused by recovery
   1921     if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
   1922       break;
   1923   }
   1924   errors_.resize(errorCount);
   1925   return false;
   1926 }
   1927 
   1928 bool OurReader::addErrorAndRecover(const std::string& message,
   1929                                 Token& token,
   1930                                 TokenType skipUntilToken) {
   1931   addError(message, token);
   1932   return recoverFromError(skipUntilToken);
   1933 }
   1934 
   1935 Value& OurReader::currentValue() { return *(nodes_.top()); }
   1936 
   1937 OurReader::Char OurReader::getNextChar() {
   1938   if (current_ == end_)
   1939     return 0;
   1940   return *current_++;
   1941 }
   1942 
   1943 void OurReader::getLocationLineAndColumn(Location location,
   1944                                       int& line,
   1945                                       int& column) const {
   1946   Location current = begin_;
   1947   Location lastLineStart = current;
   1948   line = 0;
   1949   while (current < location && current != end_) {
   1950     Char c = *current++;
   1951     if (c == '\r') {
   1952       if (*current == '\n')
   1953         ++current;
   1954       lastLineStart = current;
   1955       ++line;
   1956     } else if (c == '\n') {
   1957       lastLineStart = current;
   1958       ++line;
   1959     }
   1960   }
   1961   // column & line start at 1
   1962   column = int(location - lastLineStart) + 1;
   1963   ++line;
   1964 }
   1965 
   1966 std::string OurReader::getLocationLineAndColumn(Location location) const {
   1967   int line, column;
   1968   getLocationLineAndColumn(location, line, column);
   1969   char buffer[18 + 16 + 16 + 1];
   1970 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
   1971 #if defined(WINCE)
   1972   _snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
   1973 #else
   1974   sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
   1975 #endif
   1976 #else
   1977   snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
   1978 #endif
   1979   return buffer;
   1980 }
   1981 
   1982 std::string OurReader::getFormattedErrorMessages() const {
   1983   std::string formattedMessage;
   1984   for (Errors::const_iterator itError = errors_.begin();
   1985        itError != errors_.end();
   1986        ++itError) {
   1987     const ErrorInfo& error = *itError;
   1988     formattedMessage +=
   1989         "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
   1990     formattedMessage += "  " + error.message_ + "\n";
   1991     if (error.extra_)
   1992       formattedMessage +=
   1993           "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
   1994   }
   1995   return formattedMessage;
   1996 }
   1997 
   1998 std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
   1999   std::vector<OurReader::StructuredError> allErrors;
   2000   for (Errors::const_iterator itError = errors_.begin();
   2001        itError != errors_.end();
   2002        ++itError) {
   2003     const ErrorInfo& error = *itError;
   2004     OurReader::StructuredError structured;
   2005     structured.offset_start = error.token_.start_ - begin_;
   2006     structured.offset_limit = error.token_.end_ - begin_;
   2007     structured.message = error.message_;
   2008     allErrors.push_back(structured);
   2009   }
   2010   return allErrors;
   2011 }
   2012 
   2013 bool OurReader::pushError(const Value& value, const std::string& message) {
   2014   size_t length = end_ - begin_;
   2015   if(value.getOffsetStart() > length
   2016     || value.getOffsetLimit() > length)
   2017     return false;
   2018   Token token;
   2019   token.type_ = tokenError;
   2020   token.start_ = begin_ + value.getOffsetStart();
   2021   token.end_ = end_ + value.getOffsetLimit();
   2022   ErrorInfo info;
   2023   info.token_ = token;
   2024   info.message_ = message;
   2025   info.extra_ = 0;
   2026   errors_.push_back(info);
   2027   return true;
   2028 }
   2029 
   2030 bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) {
   2031   size_t length = end_ - begin_;
   2032   if(value.getOffsetStart() > length
   2033     || value.getOffsetLimit() > length
   2034     || extra.getOffsetLimit() > length)
   2035     return false;
   2036   Token token;
   2037   token.type_ = tokenError;
   2038   token.start_ = begin_ + value.getOffsetStart();
   2039   token.end_ = begin_ + value.getOffsetLimit();
   2040   ErrorInfo info;
   2041   info.token_ = token;
   2042   info.message_ = message;
   2043   info.extra_ = begin_ + extra.getOffsetStart();
   2044   errors_.push_back(info);
   2045   return true;
   2046 }
   2047 
   2048 bool OurReader::good() const {
   2049   return !errors_.size();
   2050 }
   2051 
   2052 
   2053 class OurCharReader : public CharReader {
   2054   bool const collectComments_;
   2055   OurReader reader_;
   2056 public:
   2057   OurCharReader(
   2058     bool collectComments,
   2059     OurFeatures const& features)
   2060   : collectComments_(collectComments)
   2061   , reader_(features)
   2062   {}
   2063   virtual bool parse(
   2064       char const* beginDoc, char const* endDoc,
   2065       Value* root, std::string* errs) {
   2066     bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
   2067     if (errs) {
   2068       *errs = reader_.getFormattedErrorMessages();
   2069     }
   2070     return ok;
   2071   }
   2072 };
   2073 
   2074 CharReaderBuilder::CharReaderBuilder()
   2075 {
   2076   setDefaults(&settings_);
   2077 }
   2078 CharReaderBuilder::~CharReaderBuilder()
   2079 {}
   2080 CharReader* CharReaderBuilder::newCharReader() const
   2081 {
   2082   bool collectComments = settings_["collectComments"].asBool();
   2083   OurFeatures features = OurFeatures::all();
   2084   features.allowComments_ = settings_["allowComments"].asBool();
   2085   features.strictRoot_ = settings_["strictRoot"].asBool();
   2086   features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool();
   2087   features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
   2088   features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
   2089   features.stackLimit_ = settings_["stackLimit"].asInt();
   2090   features.failIfExtra_ = settings_["failIfExtra"].asBool();
   2091   features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool();
   2092   return new OurCharReader(collectComments, features);
   2093 }
   2094 static void getValidReaderKeys(std::set<std::string>* valid_keys)
   2095 {
   2096   valid_keys->clear();
   2097   valid_keys->insert("collectComments");
   2098   valid_keys->insert("allowComments");
   2099   valid_keys->insert("strictRoot");
   2100   valid_keys->insert("allowDroppedNullPlaceholders");
   2101   valid_keys->insert("allowNumericKeys");
   2102   valid_keys->insert("allowSingleQuotes");
   2103   valid_keys->insert("stackLimit");
   2104   valid_keys->insert("failIfExtra");
   2105   valid_keys->insert("rejectDupKeys");
   2106 }
   2107 bool CharReaderBuilder::validate(Json::Value* invalid) const
   2108 {
   2109   Json::Value my_invalid;
   2110   if (!invalid) invalid = &my_invalid;  // so we do not need to test for NULL
   2111   Json::Value& inv = *invalid;
   2112   std::set<std::string> valid_keys;
   2113   getValidReaderKeys(&valid_keys);
   2114   Value::Members keys = settings_.getMemberNames();
   2115   size_t n = keys.size();
   2116   for (size_t i = 0; i < n; ++i) {
   2117     std::string const& key = keys[i];
   2118     if (valid_keys.find(key) == valid_keys.end()) {
   2119       inv[key] = settings_[key];
   2120     }
   2121   }
   2122   return 0u == inv.size();
   2123 }
   2124 Value& CharReaderBuilder::operator[](std::string key)
   2125 {
   2126   return settings_[key];
   2127 }
   2128 // static
   2129 void CharReaderBuilder::strictMode(Json::Value* settings)
   2130 {
   2131 //! [CharReaderBuilderStrictMode]
   2132   (*settings)["allowComments"] = false;
   2133   (*settings)["strictRoot"] = true;
   2134   (*settings)["allowDroppedNullPlaceholders"] = false;
   2135   (*settings)["allowNumericKeys"] = false;
   2136   (*settings)["allowSingleQuotes"] = false;
   2137   (*settings)["failIfExtra"] = true;
   2138   (*settings)["rejectDupKeys"] = true;
   2139 //! [CharReaderBuilderStrictMode]
   2140 }
   2141 // static
   2142 void CharReaderBuilder::setDefaults(Json::Value* settings)
   2143 {
   2144 //! [CharReaderBuilderDefaults]
   2145   (*settings)["collectComments"] = true;
   2146   (*settings)["allowComments"] = true;
   2147   (*settings)["strictRoot"] = false;
   2148   (*settings)["allowDroppedNullPlaceholders"] = false;
   2149   (*settings)["allowNumericKeys"] = false;
   2150   (*settings)["allowSingleQuotes"] = false;
   2151   (*settings)["stackLimit"] = 1000;
   2152   (*settings)["failIfExtra"] = false;
   2153   (*settings)["rejectDupKeys"] = false;
   2154 //! [CharReaderBuilderDefaults]
   2155 }
   2156 
   2157 //////////////////////////////////
   2158 // global functions
   2159 
   2160 bool parseFromStream(
   2161     CharReader::Factory const& fact, std::istream& sin,
   2162     Value* root, std::string* errs)
   2163 {
   2164   std::ostringstream ssin;
   2165   ssin << sin.rdbuf();
   2166   std::string doc = ssin.str();
   2167   char const* begin = doc.data();
   2168   char const* end = begin + doc.size();
   2169   // Note that we do not actually need a null-terminator.
   2170   CharReaderPtr const reader(fact.newCharReader());
   2171   return reader->parse(begin, end, root, errs);
   2172 }
   2173 
   2174 std::istream& operator>>(std::istream& sin, Value& root) {
   2175   CharReaderBuilder b;
   2176   std::string errs;
   2177   bool ok = parseFromStream(b, sin, &root, &errs);
   2178   if (!ok) {
   2179     fprintf(stderr,
   2180             "Error from reader: %s",
   2181             errs.c_str());
   2182 
   2183     throwRuntimeError("reader error");
   2184   }
   2185   return sin;
   2186 }
   2187 
   2188 } // namespace Json
   2189 
   2190 // //////////////////////////////////////////////////////////////////////
   2191 // End of content of file: src/lib_json/json_reader.cpp
   2192 // //////////////////////////////////////////////////////////////////////
   2193 
   2194 
   2195 
   2196 
   2197 
   2198 
   2199 // //////////////////////////////////////////////////////////////////////
   2200 // Beginning of content of file: src/lib_json/json_valueiterator.inl
   2201 // //////////////////////////////////////////////////////////////////////
   2202 
   2203 // Copyright 2007-2010 Baptiste Lepilleur
   2204 // Distributed under MIT license, or public domain if desired and
   2205 // recognized in your jurisdiction.
   2206 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
   2207 
   2208 // included by json_value.cpp
   2209 
   2210 namespace Json {
   2211 
   2212 // //////////////////////////////////////////////////////////////////
   2213 // //////////////////////////////////////////////////////////////////
   2214 // //////////////////////////////////////////////////////////////////
   2215 // class ValueIteratorBase
   2216 // //////////////////////////////////////////////////////////////////
   2217 // //////////////////////////////////////////////////////////////////
   2218 // //////////////////////////////////////////////////////////////////
   2219 
   2220 ValueIteratorBase::ValueIteratorBase()
   2221     : current_(), isNull_(true) {
   2222 }
   2223 
   2224 ValueIteratorBase::ValueIteratorBase(
   2225     const Value::ObjectValues::iterator& current)
   2226     : current_(current), isNull_(false) {}
   2227 
   2228 Value& ValueIteratorBase::deref() const {
   2229   return current_->second;
   2230 }
   2231 
   2232 void ValueIteratorBase::increment() {
   2233   ++current_;
   2234 }
   2235 
   2236 void ValueIteratorBase::decrement() {
   2237   --current_;
   2238 }
   2239 
   2240 ValueIteratorBase::difference_type
   2241 ValueIteratorBase::computeDistance(const SelfType& other) const {
   2242 #ifdef JSON_USE_CPPTL_SMALLMAP
   2243   return other.current_ - current_;
   2244 #else
   2245   // Iterator for null value are initialized using the default
   2246   // constructor, which initialize current_ to the default
   2247   // std::map::iterator. As begin() and end() are two instance
   2248   // of the default std::map::iterator, they can not be compared.
   2249   // To allow this, we handle this comparison specifically.
   2250   if (isNull_ && other.isNull_) {
   2251     return 0;
   2252   }
   2253 
   2254   // Usage of std::distance is not portable (does not compile with Sun Studio 12
   2255   // RogueWave STL,
   2256   // which is the one used by default).
   2257   // Using a portable hand-made version for non random iterator instead:
   2258   //   return difference_type( std::distance( current_, other.current_ ) );
   2259   difference_type myDistance = 0;
   2260   for (Value::ObjectValues::iterator it = current_; it != other.current_;
   2261        ++it) {
   2262     ++myDistance;
   2263   }
   2264   return myDistance;
   2265 #endif
   2266 }
   2267 
   2268 bool ValueIteratorBase::isEqual(const SelfType& other) const {
   2269   if (isNull_) {
   2270     return other.isNull_;
   2271   }
   2272   return current_ == other.current_;
   2273 }
   2274 
   2275 void ValueIteratorBase::copy(const SelfType& other) {
   2276   current_ = other.current_;
   2277   isNull_ = other.isNull_;
   2278 }
   2279 
   2280 Value ValueIteratorBase::key() const {
   2281   const Value::CZString czstring = (*current_).first;
   2282   if (czstring.data()) {
   2283     if (czstring.isStaticString())
   2284       return Value(StaticString(czstring.data()));
   2285     return Value(czstring.data(), czstring.data() + czstring.length());
   2286   }
   2287   return Value(czstring.index());
   2288 }
   2289 
   2290 UInt ValueIteratorBase::index() const {
   2291   const Value::CZString czstring = (*current_).first;
   2292   if (!czstring.data())
   2293     return czstring.index();
   2294   return Value::UInt(-1);
   2295 }
   2296 
   2297 std::string ValueIteratorBase::name() const {
   2298   char const* key;
   2299   char const* end;
   2300   key = memberName(&end);
   2301   if (!key) return std::string();
   2302   return std::string(key, end);
   2303 }
   2304 
   2305 char const* ValueIteratorBase::memberName() const {
   2306   const char* name = (*current_).first.data();
   2307   return name ? name : "";
   2308 }
   2309 
   2310 char const* ValueIteratorBase::memberName(char const** end) const {
   2311   const char* name = (*current_).first.data();
   2312   if (!name) {
   2313     *end = NULL;
   2314     return NULL;
   2315   }
   2316   *end = name + (*current_).first.length();
   2317   return name;
   2318 }
   2319 
   2320 // //////////////////////////////////////////////////////////////////
   2321 // //////////////////////////////////////////////////////////////////
   2322 // //////////////////////////////////////////////////////////////////
   2323 // class ValueConstIterator
   2324 // //////////////////////////////////////////////////////////////////
   2325 // //////////////////////////////////////////////////////////////////
   2326 // //////////////////////////////////////////////////////////////////
   2327 
   2328 ValueConstIterator::ValueConstIterator() {}
   2329 
   2330 ValueConstIterator::ValueConstIterator(
   2331     const Value::ObjectValues::iterator& current)
   2332     : ValueIteratorBase(current) {}
   2333 
   2334 ValueConstIterator& ValueConstIterator::
   2335 operator=(const ValueIteratorBase& other) {
   2336   copy(other);
   2337   return *this;
   2338 }
   2339 
   2340 // //////////////////////////////////////////////////////////////////
   2341 // //////////////////////////////////////////////////////////////////
   2342 // //////////////////////////////////////////////////////////////////
   2343 // class ValueIterator
   2344 // //////////////////////////////////////////////////////////////////
   2345 // //////////////////////////////////////////////////////////////////
   2346 // //////////////////////////////////////////////////////////////////
   2347 
   2348 ValueIterator::ValueIterator() {}
   2349 
   2350 ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
   2351     : ValueIteratorBase(current) {}
   2352 
   2353 ValueIterator::ValueIterator(const ValueConstIterator& other)
   2354     : ValueIteratorBase(other) {}
   2355 
   2356 ValueIterator::ValueIterator(const ValueIterator& other)
   2357     : ValueIteratorBase(other) {}
   2358 
   2359 ValueIterator& ValueIterator::operator=(const SelfType& other) {
   2360   copy(other);
   2361   return *this;
   2362 }
   2363 
   2364 } // namespace Json
   2365 
   2366 // //////////////////////////////////////////////////////////////////////
   2367 // End of content of file: src/lib_json/json_valueiterator.inl
   2368 // //////////////////////////////////////////////////////////////////////
   2369 
   2370 
   2371 
   2372 
   2373 
   2374 
   2375 // //////////////////////////////////////////////////////////////////////
   2376 // Beginning of content of file: src/lib_json/json_value.cpp
   2377 // //////////////////////////////////////////////////////////////////////
   2378 
   2379 // Copyright 2011 Baptiste Lepilleur
   2380 // Distributed under MIT license, or public domain if desired and
   2381 // recognized in your jurisdiction.
   2382 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
   2383 
   2384 #if !defined(JSON_IS_AMALGAMATION)
   2385 #include <json/assertions.h>
   2386 #include <json/value.h>
   2387 #include <json/writer.h>
   2388 #endif // if !defined(JSON_IS_AMALGAMATION)
   2389 #include <math.h>
   2390 #include <sstream>
   2391 #include <utility>
   2392 #include <cstring>
   2393 #include <cassert>
   2394 #ifdef JSON_USE_CPPTL
   2395 #include <cpptl/conststring.h>
   2396 #endif
   2397 #include <cstddef> // size_t
   2398 #include <algorithm> // min()
   2399 
   2400 #define JSON_ASSERT_UNREACHABLE assert(false)
   2401 
   2402 namespace Json {
   2403 
   2404 // This is a walkaround to avoid the static initialization of Value::null.
   2405 // kNull must be word-aligned to avoid crashing on ARM.  We use an alignment of
   2406 // 8 (instead of 4) as a bit of future-proofing.
   2407 #if defined(__ARMEL__)
   2408 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
   2409 #else
   2410 #define ALIGNAS(byte_alignment)
   2411 #endif
   2412 static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
   2413 const unsigned char& kNullRef = kNull[0];
   2414 const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
   2415 const Value& Value::nullRef = null;
   2416 
   2417 const Int Value::minInt = Int(~(UInt(-1) / 2));
   2418 const Int Value::maxInt = Int(UInt(-1) / 2);
   2419 const UInt Value::maxUInt = UInt(-1);
   2420 #if defined(JSON_HAS_INT64)
   2421 const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
   2422 const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
   2423 const UInt64 Value::maxUInt64 = UInt64(-1);
   2424 // The constant is hard-coded because some compiler have trouble
   2425 // converting Value::maxUInt64 to a double correctly (AIX/xlC).
   2426 // Assumes that UInt64 is a 64 bits integer.
   2427 static const double maxUInt64AsDouble = 18446744073709551615.0;
   2428 #endif // defined(JSON_HAS_INT64)
   2429 const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
   2430 const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
   2431 const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
   2432 
   2433 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
   2434 template <typename T, typename U>
   2435 static inline bool InRange(double d, T min, U max) {
   2436   return d >= min && d <= max;
   2437 }
   2438 #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
   2439 static inline double integerToDouble(Json::UInt64 value) {
   2440   return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1);
   2441 }
   2442 
   2443 template <typename T> static inline double integerToDouble(T value) {
   2444   return static_cast<double>(value);
   2445 }
   2446 
   2447 template <typename T, typename U>
   2448 static inline bool InRange(double d, T min, U max) {
   2449   return d >= integerToDouble(min) && d <= integerToDouble(max);
   2450 }
   2451 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
   2452 
   2453 /** Duplicates the specified string value.
   2454  * @param value Pointer to the string to duplicate. Must be zero-terminated if
   2455  *              length is "unknown".
   2456  * @param length Length of the value. if equals to unknown, then it will be
   2457  *               computed using strlen(value).
   2458  * @return Pointer on the duplicate instance of string.
   2459  */
   2460 static inline char* duplicateStringValue(const char* value,
   2461                                          size_t length) {
   2462   // Avoid an integer overflow in the call to malloc below by limiting length
   2463   // to a sane value.
   2464   if (length >= (size_t)Value::maxInt)
   2465     length = Value::maxInt - 1;
   2466 
   2467   char* newString = static_cast<char*>(malloc(length + 1));
   2468   if (newString == NULL) {
   2469     throwRuntimeError(
   2470         "in Json::Value::duplicateStringValue(): "
   2471         "Failed to allocate string value buffer");
   2472   }
   2473   memcpy(newString, value, length);
   2474   newString[length] = 0;
   2475   return newString;
   2476 }
   2477 
   2478 /* Record the length as a prefix.
   2479  */
   2480 static inline char* duplicateAndPrefixStringValue(
   2481     const char* value,
   2482     unsigned int length)
   2483 {
   2484   // Avoid an integer overflow in the call to malloc below by limiting length
   2485   // to a sane value.
   2486   JSON_ASSERT_MESSAGE(length <= (unsigned)Value::maxInt - sizeof(unsigned) - 1U,
   2487                       "in Json::Value::duplicateAndPrefixStringValue(): "
   2488                       "length too big for prefixing");
   2489   unsigned actualLength = length + sizeof(unsigned) + 1U;
   2490   char* newString = static_cast<char*>(malloc(actualLength));
   2491   if (newString == 0) {
   2492     throwRuntimeError(
   2493         "in Json::Value::duplicateAndPrefixStringValue(): "
   2494         "Failed to allocate string value buffer");
   2495   }
   2496   *reinterpret_cast<unsigned*>(newString) = length;
   2497   memcpy(newString + sizeof(unsigned), value, length);
   2498   newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
   2499   return newString;
   2500 }
   2501 inline static void decodePrefixedString(
   2502     bool isPrefixed, char const* prefixed,
   2503     unsigned* length, char const** value)
   2504 {
   2505   if (!isPrefixed) {
   2506     *length = strlen(prefixed);
   2507     *value = prefixed;
   2508   } else {
   2509     *length = *reinterpret_cast<unsigned const*>(prefixed);
   2510     *value = prefixed + sizeof(unsigned);
   2511   }
   2512 }
   2513 /** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
   2514  */
   2515 static inline void releaseStringValue(char* value) { free(value); }
   2516 
   2517 } // namespace Json
   2518 
   2519 // //////////////////////////////////////////////////////////////////
   2520 // //////////////////////////////////////////////////////////////////
   2521 // //////////////////////////////////////////////////////////////////
   2522 // ValueInternals...
   2523 // //////////////////////////////////////////////////////////////////
   2524 // //////////////////////////////////////////////////////////////////
   2525 // //////////////////////////////////////////////////////////////////
   2526 #if !defined(JSON_IS_AMALGAMATION)
   2527 
   2528 #include "json_valueiterator.inl"
   2529 #endif // if !defined(JSON_IS_AMALGAMATION)
   2530 
   2531 namespace Json {
   2532 
   2533 class JSON_API Exception : public std::exception {
   2534 public:
   2535   Exception(std::string const& msg);
   2536   virtual ~Exception() throw();
   2537   virtual char const* what() const throw();
   2538 protected:
   2539   std::string const msg_;
   2540 };
   2541 class JSON_API RuntimeError : public Exception {
   2542 public:
   2543   RuntimeError(std::string const& msg);
   2544 };
   2545 class JSON_API LogicError : public Exception {
   2546 public:
   2547   LogicError(std::string const& msg);
   2548 };
   2549 
   2550 Exception::Exception(std::string const& msg)
   2551   : msg_(msg)
   2552 {}
   2553 Exception::~Exception() throw()
   2554 {}
   2555 char const* Exception::what() const throw()
   2556 {
   2557   return msg_.c_str();
   2558 }
   2559 RuntimeError::RuntimeError(std::string const& msg)
   2560   : Exception(msg)
   2561 {}
   2562 LogicError::LogicError(std::string const& msg)
   2563   : Exception(msg)
   2564 {}
   2565 void throwRuntimeError(std::string const& msg)
   2566 {
   2567   throw RuntimeError(msg);
   2568 }
   2569 void throwLogicError(std::string const& msg)
   2570 {
   2571   throw LogicError(msg);
   2572 }
   2573 
   2574 // //////////////////////////////////////////////////////////////////
   2575 // //////////////////////////////////////////////////////////////////
   2576 // //////////////////////////////////////////////////////////////////
   2577 // class Value::CommentInfo
   2578 // //////////////////////////////////////////////////////////////////
   2579 // //////////////////////////////////////////////////////////////////
   2580 // //////////////////////////////////////////////////////////////////
   2581 
   2582 Value::CommentInfo::CommentInfo() : comment_(0) {}
   2583 
   2584 Value::CommentInfo::~CommentInfo() {
   2585   if (comment_)
   2586     releaseStringValue(comment_);
   2587 }
   2588 
   2589 void Value::CommentInfo::setComment(const char* text, size_t len) {
   2590   if (comment_) {
   2591     releaseStringValue(comment_);
   2592     comment_ = 0;
   2593   }
   2594   JSON_ASSERT(text != 0);
   2595   JSON_ASSERT_MESSAGE(
   2596       text[0] == '\0' || text[0] == '/',
   2597       "in Json::Value::setComment(): Comments must start with /");
   2598   // It seems that /**/ style comments are acceptable as well.
   2599   comment_ = duplicateStringValue(text, len);
   2600 }
   2601 
   2602 // //////////////////////////////////////////////////////////////////
   2603 // //////////////////////////////////////////////////////////////////
   2604 // //////////////////////////////////////////////////////////////////
   2605 // class Value::CZString
   2606 // //////////////////////////////////////////////////////////////////
   2607 // //////////////////////////////////////////////////////////////////
   2608 // //////////////////////////////////////////////////////////////////
   2609 
   2610 // Notes: policy_ indicates if the string was allocated when
   2611 // a string is stored.
   2612 
   2613 Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {}
   2614 
   2615 Value::CZString::CZString(char const* str, unsigned length, DuplicationPolicy allocate)
   2616     : cstr_(str)
   2617 {
   2618   // allocate != duplicate
   2619   storage_.policy_ = allocate;
   2620   storage_.length_ = length;
   2621 }
   2622 
   2623 Value::CZString::CZString(const CZString& other)
   2624     : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
   2625                 ? duplicateStringValue(other.cstr_, other.storage_.length_)
   2626                 : other.cstr_)
   2627 {
   2628   storage_.policy_ = (other.cstr_
   2629                  ? (other.storage_.policy_ == noDuplication
   2630                      ? noDuplication : duplicate)
   2631                  : other.storage_.policy_);
   2632   storage_.length_ = other.storage_.length_;
   2633 }
   2634 
   2635 Value::CZString::~CZString() {
   2636   if (cstr_ && storage_.policy_ == duplicate)
   2637     releaseStringValue(const_cast<char*>(cstr_));
   2638 }
   2639 
   2640 void Value::CZString::swap(CZString& other) {
   2641   std::swap(cstr_, other.cstr_);
   2642   std::swap(index_, other.index_);
   2643 }
   2644 
   2645 Value::CZString& Value::CZString::operator=(CZString other) {
   2646   swap(other);
   2647   return *this;
   2648 }
   2649 
   2650 bool Value::CZString::operator<(const CZString& other) const {
   2651   if (!cstr_) return index_ < other.index_;
   2652   //return strcmp(cstr_, other.cstr_) < 0;
   2653   // Assume both are strings.
   2654   unsigned this_len = this->storage_.length_;
   2655   unsigned other_len = other.storage_.length_;
   2656   unsigned min_len = std::min(this_len, other_len);
   2657   int comp = memcmp(this->cstr_, other.cstr_, min_len);
   2658   if (comp < 0) return true;
   2659   if (comp > 0) return false;
   2660   return (this_len < other_len);
   2661 }
   2662 
   2663 bool Value::CZString::operator==(const CZString& other) const {
   2664   if (!cstr_) return index_ == other.index_;
   2665   //return strcmp(cstr_, other.cstr_) == 0;
   2666   // Assume both are strings.
   2667   unsigned this_len = this->storage_.length_;
   2668   unsigned other_len = other.storage_.length_;
   2669   if (this_len != other_len) return false;
   2670   int comp = memcmp(this->cstr_, other.cstr_, this_len);
   2671   return comp == 0;
   2672 }
   2673 
   2674 ArrayIndex Value::CZString::index() const { return index_; }
   2675 
   2676 //const char* Value::CZString::c_str() const { return cstr_; }
   2677 const char* Value::CZString::data() const { return cstr_; }
   2678 unsigned Value::CZString::length() const { return storage_.length_; }
   2679 bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; }
   2680 
   2681 // //////////////////////////////////////////////////////////////////
   2682 // //////////////////////////////////////////////////////////////////
   2683 // //////////////////////////////////////////////////////////////////
   2684 // class Value::Value
   2685 // //////////////////////////////////////////////////////////////////
   2686 // //////////////////////////////////////////////////////////////////
   2687 // //////////////////////////////////////////////////////////////////
   2688 
   2689 /*! \internal Default constructor initialization must be equivalent to:
   2690  * memset( this, 0, sizeof(Value) )
   2691  * This optimization is used in ValueInternalMap fast allocator.
   2692  */
   2693 Value::Value(ValueType type) {
   2694   initBasic(type);
   2695   switch (type) {
   2696   case nullValue:
   2697     break;
   2698   case intValue:
   2699   case uintValue:
   2700     value_.int_ = 0;
   2701     break;
   2702   case realValue:
   2703     value_.real_ = 0.0;
   2704     break;
   2705   case stringValue:
   2706     value_.string_ = 0;
   2707     break;
   2708   case arrayValue:
   2709   case objectValue:
   2710     value_.map_ = new ObjectValues();
   2711     break;
   2712   case booleanValue:
   2713     value_.bool_ = false;
   2714     break;
   2715   default:
   2716     JSON_ASSERT_UNREACHABLE;
   2717   }
   2718 }
   2719 
   2720 Value::Value(Int value) {
   2721   initBasic(intValue);
   2722   value_.int_ = value;
   2723 }
   2724 
   2725 Value::Value(UInt value) {
   2726   initBasic(uintValue);
   2727   value_.uint_ = value;
   2728 }
   2729 #if defined(JSON_HAS_INT64)
   2730 Value::Value(Int64 value) {
   2731   initBasic(intValue);
   2732   value_.int_ = value;
   2733 }
   2734 Value::Value(UInt64 value) {
   2735   initBasic(uintValue);
   2736   value_.uint_ = value;
   2737 }
   2738 #endif // defined(JSON_HAS_INT64)
   2739 
   2740 Value::Value(double value) {
   2741   initBasic(realValue);
   2742   value_.real_ = value;
   2743 }
   2744 
   2745 Value::Value(const char* value) {
   2746   initBasic(stringValue, true);
   2747   value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
   2748 }
   2749 
   2750 Value::Value(const char* beginValue, const char* endValue) {
   2751   initBasic(stringValue, true);
   2752   value_.string_ =
   2753       duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
   2754 }
   2755 
   2756 Value::Value(const std::string& value) {
   2757   initBasic(stringValue, true);
   2758   value_.string_ =
   2759       duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
   2760 }
   2761 
   2762 Value::Value(const StaticString& value) {
   2763   initBasic(stringValue);
   2764   value_.string_ = const_cast<char*>(value.c_str());
   2765 }
   2766 
   2767 #ifdef JSON_USE_CPPTL
   2768 Value::Value(const CppTL::ConstString& value) {
   2769   initBasic(stringValue, true);
   2770   value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
   2771 }
   2772 #endif
   2773 
   2774 Value::Value(bool value) {
   2775   initBasic(booleanValue);
   2776   value_.bool_ = value;
   2777 }
   2778 
   2779 Value::Value(Value const& other)
   2780     : type_(other.type_), allocated_(false)
   2781       ,
   2782       comments_(0), start_(other.start_), limit_(other.limit_)
   2783 {
   2784   switch (type_) {
   2785   case nullValue:
   2786   case intValue:
   2787   case uintValue:
   2788   case realValue:
   2789   case booleanValue:
   2790     value_ = other.value_;
   2791     break;
   2792   case stringValue:
   2793     if (other.value_.string_ && other.allocated_) {
   2794       unsigned len;
   2795       char const* str;
   2796       decodePrefixedString(other.allocated_, other.value_.string_,
   2797           &len, &str);
   2798       value_.string_ = duplicateAndPrefixStringValue(str, len);
   2799       allocated_ = true;
   2800     } else {
   2801       value_.string_ = other.value_.string_;
   2802       allocated_ = false;
   2803     }
   2804     break;
   2805   case arrayValue:
   2806   case objectValue:
   2807     value_.map_ = new ObjectValues(*other.value_.map_);
   2808     break;
   2809   default:
   2810     JSON_ASSERT_UNREACHABLE;
   2811   }
   2812   if (other.comments_) {
   2813     comments_ = new CommentInfo[numberOfCommentPlacement];
   2814     for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
   2815       const CommentInfo& otherComment = other.comments_[comment];
   2816       if (otherComment.comment_)
   2817         comments_[comment].setComment(
   2818             otherComment.comment_, strlen(otherComment.comment_));
   2819     }
   2820   }
   2821 }
   2822 
   2823 Value::~Value() {
   2824   switch (type_) {
   2825   case nullValue:
   2826   case intValue:
   2827   case uintValue:
   2828   case realValue:
   2829   case booleanValue:
   2830     break;
   2831   case stringValue:
   2832     if (allocated_)
   2833       releaseStringValue(value_.string_);
   2834     break;
   2835   case arrayValue:
   2836   case objectValue:
   2837     delete value_.map_;
   2838     break;
   2839   default:
   2840     JSON_ASSERT_UNREACHABLE;
   2841   }
   2842 
   2843   if (comments_)
   2844     delete[] comments_;
   2845 }
   2846 
   2847 Value& Value::operator=(Value other) {
   2848   swap(other);
   2849   return *this;
   2850 }
   2851 
   2852 void Value::swapPayload(Value& other) {
   2853   ValueType temp = type_;
   2854   type_ = other.type_;
   2855   other.type_ = temp;
   2856   std::swap(value_, other.value_);
   2857   int temp2 = allocated_;
   2858   allocated_ = other.allocated_;
   2859   other.allocated_ = temp2;
   2860 }
   2861 
   2862 void Value::swap(Value& other) {
   2863   swapPayload(other);
   2864   std::swap(comments_, other.comments_);
   2865   std::swap(start_, other.start_);
   2866   std::swap(limit_, other.limit_);
   2867 }
   2868 
   2869 ValueType Value::type() const { return type_; }
   2870 
   2871 int Value::compare(const Value& other) const {
   2872   if (*this < other)
   2873     return -1;
   2874   if (*this > other)
   2875     return 1;
   2876   return 0;
   2877 }
   2878 
   2879 bool Value::operator<(const Value& other) const {
   2880   int typeDelta = type_ - other.type_;
   2881   if (typeDelta)
   2882     return typeDelta < 0 ? true : false;
   2883   switch (type_) {
   2884   case nullValue:
   2885     return false;
   2886   case intValue:
   2887     return value_.int_ < other.value_.int_;
   2888   case uintValue:
   2889     return value_.uint_ < other.value_.uint_;
   2890   case realValue:
   2891     return value_.real_ < other.value_.real_;
   2892   case booleanValue:
   2893     return value_.bool_ < other.value_.bool_;
   2894   case stringValue:
   2895   {
   2896     if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
   2897       if (other.value_.string_) return true;
   2898       else return false;
   2899     }
   2900     unsigned this_len;
   2901     unsigned other_len;
   2902     char const* this_str;
   2903     char const* other_str;
   2904     decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
   2905     decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
   2906     unsigned min_len = std::min(this_len, other_len);
   2907     int comp = memcmp(this_str, other_str, min_len);
   2908     if (comp < 0) return true;
   2909     if (comp > 0) return false;
   2910     return (this_len < other_len);
   2911   }
   2912   case arrayValue:
   2913   case objectValue: {
   2914     int delta = int(value_.map_->size() - other.value_.map_->size());
   2915     if (delta)
   2916       return delta < 0;
   2917     return (*value_.map_) < (*other.value_.map_);
   2918   }
   2919   default:
   2920     JSON_ASSERT_UNREACHABLE;
   2921   }
   2922   return false; // unreachable
   2923 }
   2924 
   2925 bool Value::operator<=(const Value& other) const { return !(other < *this); }
   2926 
   2927 bool Value::operator>=(const Value& other) const { return !(*this < other); }
   2928 
   2929 bool Value::operator>(const Value& other) const { return other < *this; }
   2930 
   2931 bool Value::operator==(const Value& other) const {
   2932   // if ( type_ != other.type_ )
   2933   // GCC 2.95.3 says:
   2934   // attempt to take address of bit-field structure member `Json::Value::type_'
   2935   // Beats me, but a temp solves the problem.
   2936   int temp = other.type_;
   2937   if (type_ != temp)
   2938     return false;
   2939   switch (type_) {
   2940   case nullValue:
   2941     return true;
   2942   case intValue:
   2943     return value_.int_ == other.value_.int_;
   2944   case uintValue:
   2945     return value_.uint_ == other.value_.uint_;
   2946   case realValue:
   2947     return value_.real_ == other.value_.real_;
   2948   case booleanValue:
   2949     return value_.bool_ == other.value_.bool_;
   2950   case stringValue:
   2951   {
   2952     if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
   2953       return (value_.string_ == other.value_.string_);
   2954     }
   2955     unsigned this_len;
   2956     unsigned other_len;
   2957     char const* this_str;
   2958     char const* other_str;
   2959     decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
   2960     decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
   2961     if (this_len != other_len) return false;
   2962     int comp = memcmp(this_str, other_str, this_len);
   2963     return comp == 0;
   2964   }
   2965   case arrayValue:
   2966   case objectValue:
   2967     return value_.map_->size() == other.value_.map_->size() &&
   2968            (*value_.map_) == (*other.value_.map_);
   2969   default:
   2970     JSON_ASSERT_UNREACHABLE;
   2971   }
   2972   return false; // unreachable
   2973 }
   2974 
   2975 bool Value::operator!=(const Value& other) const { return !(*this == other); }
   2976 
   2977 const char* Value::asCString() const {
   2978   JSON_ASSERT_MESSAGE(type_ == stringValue,
   2979                       "in Json::Value::asCString(): requires stringValue");
   2980   if (value_.string_ == 0) return 0;
   2981   unsigned this_len;
   2982   char const* this_str;
   2983   decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
   2984   return this_str;
   2985 }
   2986 
   2987 bool Value::getString(char const** str, char const** end) const {
   2988   if (type_ != stringValue) return false;
   2989   if (value_.string_ == 0) return false;
   2990   unsigned length;
   2991   decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
   2992   *end = *str + length;
   2993   return true;
   2994 }
   2995 
   2996 std::string Value::asString() const {
   2997   switch (type_) {
   2998   case nullValue:
   2999     return "";
   3000   case stringValue:
   3001   {
   3002     if (value_.string_ == 0) return "";
   3003     unsigned this_len;
   3004     char const* this_str;
   3005     decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
   3006     return std::string(this_str, this_len);
   3007   }
   3008   case booleanValue:
   3009     return value_.bool_ ? "true" : "false";
   3010   case intValue:
   3011     return valueToString(value_.int_);
   3012   case uintValue:
   3013     return valueToString(value_.uint_);
   3014   case realValue:
   3015     return valueToString(value_.real_);
   3016   default:
   3017     JSON_FAIL_MESSAGE("Type is not convertible to string");
   3018   }
   3019 }
   3020 
   3021 #ifdef JSON_USE_CPPTL
   3022 CppTL::ConstString Value::asConstString() const {
   3023   unsigned len;
   3024   char const* str;
   3025   decodePrefixedString(allocated_, value_.string_,
   3026       &len, &str);
   3027   return CppTL::ConstString(str, len);
   3028 }
   3029 #endif
   3030 
   3031 Value::Int Value::asInt() const {
   3032   switch (type_) {
   3033   case intValue:
   3034     JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
   3035     return Int(value_.int_);
   3036   case uintValue:
   3037     JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
   3038     return Int(value_.uint_);
   3039   case realValue:
   3040     JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
   3041                         "double out of Int range");
   3042     return Int(value_.real_);
   3043   case nullValue:
   3044     return 0;
   3045   case booleanValue:
   3046     return value_.bool_ ? 1 : 0;
   3047   default:
   3048     break;
   3049   }
   3050   JSON_FAIL_MESSAGE("Value is not convertible to Int.");
   3051 }
   3052 
   3053 Value::UInt Value::asUInt() const {
   3054   switch (type_) {
   3055   case intValue:
   3056     JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
   3057     return UInt(value_.int_);
   3058   case uintValue:
   3059     JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
   3060     return UInt(value_.uint_);
   3061   case realValue:
   3062     JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
   3063                         "double out of UInt range");
   3064     return UInt(value_.real_);
   3065   case nullValue:
   3066     return 0;
   3067   case booleanValue:
   3068     return value_.bool_ ? 1 : 0;
   3069   default:
   3070     break;
   3071   }
   3072   JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
   3073 }
   3074 
   3075 #if defined(JSON_HAS_INT64)
   3076 
   3077 Value::Int64 Value::asInt64() const {
   3078   switch (type_) {
   3079   case intValue:
   3080     return Int64(value_.int_);
   3081   case uintValue:
   3082     JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
   3083     return Int64(value_.uint_);
   3084   case realValue:
   3085     JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
   3086                         "double out of Int64 range");
   3087     return Int64(value_.real_);
   3088   case nullValue:
   3089     return 0;
   3090   case booleanValue:
   3091     return value_.bool_ ? 1 : 0;
   3092   default:
   3093     break;
   3094   }
   3095   JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
   3096 }
   3097 
   3098 Value::UInt64 Value::asUInt64() const {
   3099   switch (type_) {
   3100   case intValue:
   3101     JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
   3102     return UInt64(value_.int_);
   3103   case uintValue:
   3104     return UInt64(value_.uint_);
   3105   case realValue:
   3106     JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
   3107                         "double out of UInt64 range");
   3108     return UInt64(value_.real_);
   3109   case nullValue:
   3110     return 0;
   3111   case booleanValue:
   3112     return value_.bool_ ? 1 : 0;
   3113   default:
   3114     break;
   3115   }
   3116   JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
   3117 }
   3118 #endif // if defined(JSON_HAS_INT64)
   3119 
   3120 LargestInt Value::asLargestInt() const {
   3121 #if defined(JSON_NO_INT64)
   3122   return asInt();
   3123 #else
   3124   return asInt64();
   3125 #endif
   3126 }
   3127 
   3128 LargestUInt Value::asLargestUInt() const {
   3129 #if defined(JSON_NO_INT64)
   3130   return asUInt();
   3131 #else
   3132   return asUInt64();
   3133 #endif
   3134 }
   3135 
   3136 double Value::asDouble() const {
   3137   switch (type_) {
   3138   case intValue:
   3139     return static_cast<double>(value_.int_);
   3140   case uintValue:
   3141 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
   3142     return static_cast<double>(value_.uint_);
   3143 #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
   3144     return integerToDouble(value_.uint_);
   3145 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
   3146   case realValue:
   3147     return value_.real_;
   3148   case nullValue:
   3149     return 0.0;
   3150   case booleanValue:
   3151     return value_.bool_ ? 1.0 : 0.0;
   3152   default:
   3153     break;
   3154   }
   3155   JSON_FAIL_MESSAGE("Value is not convertible to double.");
   3156 }
   3157 
   3158 float Value::asFloat() const {
   3159   switch (type_) {
   3160   case intValue:
   3161     return static_cast<float>(value_.int_);
   3162   case uintValue:
   3163 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
   3164     return static_cast<float>(value_.uint_);
   3165 #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
   3166     return integerToDouble(value_.uint_);
   3167 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
   3168   case realValue:
   3169     return static_cast<float>(value_.real_);
   3170   case nullValue:
   3171     return 0.0;
   3172   case booleanValue:
   3173     return value_.bool_ ? 1.0f : 0.0f;
   3174   default:
   3175     break;
   3176   }
   3177   JSON_FAIL_MESSAGE("Value is not convertible to float.");
   3178 }
   3179 
   3180 bool Value::asBool() const {
   3181   switch (type_) {
   3182   case booleanValue:
   3183     return value_.bool_;
   3184   case nullValue:
   3185     return false;
   3186   case intValue:
   3187     return value_.int_ ? true : false;
   3188   case uintValue:
   3189     return value_.uint_ ? true : false;
   3190   case realValue:
   3191     return value_.real_ ? true : false;
   3192   default:
   3193     break;
   3194   }
   3195   JSON_FAIL_MESSAGE("Value is not convertible to bool.");
   3196 }
   3197 
   3198 bool Value::isConvertibleTo(ValueType other) const {
   3199   switch (other) {
   3200   case nullValue:
   3201     return (isNumeric() && asDouble() == 0.0) ||
   3202            (type_ == booleanValue && value_.bool_ == false) ||
   3203            (type_ == stringValue && asString() == "") ||
   3204            (type_ == arrayValue && value_.map_->size() == 0) ||
   3205            (type_ == objectValue && value_.map_->size() == 0) ||
   3206            type_ == nullValue;
   3207   case intValue:
   3208     return isInt() ||
   3209            (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
   3210            type_ == booleanValue || type_ == nullValue;
   3211   case uintValue:
   3212     return isUInt() ||
   3213            (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
   3214            type_ == booleanValue || type_ == nullValue;
   3215   case realValue:
   3216     return isNumeric() || type_ == booleanValue || type_ == nullValue;
   3217   case booleanValue:
   3218     return isNumeric() || type_ == booleanValue || type_ == nullValue;
   3219   case stringValue:
   3220     return isNumeric() || type_ == booleanValue || type_ == stringValue ||
   3221            type_ == nullValue;
   3222   case arrayValue:
   3223     return type_ == arrayValue || type_ == nullValue;
   3224   case objectValue:
   3225     return type_ == objectValue || type_ == nullValue;
   3226   }
   3227   JSON_ASSERT_UNREACHABLE;
   3228   return false;
   3229 }
   3230 
   3231 /// Number of values in array or object
   3232 ArrayIndex Value::size() const {
   3233   switch (type_) {
   3234   case nullValue:
   3235   case intValue:
   3236   case uintValue:
   3237   case realValue:
   3238   case booleanValue:
   3239   case stringValue:
   3240     return 0;
   3241   case arrayValue: // size of the array is highest index + 1
   3242     if (!value_.map_->empty()) {
   3243       ObjectValues::const_iterator itLast = value_.map_->end();
   3244       --itLast;
   3245       return (*itLast).first.index() + 1;
   3246     }
   3247     return 0;
   3248   case objectValue:
   3249     return ArrayIndex(value_.map_->size());
   3250   }
   3251   JSON_ASSERT_UNREACHABLE;
   3252   return 0; // unreachable;
   3253 }
   3254 
   3255 bool Value::empty() const {
   3256   if (isNull() || isArray() || isObject())
   3257     return size() == 0u;
   3258   else
   3259     return false;
   3260 }
   3261 
   3262 bool Value::operator!() const { return isNull(); }
   3263 
   3264 void Value::clear() {
   3265   JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
   3266                           type_ == objectValue,
   3267                       "in Json::Value::clear(): requires complex value");
   3268   start_ = 0;
   3269   limit_ = 0;
   3270   switch (type_) {
   3271   case arrayValue:
   3272   case objectValue:
   3273     value_.map_->clear();
   3274     break;
   3275   default:
   3276     break;
   3277   }
   3278 }
   3279 
   3280 void Value::resize(ArrayIndex newSize) {
   3281   JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
   3282                       "in Json::Value::resize(): requires arrayValue");
   3283   if (type_ == nullValue)
   3284     *this = Value(arrayValue);
   3285   ArrayIndex oldSize = size();
   3286   if (newSize == 0)
   3287     clear();
   3288   else if (newSize > oldSize)
   3289     (*this)[newSize - 1];
   3290   else {
   3291     for (ArrayIndex index = newSize; index < oldSize; ++index) {
   3292       value_.map_->erase(index);
   3293     }
   3294     assert(size() == newSize);
   3295   }
   3296 }
   3297 
   3298 Value& Value::operator[](ArrayIndex index) {
   3299   JSON_ASSERT_MESSAGE(
   3300       type_ == nullValue || type_ == arrayValue,
   3301       "in Json::Value::operator[](ArrayIndex): requires arrayValue");
   3302   if (type_ == nullValue)
   3303     *this = Value(arrayValue);
   3304   CZString key(index);
   3305   ObjectValues::iterator it = value_.map_->lower_bound(key);
   3306   if (it != value_.map_->end() && (*it).first == key)
   3307     return (*it).second;
   3308 
   3309   ObjectValues::value_type defaultValue(key, nullRef);
   3310   it = value_.map_->insert(it, defaultValue);
   3311   return (*it).second;
   3312 }
   3313 
   3314 Value& Value::operator[](int index) {
   3315   JSON_ASSERT_MESSAGE(
   3316       index >= 0,
   3317       "in Json::Value::operator[](int index): index cannot be negative");
   3318   return (*this)[ArrayIndex(index)];
   3319 }
   3320 
   3321 const Value& Value::operator[](ArrayIndex index) const {
   3322   JSON_ASSERT_MESSAGE(
   3323       type_ == nullValue || type_ == arrayValue,
   3324       "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
   3325   if (type_ == nullValue)
   3326     return nullRef;
   3327   CZString key(index);
   3328   ObjectValues::const_iterator it = value_.map_->find(key);
   3329   if (it == value_.map_->end())
   3330     return nullRef;
   3331   return (*it).second;
   3332 }
   3333 
   3334 const Value& Value::operator[](int index) const {
   3335   JSON_ASSERT_MESSAGE(
   3336       index >= 0,
   3337       "in Json::Value::operator[](int index) const: index cannot be negative");
   3338   return (*this)[ArrayIndex(index)];
   3339 }
   3340 
   3341 void Value::initBasic(ValueType type, bool allocated) {
   3342   type_ = type;
   3343   allocated_ = allocated;
   3344   comments_ = 0;
   3345   start_ = 0;
   3346   limit_ = 0;
   3347 }
   3348 
   3349 // Access an object value by name, create a null member if it does not exist.
   3350 // @pre Type of '*this' is object or null.
   3351 // @param key is null-terminated.
   3352 Value& Value::resolveReference(const char* key) {
   3353   JSON_ASSERT_MESSAGE(
   3354       type_ == nullValue || type_ == objectValue,
   3355       "in Json::Value::resolveReference(): requires objectValue");
   3356   if (type_ == nullValue)
   3357     *this = Value(objectValue);
   3358   CZString actualKey(
   3359       key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!
   3360   ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
   3361   if (it != value_.map_->end() && (*it).first == actualKey)
   3362     return (*it).second;
   3363 
   3364   ObjectValues::value_type defaultValue(actualKey, nullRef);
   3365   it = value_.map_->insert(it, defaultValue);
   3366   Value& value = (*it).second;
   3367   return value;
   3368 }
   3369 
   3370 // @param key is not null-terminated.
   3371 Value& Value::resolveReference(char const* key, char const* end)
   3372 {
   3373   JSON_ASSERT_MESSAGE(
   3374       type_ == nullValue || type_ == objectValue,
   3375       "in Json::Value::resolveReference(key, end): requires objectValue");
   3376   if (type_ == nullValue)
   3377     *this = Value(objectValue);
   3378   CZString actualKey(
   3379       key, static_cast<unsigned>(end-key), CZString::duplicateOnCopy);
   3380   ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
   3381   if (it != value_.map_->end() && (*it).first == actualKey)
   3382     return (*it).second;
   3383 
   3384   ObjectValues::value_type defaultValue(actualKey, nullRef);
   3385   it = value_.map_->insert(it, defaultValue);
   3386   Value& value = (*it).second;
   3387   return value;
   3388 }
   3389 
   3390 Value Value::get(ArrayIndex index, const Value& defaultValue) const {
   3391   const Value* value = &((*this)[index]);
   3392   return value == &nullRef ? defaultValue : *value;
   3393 }
   3394 
   3395 bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
   3396 
   3397 Value const* Value::find(char const* key, char const* end) const
   3398 {
   3399   JSON_ASSERT_MESSAGE(
   3400       type_ == nullValue || type_ == objectValue,
   3401       "in Json::Value::find(key, end, found): requires objectValue or nullValue");
   3402   if (type_ == nullValue) return NULL;
   3403   CZString actualKey(key, static_cast<unsigned>(end-key), CZString::noDuplication);
   3404   ObjectValues::const_iterator it = value_.map_->find(actualKey);
   3405   if (it == value_.map_->end()) return NULL;
   3406   return &(*it).second;
   3407 }
   3408 const Value& Value::operator[](const char* key) const
   3409 {
   3410   Value const* found = find(key, key + strlen(key));
   3411   if (!found) return nullRef;
   3412   return *found;
   3413 }
   3414 Value const& Value::operator[](std::string const& key) const
   3415 {
   3416   Value const* found = find(key.data(), key.data() + key.length());
   3417   if (!found) return nullRef;
   3418   return *found;
   3419 }
   3420 
   3421 Value& Value::operator[](const char* key) {
   3422   return resolveReference(key, key + strlen(key));
   3423 }
   3424 
   3425 Value& Value::operator[](const std::string& key) {
   3426   return resolveReference(key.data(), key.data() + key.length());
   3427 }
   3428 
   3429 Value& Value::operator[](const StaticString& key) {
   3430   return resolveReference(key.c_str());
   3431 }
   3432 
   3433 #ifdef JSON_USE_CPPTL
   3434 Value& Value::operator[](const CppTL::ConstString& key) {
   3435   return resolveReference(key.c_str(), key.end_c_str());
   3436 }
   3437 Value const& Value::operator[](CppTL::ConstString const& key) const
   3438 {
   3439   Value const* found = find(key.c_str(), key.end_c_str());
   3440   if (!found) return nullRef;
   3441   return *found;
   3442 }
   3443 #endif
   3444 
   3445 Value& Value::append(const Value& value) { return (*this)[size()] = value; }
   3446 
   3447 Value Value::get(char const* key, char const* end, Value const& defaultValue) const
   3448 {
   3449   Value const* found = find(key, end);
   3450   return !found ? defaultValue : *found;
   3451 }
   3452 Value Value::get(char const* key, Value const& defaultValue) const
   3453 {
   3454   return get(key, key + strlen(key), defaultValue);
   3455 }
   3456 Value Value::get(std::string const& key, Value const& defaultValue) const
   3457 {
   3458   return get(key.data(), key.data() + key.length(), defaultValue);
   3459 }
   3460 
   3461 
   3462 bool Value::removeMember(const char* key, const char* end, Value* removed)
   3463 {
   3464   if (type_ != objectValue) {
   3465     return false;
   3466   }
   3467   CZString actualKey(key, static_cast<unsigned>(end-key), CZString::noDuplication);
   3468   ObjectValues::iterator it = value_.map_->find(actualKey);
   3469   if (it == value_.map_->end())
   3470     return false;
   3471   *removed = it->second;
   3472   value_.map_->erase(it);
   3473   return true;
   3474 }
   3475 bool Value::removeMember(const char* key, Value* removed)
   3476 {
   3477   return removeMember(key, key + strlen(key), removed);
   3478 }
   3479 bool Value::removeMember(std::string const& key, Value* removed)
   3480 {
   3481   return removeMember(key.data(), key.data() + key.length(), removed);
   3482 }
   3483 Value Value::removeMember(const char* key)
   3484 {
   3485   JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
   3486                       "in Json::Value::removeMember(): requires objectValue");
   3487   if (type_ == nullValue)
   3488     return nullRef;
   3489 
   3490   Value removed;  // null
   3491   removeMember(key, key + strlen(key), &removed);
   3492   return removed; // still null if removeMember() did nothing
   3493 }
   3494 Value Value::removeMember(const std::string& key)
   3495 {
   3496   return removeMember(key.c_str());
   3497 }
   3498 
   3499 bool Value::removeIndex(ArrayIndex index, Value* removed) {
   3500   if (type_ != arrayValue) {
   3501     return false;
   3502   }
   3503   CZString key(index);
   3504   ObjectValues::iterator it = value_.map_->find(key);
   3505   if (it == value_.map_->end()) {
   3506     return false;
   3507   }
   3508   *removed = it->second;
   3509   ArrayIndex oldSize = size();
   3510   // shift left all items left, into the place of the "removed"
   3511   for (ArrayIndex i = index; i < (oldSize - 1); ++i){
   3512     CZString key(i);
   3513     (*value_.map_)[key] = (*this)[i + 1];
   3514   }
   3515   // erase the last one ("leftover")
   3516   CZString keyLast(oldSize - 1);
   3517   ObjectValues::iterator itLast = value_.map_->find(keyLast);
   3518   value_.map_->erase(itLast);
   3519   return true;
   3520 }
   3521 
   3522 #ifdef JSON_USE_CPPTL
   3523 Value Value::get(const CppTL::ConstString& key,
   3524                  const Value& defaultValue) const {
   3525   return get(key.c_str(), key.end_c_str(), defaultValue);
   3526 }
   3527 #endif
   3528 
   3529 bool Value::isMember(char const* key, char const* end) const
   3530 {
   3531   Value const* value = find(key, end);
   3532   return NULL != value;
   3533 }
   3534 bool Value::isMember(char const* key) const
   3535 {
   3536   return isMember(key, key + strlen(key));
   3537 }
   3538 bool Value::isMember(std::string const& key) const
   3539 {
   3540   return isMember(key.data(), key.data() + key.length());
   3541 }
   3542 
   3543 #ifdef JSON_USE_CPPTL
   3544 bool Value::isMember(const CppTL::ConstString& key) const {
   3545   return isMember(key.c_str(), key.end_c_str());
   3546 }
   3547 #endif
   3548 
   3549 Value::Members Value::getMemberNames() const {
   3550   JSON_ASSERT_MESSAGE(
   3551       type_ == nullValue || type_ == objectValue,
   3552       "in Json::Value::getMemberNames(), value must be objectValue");
   3553   if (type_ == nullValue)
   3554     return Value::Members();
   3555   Members members;
   3556   members.reserve(value_.map_->size());
   3557   ObjectValues::const_iterator it = value_.map_->begin();
   3558   ObjectValues::const_iterator itEnd = value_.map_->end();
   3559   for (; it != itEnd; ++it) {
   3560     members.push_back(std::string((*it).first.data(),
   3561                                   (*it).first.length()));
   3562   }
   3563   return members;
   3564 }
   3565 //
   3566 //# ifdef JSON_USE_CPPTL
   3567 // EnumMemberNames
   3568 // Value::enumMemberNames() const
   3569 //{
   3570 //   if ( type_ == objectValue )
   3571 //   {
   3572 //      return CppTL::Enum::any(  CppTL::Enum::transform(
   3573 //         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
   3574 //         MemberNamesTransform() ) );
   3575 //   }
   3576 //   return EnumMemberNames();
   3577 //}
   3578 //
   3579 //
   3580 // EnumValues
   3581 // Value::enumValues() const
   3582 //{
   3583 //   if ( type_ == objectValue  ||  type_ == arrayValue )
   3584 //      return CppTL::Enum::anyValues( *(value_.map_),
   3585 //                                     CppTL::Type<const Value &>() );
   3586 //   return EnumValues();
   3587 //}
   3588 //
   3589 //# endif
   3590 
   3591 static bool IsIntegral(double d) {
   3592   double integral_part;
   3593   return modf(d, &integral_part) == 0.0;
   3594 }
   3595 
   3596 bool Value::isNull() const { return type_ == nullValue; }
   3597 
   3598 bool Value::isBool() const { return type_ == booleanValue; }
   3599 
   3600 bool Value::isInt() const {
   3601   switch (type_) {
   3602   case intValue:
   3603     return value_.int_ >= minInt && value_.int_ <= maxInt;
   3604   case uintValue:
   3605     return value_.uint_ <= UInt(maxInt);
   3606   case realValue:
   3607     return value_.real_ >= minInt && value_.real_ <= maxInt &&
   3608            IsIntegral(value_.real_);
   3609   default:
   3610     break;
   3611   }
   3612   return false;
   3613 }
   3614 
   3615 bool Value::isUInt() const {
   3616   switch (type_) {
   3617   case intValue:
   3618     return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
   3619   case uintValue:
   3620     return value_.uint_ <= maxUInt;
   3621   case realValue:
   3622     return value_.real_ >= 0 && value_.real_ <= maxUInt &&
   3623            IsIntegral(value_.real_);
   3624   default:
   3625     break;
   3626   }
   3627   return false;
   3628 }
   3629 
   3630 bool Value::isInt64() const {
   3631 #if defined(JSON_HAS_INT64)
   3632   switch (type_) {
   3633   case intValue:
   3634     return true;
   3635   case uintValue:
   3636     return value_.uint_ <= UInt64(maxInt64);
   3637   case realValue:
   3638     // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
   3639     // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
   3640     // require the value to be strictly less than the limit.
   3641     return value_.real_ >= double(minInt64) &&
   3642            value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
   3643   default:
   3644     break;
   3645   }
   3646 #endif // JSON_HAS_INT64
   3647   return false;
   3648 }
   3649 
   3650 bool Value::isUInt64() const {
   3651 #if defined(JSON_HAS_INT64)
   3652   switch (type_) {
   3653   case intValue:
   3654     return value_.int_ >= 0;
   3655   case uintValue:
   3656     return true;
   3657   case realValue:
   3658     // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
   3659     // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
   3660     // require the value to be strictly less than the limit.
   3661     return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
   3662            IsIntegral(value_.real_);
   3663   default:
   3664     break;
   3665   }
   3666 #endif // JSON_HAS_INT64
   3667   return false;
   3668 }
   3669 
   3670 bool Value::isIntegral() const {
   3671 #if defined(JSON_HAS_INT64)
   3672   return isInt64() || isUInt64();
   3673 #else
   3674   return isInt() || isUInt();
   3675 #endif
   3676 }
   3677 
   3678 bool Value::isDouble() const { return type_ == realValue || isIntegral(); }
   3679 
   3680 bool Value::isNumeric() const { return isIntegral() || isDouble(); }
   3681 
   3682 bool Value::isString() const { return type_ == stringValue; }
   3683 
   3684 bool Value::isArray() const { return type_ == arrayValue; }
   3685 
   3686 bool Value::isObject() const { return type_ == objectValue; }
   3687 
   3688 void Value::setComment(const char* comment, size_t len, CommentPlacement placement) {
   3689   if (!comments_)
   3690     comments_ = new CommentInfo[numberOfCommentPlacement];
   3691   if ((len > 0) && (comment[len-1] == '\n')) {
   3692     // Always discard trailing newline, to aid indentation.
   3693     len -= 1;
   3694   }
   3695   comments_[placement].setComment(comment, len);
   3696 }
   3697 
   3698 void Value::setComment(const char* comment, CommentPlacement placement) {
   3699   setComment(comment, strlen(comment), placement);
   3700 }
   3701 
   3702 void Value::setComment(const std::string& comment, CommentPlacement placement) {
   3703   setComment(comment.c_str(), comment.length(), placement);
   3704 }
   3705 
   3706 bool Value::hasComment(CommentPlacement placement) const {
   3707   return comments_ != 0 && comments_[placement].comment_ != 0;
   3708 }
   3709 
   3710 std::string Value::getComment(CommentPlacement placement) const {
   3711   if (hasComment(placement))
   3712     return comments_[placement].comment_;
   3713   return "";
   3714 }
   3715 
   3716 void Value::setOffsetStart(size_t start) { start_ = start; }
   3717 
   3718 void Value::setOffsetLimit(size_t limit) { limit_ = limit; }
   3719 
   3720 size_t Value::getOffsetStart() const { return start_; }
   3721 
   3722 size_t Value::getOffsetLimit() const { return limit_; }
   3723 
   3724 std::string Value::toStyledString() const {
   3725   StyledWriter writer;
   3726   return writer.write(*this);
   3727 }
   3728 
   3729 Value::const_iterator Value::begin() const {
   3730   switch (type_) {
   3731   case arrayValue:
   3732   case objectValue:
   3733     if (value_.map_)
   3734       return const_iterator(value_.map_->begin());
   3735     break;
   3736   default:
   3737     break;
   3738   }
   3739   return const_iterator();
   3740 }
   3741 
   3742 Value::const_iterator Value::end() const {
   3743   switch (type_) {
   3744   case arrayValue:
   3745   case objectValue:
   3746     if (value_.map_)
   3747       return const_iterator(value_.map_->end());
   3748     break;
   3749   default:
   3750     break;
   3751   }
   3752   return const_iterator();
   3753 }
   3754 
   3755 Value::iterator Value::begin() {
   3756   switch (type_) {
   3757   case arrayValue:
   3758   case objectValue:
   3759     if (value_.map_)
   3760       return iterator(value_.map_->begin());
   3761     break;
   3762   default:
   3763     break;
   3764   }
   3765   return iterator();
   3766 }
   3767 
   3768 Value::iterator Value::end() {
   3769   switch (type_) {
   3770   case arrayValue:
   3771   case objectValue:
   3772     if (value_.map_)
   3773       return iterator(value_.map_->end());
   3774     break;
   3775   default:
   3776     break;
   3777   }
   3778   return iterator();
   3779 }
   3780 
   3781 // class PathArgument
   3782 // //////////////////////////////////////////////////////////////////
   3783 
   3784 PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
   3785 
   3786 PathArgument::PathArgument(ArrayIndex index)
   3787     : key_(), index_(index), kind_(kindIndex) {}
   3788 
   3789 PathArgument::PathArgument(const char* key)
   3790     : key_(key), index_(), kind_(kindKey) {}
   3791 
   3792 PathArgument::PathArgument(const std::string& key)
   3793     : key_(key.c_str()), index_(), kind_(kindKey) {}
   3794 
   3795 // class Path
   3796 // //////////////////////////////////////////////////////////////////
   3797 
   3798 Path::Path(const std::string& path,
   3799            const PathArgument& a1,
   3800            const PathArgument& a2,
   3801            const PathArgument& a3,
   3802            const PathArgument& a4,
   3803            const PathArgument& a5) {
   3804   InArgs in;
   3805   in.push_back(&a1);
   3806   in.push_back(&a2);
   3807   in.push_back(&a3);
   3808   in.push_back(&a4);
   3809   in.push_back(&a5);
   3810   makePath(path, in);
   3811 }
   3812 
   3813 void Path::makePath(const std::string& path, const InArgs& in) {
   3814   const char* current = path.c_str();
   3815   const char* end = current + path.length();
   3816   InArgs::const_iterator itInArg = in.begin();
   3817   while (current != end) {
   3818     if (*current == '[') {
   3819       ++current;
   3820       if (*current == '%')
   3821         addPathInArg(path, in, itInArg, PathArgument::kindIndex);
   3822       else {
   3823         ArrayIndex index = 0;
   3824         for (; current != end && *current >= '0' && *current <= '9'; ++current)
   3825           index = index * 10 + ArrayIndex(*current - '0');
   3826         args_.push_back(index);
   3827       }
   3828       if (current == end || *current++ != ']')
   3829         invalidPath(path, int(current - path.c_str()));
   3830     } else if (*current == '%') {
   3831       addPathInArg(path, in, itInArg, PathArgument::kindKey);
   3832       ++current;
   3833     } else if (*current == '.') {
   3834       ++current;
   3835     } else {
   3836       const char* beginName = current;
   3837       while (current != end && !strchr("[.", *current))
   3838         ++current;
   3839       args_.push_back(std::string(beginName, current));
   3840     }
   3841   }
   3842 }
   3843 
   3844 void Path::addPathInArg(const std::string& /*path*/,
   3845                         const InArgs& in,
   3846                         InArgs::const_iterator& itInArg,
   3847                         PathArgument::Kind kind) {
   3848   if (itInArg == in.end()) {
   3849     // Error: missing argument %d
   3850   } else if ((*itInArg)->kind_ != kind) {
   3851     // Error: bad argument type
   3852   } else {
   3853     args_.push_back(**itInArg);
   3854   }
   3855 }
   3856 
   3857 void Path::invalidPath(const std::string& /*path*/, int /*location*/) {
   3858   // Error: invalid path.
   3859 }
   3860 
   3861 const Value& Path::resolve(const Value& root) const {
   3862   const Value* node = &root;
   3863   for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
   3864     const PathArgument& arg = *it;
   3865     if (arg.kind_ == PathArgument::kindIndex) {
   3866       if (!node->isArray() || !node->isValidIndex(arg.index_)) {
   3867         // Error: unable to resolve path (array value expected at position...
   3868       }
   3869       node = &((*node)[arg.index_]);
   3870     } else if (arg.kind_ == PathArgument::kindKey) {
   3871       if (!node->isObject()) {
   3872         // Error: unable to resolve path (object value expected at position...)
   3873       }
   3874       node = &((*node)[arg.key_]);
   3875       if (node == &Value::nullRef) {
   3876         // Error: unable to resolve path (object has no member named '' at
   3877         // position...)
   3878       }
   3879     }
   3880   }
   3881   return *node;
   3882 }
   3883 
   3884 Value Path::resolve(const Value& root, const Value& defaultValue) const {
   3885   const Value* node = &root;
   3886   for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
   3887     const PathArgument& arg = *it;
   3888     if (arg.kind_ == PathArgument::kindIndex) {
   3889       if (!node->isArray() || !node->isValidIndex(arg.index_))
   3890         return defaultValue;
   3891       node = &((*node)[arg.index_]);
   3892     } else if (arg.kind_ == PathArgument::kindKey) {
   3893       if (!node->isObject())
   3894         return defaultValue;
   3895       node = &((*node)[arg.key_]);
   3896       if (node == &Value::nullRef)
   3897         return defaultValue;
   3898     }
   3899   }
   3900   return *node;
   3901 }
   3902 
   3903 Value& Path::make(Value& root) const {
   3904   Value* node = &root;
   3905   for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
   3906     const PathArgument& arg = *it;
   3907     if (arg.kind_ == PathArgument::kindIndex) {
   3908       if (!node->isArray()) {
   3909         // Error: node is not an array at position ...
   3910       }
   3911       node = &((*node)[arg.index_]);
   3912     } else if (arg.kind_ == PathArgument::kindKey) {
   3913       if (!node->isObject()) {
   3914         // Error: node is not an object at position...
   3915       }
   3916       node = &((*node)[arg.key_]);
   3917     }
   3918   }
   3919   return *node;
   3920 }
   3921 
   3922 } // namespace Json
   3923 
   3924 // //////////////////////////////////////////////////////////////////////
   3925 // End of content of file: src/lib_json/json_value.cpp
   3926 // //////////////////////////////////////////////////////////////////////
   3927 
   3928 
   3929 
   3930 
   3931 
   3932 
   3933 // //////////////////////////////////////////////////////////////////////
   3934 // Beginning of content of file: src/lib_json/json_writer.cpp
   3935 // //////////////////////////////////////////////////////////////////////
   3936 
   3937 // Copyright 2011 Baptiste Lepilleur
   3938 // Distributed under MIT license, or public domain if desired and
   3939 // recognized in your jurisdiction.
   3940 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
   3941 
   3942 #if !defined(JSON_IS_AMALGAMATION)
   3943 #include <json/writer.h>
   3944 #include "json_tool.h"
   3945 #endif // if !defined(JSON_IS_AMALGAMATION)
   3946 #include <iomanip>
   3947 #include <memory>
   3948 #include <sstream>
   3949 #include <utility>
   3950 #include <set>
   3951 #include <cassert>
   3952 #include <cstring>
   3953 #include <cstdio>
   3954 
   3955 #if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
   3956 #include <float.h>
   3957 #define isfinite _finite
   3958 #elif defined(__sun) && defined(__SVR4) //Solaris
   3959 #include <ieeefp.h>
   3960 #define isfinite finite
   3961 #else
   3962 #include <cmath>
   3963 #define isfinite std::isfinite
   3964 #endif
   3965 
   3966 #if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
   3967 #define snprintf _snprintf
   3968 #elif defined(__ANDROID__)
   3969 #define snprintf snprintf
   3970 #elif __cplusplus >= 201103L
   3971 #define snprintf std::snprintf
   3972 #endif
   3973 
   3974 #if defined(__BORLANDC__)
   3975 #include <float.h>
   3976 #define isfinite _finite
   3977 #define snprintf _snprintf
   3978 #endif
   3979 
   3980 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
   3981 // Disable warning about strdup being deprecated.
   3982 #pragma warning(disable : 4996)
   3983 #endif
   3984 
   3985 namespace Json {
   3986 
   3987 #if __cplusplus >= 201103L
   3988 typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
   3989 #else
   3990 typedef std::auto_ptr<StreamWriter>   StreamWriterPtr;
   3991 #endif
   3992 
   3993 static bool containsControlCharacter(const char* str) {
   3994   while (*str) {
   3995     if (isControlCharacter(*(str++)))
   3996       return true;
   3997   }
   3998   return false;
   3999 }
   4000 
   4001 static bool containsControlCharacter0(const char* str, unsigned len) {
   4002   char const* end = str + len;
   4003   while (end != str) {
   4004     if (isControlCharacter(*str) || 0==*str)
   4005       return true;
   4006     ++str;
   4007   }
   4008   return false;
   4009 }
   4010 
   4011 std::string valueToString(LargestInt value) {
   4012   UIntToStringBuffer buffer;
   4013   char* current = buffer + sizeof(buffer);
   4014   bool isNegative = value < 0;
   4015   if (isNegative)
   4016     value = -value;
   4017   uintToString(LargestUInt(value), current);
   4018   if (isNegative)
   4019     *--current = '-';
   4020   assert(current >= buffer);
   4021   return current;
   4022 }
   4023 
   4024 std::string valueToString(LargestUInt value) {
   4025   UIntToStringBuffer buffer;
   4026   char* current = buffer + sizeof(buffer);
   4027   uintToString(value, current);
   4028   assert(current >= buffer);
   4029   return current;
   4030 }
   4031 
   4032 #if defined(JSON_HAS_INT64)
   4033 
   4034 std::string valueToString(Int value) {
   4035   return valueToString(LargestInt(value));
   4036 }
   4037 
   4038 std::string valueToString(UInt value) {
   4039   return valueToString(LargestUInt(value));
   4040 }
   4041 
   4042 #endif // # if defined(JSON_HAS_INT64)
   4043 
   4044 std::string valueToString(double value) {
   4045   // Allocate a buffer that is more than large enough to store the 16 digits of
   4046   // precision requested below.
   4047   char buffer[32];
   4048   int len = -1;
   4049 
   4050 // Print into the buffer. We need not request the alternative representation
   4051 // that always has a decimal point because JSON doesn't distingish the
   4052 // concepts of reals and integers.
   4053 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with
   4054                                                       // visual studio 2005 to
   4055                                                       // avoid warning.
   4056 #if defined(WINCE)
   4057   len = _snprintf(buffer, sizeof(buffer), "%.17g", value);
   4058 #else
   4059   len = sprintf_s(buffer, sizeof(buffer), "%.17g", value);
   4060 #endif
   4061 #else
   4062   if (isfinite(value)) {
   4063     len = snprintf(buffer, sizeof(buffer), "%.17g", value);
   4064   } else {
   4065     // IEEE standard states that NaN values will not compare to themselves
   4066     if (value != value) {
   4067       len = snprintf(buffer, sizeof(buffer), "null");
   4068     } else if (value < 0) {
   4069       len = snprintf(buffer, sizeof(buffer), "-1e+9999");
   4070     } else {
   4071       len = snprintf(buffer, sizeof(buffer), "1e+9999");
   4072     }
   4073     // For those, we do not need to call fixNumLoc, but it is fast.
   4074   }
   4075 #endif
   4076   assert(len >= 0);
   4077   fixNumericLocale(buffer, buffer + len);
   4078   return buffer;
   4079 }
   4080 
   4081 std::string valueToString(bool value) { return value ? "true" : "false"; }
   4082 
   4083 std::string valueToQuotedString(const char* value) {
   4084   if (value == NULL)
   4085     return "";
   4086   // Not sure how to handle unicode...
   4087   if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL &&
   4088       !containsControlCharacter(value))
   4089     return std::string("\"") + value + "\"";
   4090   // We have to walk value and escape any special characters.
   4091   // Appending to std::string is not efficient, but this should be rare.
   4092   // (Note: forward slashes are *not* rare, but I am not escaping them.)
   4093   std::string::size_type maxsize =
   4094       strlen(value) * 2 + 3; // allescaped+quotes+NULL
   4095   std::string result;
   4096   result.reserve(maxsize); // to avoid lots of mallocs
   4097   result += "\"";
   4098   for (const char* c = value; *c != 0; ++c) {
   4099     switch (*c) {
   4100     case '\"':
   4101       result += "\\\"";
   4102       break;
   4103     case '\\':
   4104       result += "\\\\";
   4105       break;
   4106     case '\b':
   4107       result += "\\b";
   4108       break;
   4109     case '\f':
   4110       result += "\\f";
   4111       break;
   4112     case '\n':
   4113       result += "\\n";
   4114       break;
   4115     case '\r':
   4116       result += "\\r";
   4117       break;
   4118     case '\t':
   4119       result += "\\t";
   4120       break;
   4121     // case '/':
   4122     // Even though \/ is considered a legal escape in JSON, a bare
   4123     // slash is also legal, so I see no reason to escape it.
   4124     // (I hope I am not misunderstanding something.
   4125     // blep notes: actually escaping \/ may be useful in javascript to avoid </
   4126     // sequence.
   4127     // Should add a flag to allow this compatibility mode and prevent this
   4128     // sequence from occurring.
   4129     default:
   4130       if (isControlCharacter(*c)) {
   4131         std::ostringstream oss;
   4132         oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
   4133             << std::setw(4) << static_cast<int>(*c);
   4134         result += oss.str();
   4135       } else {
   4136         result += *c;
   4137       }
   4138       break;
   4139     }
   4140   }
   4141   result += "\"";
   4142   return result;
   4143 }
   4144 
   4145 // https://github.com/upcaste/upcaste/blob/master/src/upcore/src/cstring/strnpbrk.cpp
   4146 static char const* strnpbrk(char const* s, char const* accept, size_t n) {
   4147   assert((s || !n) && accept);
   4148 
   4149   char const* const end = s + n;
   4150   for (char const* cur = s; cur < end; ++cur) {
   4151     int const c = *cur;
   4152     for (char const* a = accept; *a; ++a) {
   4153       if (*a == c) {
   4154         return cur;
   4155       }
   4156     }
   4157   }
   4158   return NULL;
   4159 }
   4160 static std::string valueToQuotedStringN(const char* value, unsigned length) {
   4161   if (value == NULL)
   4162     return "";
   4163   // Not sure how to handle unicode...
   4164   if (strnpbrk(value, "\"\\\b\f\n\r\t", length) == NULL &&
   4165       !containsControlCharacter0(value, length))
   4166     return std::string("\"") + value + "\"";
   4167   // We have to walk value and escape any special characters.
   4168   // Appending to std::string is not efficient, but this should be rare.
   4169   // (Note: forward slashes are *not* rare, but I am not escaping them.)
   4170   std::string::size_type maxsize =
   4171       length * 2 + 3; // allescaped+quotes+NULL
   4172   std::string result;
   4173   result.reserve(maxsize); // to avoid lots of mallocs
   4174   result += "\"";
   4175   char const* end = value + length;
   4176   for (const char* c = value; c != end; ++c) {
   4177     switch (*c) {
   4178     case '\"':
   4179       result += "\\\"";
   4180       break;
   4181     case '\\':
   4182       result += "\\\\";
   4183       break;
   4184     case '\b':
   4185       result += "\\b";
   4186       break;
   4187     case '\f':
   4188       result += "\\f";
   4189       break;
   4190     case '\n':
   4191       result += "\\n";
   4192       break;
   4193     case '\r':
   4194       result += "\\r";
   4195       break;
   4196     case '\t':
   4197       result += "\\t";
   4198       break;
   4199     // case '/':
   4200     // Even though \/ is considered a legal escape in JSON, a bare
   4201     // slash is also legal, so I see no reason to escape it.
   4202     // (I hope I am not misunderstanding something.)
   4203     // blep notes: actually escaping \/ may be useful in javascript to avoid </
   4204     // sequence.
   4205     // Should add a flag to allow this compatibility mode and prevent this
   4206     // sequence from occurring.
   4207     default:
   4208       if ((isControlCharacter(*c)) || (*c == 0)) {
   4209         std::ostringstream oss;
   4210         oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
   4211             << std::setw(4) << static_cast<int>(*c);
   4212         result += oss.str();
   4213       } else {
   4214         result += *c;
   4215       }
   4216       break;
   4217     }
   4218   }
   4219   result += "\"";
   4220   return result;
   4221 }
   4222 
   4223 // Class Writer
   4224 // //////////////////////////////////////////////////////////////////
   4225 Writer::~Writer() {}
   4226 
   4227 // Class FastWriter
   4228 // //////////////////////////////////////////////////////////////////
   4229 
   4230 FastWriter::FastWriter()
   4231     : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
   4232       omitEndingLineFeed_(false) {}
   4233 
   4234 void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
   4235 
   4236 void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
   4237 
   4238 void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
   4239 
   4240 std::string FastWriter::write(const Value& root) {
   4241   document_ = "";
   4242   writeValue(root);
   4243   if (!omitEndingLineFeed_)
   4244     document_ += "\n";
   4245   return document_;
   4246 }
   4247 
   4248 void FastWriter::writeValue(const Value& value) {
   4249   switch (value.type()) {
   4250   case nullValue:
   4251     if (!dropNullPlaceholders_)
   4252       document_ += "null";
   4253     break;
   4254   case intValue:
   4255     document_ += valueToString(value.asLargestInt());
   4256     break;
   4257   case uintValue:
   4258     document_ += valueToString(value.asLargestUInt());
   4259     break;
   4260   case realValue:
   4261     document_ += valueToString(value.asDouble());
   4262     break;
   4263   case stringValue:
   4264   {
   4265     // Is NULL possible for value.string_?
   4266     char const* str;
   4267     char const* end;
   4268     bool ok = value.getString(&str, &end);
   4269     if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str));
   4270     break;
   4271   }
   4272   case booleanValue:
   4273     document_ += valueToString(value.asBool());
   4274     break;
   4275   case arrayValue: {
   4276     document_ += '[';
   4277     int size = value.size();
   4278     for (int index = 0; index < size; ++index) {
   4279       if (index > 0)
   4280         document_ += ',';
   4281       writeValue(value[index]);
   4282     }
   4283     document_ += ']';
   4284   } break;
   4285   case objectValue: {
   4286     Value::Members members(value.getMemberNames());
   4287     document_ += '{';
   4288     for (Value::Members::iterator it = members.begin(); it != members.end();
   4289          ++it) {
   4290       const std::string& name = *it;
   4291       if (it != members.begin())
   4292         document_ += ',';
   4293       document_ += valueToQuotedStringN(name.data(), name.length());
   4294       document_ += yamlCompatiblityEnabled_ ? ": " : ":";
   4295       writeValue(value[name]);
   4296     }
   4297     document_ += '}';
   4298   } break;
   4299   }
   4300 }
   4301 
   4302 // Class StyledWriter
   4303 // //////////////////////////////////////////////////////////////////
   4304 
   4305 StyledWriter::StyledWriter()
   4306     : rightMargin_(74), indentSize_(3), addChildValues_() {}
   4307 
   4308 std::string StyledWriter::write(const Value& root) {
   4309   document_ = "";
   4310   addChildValues_ = false;
   4311   indentString_ = "";
   4312   writeCommentBeforeValue(root);
   4313   writeValue(root);
   4314   writeCommentAfterValueOnSameLine(root);
   4315   document_ += "\n";
   4316   return document_;
   4317 }
   4318 
   4319 void StyledWriter::writeValue(const Value& value) {
   4320   switch (value.type()) {
   4321   case nullValue:
   4322     pushValue("null");
   4323     break;
   4324   case intValue:
   4325     pushValue(valueToString(value.asLargestInt()));
   4326     break;
   4327   case uintValue:
   4328     pushValue(valueToString(value.asLargestUInt()));
   4329     break;
   4330   case realValue:
   4331     pushValue(valueToString(value.asDouble()));
   4332     break;
   4333   case stringValue:
   4334   {
   4335     // Is NULL possible for value.string_?
   4336     char const* str;
   4337     char const* end;
   4338     bool ok = value.getString(&str, &end);
   4339     if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
   4340     else pushValue("");
   4341     break;
   4342   }
   4343   case booleanValue:
   4344     pushValue(valueToString(value.asBool()));
   4345     break;
   4346   case arrayValue:
   4347     writeArrayValue(value);
   4348     break;
   4349   case objectValue: {
   4350     Value::Members members(value.getMemberNames());
   4351     if (members.empty())
   4352       pushValue("{}");
   4353     else {
   4354       writeWithIndent("{");
   4355       indent();
   4356       Value::Members::iterator it = members.begin();
   4357       for (;;) {
   4358         const std::string& name = *it;
   4359         const Value& childValue = value[name];
   4360         writeCommentBeforeValue(childValue);
   4361         writeWithIndent(valueToQuotedString(name.c_str()));
   4362         document_ += " : ";
   4363         writeValue(childValue);
   4364         if (++it == members.end()) {
   4365           writeCommentAfterValueOnSameLine(childValue);
   4366           break;
   4367         }
   4368         document_ += ',';
   4369         writeCommentAfterValueOnSameLine(childValue);
   4370       }
   4371       unindent();
   4372       writeWithIndent("}");
   4373     }
   4374   } break;
   4375   }
   4376 }
   4377 
   4378 void StyledWriter::writeArrayValue(const Value& value) {
   4379   unsigned size = value.size();
   4380   if (size == 0)
   4381     pushValue("[]");
   4382   else {
   4383     bool isArrayMultiLine = isMultineArray(value);
   4384     if (isArrayMultiLine) {
   4385       writeWithIndent("[");
   4386       indent();
   4387       bool hasChildValue = !childValues_.empty();
   4388       unsigned index = 0;
   4389       for (;;) {
   4390         const Value& childValue = value[index];
   4391         writeCommentBeforeValue(childValue);
   4392         if (hasChildValue)
   4393           writeWithIndent(childValues_[index]);
   4394         else {
   4395           writeIndent();
   4396           writeValue(childValue);
   4397         }
   4398         if (++index == size) {
   4399           writeCommentAfterValueOnSameLine(childValue);
   4400           break;
   4401         }
   4402         document_ += ',';
   4403         writeCommentAfterValueOnSameLine(childValue);
   4404       }
   4405       unindent();
   4406       writeWithIndent("]");
   4407     } else // output on a single line
   4408     {
   4409       assert(childValues_.size() == size);
   4410       document_ += "[ ";
   4411       for (unsigned index = 0; index < size; ++index) {
   4412         if (index > 0)
   4413           document_ += ", ";
   4414         document_ += childValues_[index];
   4415       }
   4416       document_ += " ]";
   4417     }
   4418   }
   4419 }
   4420 
   4421 bool StyledWriter::isMultineArray(const Value& value) {
   4422   int size = value.size();
   4423   bool isMultiLine = size * 3 >= rightMargin_;
   4424   childValues_.clear();
   4425   for (int index = 0; index < size && !isMultiLine; ++index) {
   4426     const Value& childValue = value[index];
   4427     isMultiLine =
   4428         isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
   4429                         childValue.size() > 0);
   4430   }
   4431   if (!isMultiLine) // check if line length > max line length
   4432   {
   4433     childValues_.reserve(size);
   4434     addChildValues_ = true;
   4435     int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
   4436     for (int index = 0; index < size; ++index) {
   4437       if (hasCommentForValue(value[index])) {
   4438         isMultiLine = true;
   4439       }
   4440       writeValue(value[index]);
   4441       lineLength += int(childValues_[index].length());
   4442     }
   4443     addChildValues_ = false;
   4444     isMultiLine = isMultiLine || lineLength >= rightMargin_;
   4445   }
   4446   return isMultiLine;
   4447 }
   4448 
   4449 void StyledWriter::pushValue(const std::string& value) {
   4450   if (addChildValues_)
   4451     childValues_.push_back(value);
   4452   else
   4453     document_ += value;
   4454 }
   4455 
   4456 void StyledWriter::writeIndent() {
   4457   if (!document_.empty()) {
   4458     char last = document_[document_.length() - 1];
   4459     if (last == ' ') // already indented
   4460       return;
   4461     if (last != '\n') // Comments may add new-line
   4462       document_ += '\n';
   4463   }
   4464   document_ += indentString_;
   4465 }
   4466 
   4467 void StyledWriter::writeWithIndent(const std::string& value) {
   4468   writeIndent();
   4469   document_ += value;
   4470 }
   4471 
   4472 void StyledWriter::indent() { indentString_ += std::string(indentSize_, ' '); }
   4473 
   4474 void StyledWriter::unindent() {
   4475   assert(int(indentString_.size()) >= indentSize_);
   4476   indentString_.resize(indentString_.size() - indentSize_);
   4477 }
   4478 
   4479 void StyledWriter::writeCommentBeforeValue(const Value& root) {
   4480   if (!root.hasComment(commentBefore))
   4481     return;
   4482 
   4483   document_ += "\n";
   4484   writeIndent();
   4485   const std::string& comment = root.getComment(commentBefore);
   4486   std::string::const_iterator iter = comment.begin();
   4487   while (iter != comment.end()) {
   4488     document_ += *iter;
   4489     if (*iter == '\n' &&
   4490        (iter != comment.end() && *(iter + 1) == '/'))
   4491       writeIndent();
   4492     ++iter;
   4493   }
   4494 
   4495   // Comments are stripped of trailing newlines, so add one here
   4496   document_ += "\n";
   4497 }
   4498 
   4499 void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) {
   4500   if (root.hasComment(commentAfterOnSameLine))
   4501     document_ += " " + root.getComment(commentAfterOnSameLine);
   4502 
   4503   if (root.hasComment(commentAfter)) {
   4504     document_ += "\n";
   4505     document_ += root.getComment(commentAfter);
   4506     document_ += "\n";
   4507   }
   4508 }
   4509 
   4510 bool StyledWriter::hasCommentForValue(const Value& value) {
   4511   return value.hasComment(commentBefore) ||
   4512          value.hasComment(commentAfterOnSameLine) ||
   4513          value.hasComment(commentAfter);
   4514 }
   4515 
   4516 // Class StyledStreamWriter
   4517 // //////////////////////////////////////////////////////////////////
   4518 
   4519 StyledStreamWriter::StyledStreamWriter(std::string indentation)
   4520     : document_(NULL), rightMargin_(74), indentation_(indentation),
   4521       addChildValues_() {}
   4522 
   4523 void StyledStreamWriter::write(std::ostream& out, const Value& root) {
   4524   document_ = &out;
   4525   addChildValues_ = false;
   4526   indentString_ = "";
   4527   indented_ = true;
   4528   writeCommentBeforeValue(root);
   4529   if (!indented_) writeIndent();
   4530   indented_ = true;
   4531   writeValue(root);
   4532   writeCommentAfterValueOnSameLine(root);
   4533   *document_ << "\n";
   4534   document_ = NULL; // Forget the stream, for safety.
   4535 }
   4536 
   4537 void StyledStreamWriter::writeValue(const Value& value) {
   4538   switch (value.type()) {
   4539   case nullValue:
   4540     pushValue("null");
   4541     break;
   4542   case intValue:
   4543     pushValue(valueToString(value.asLargestInt()));
   4544     break;
   4545   case uintValue:
   4546     pushValue(valueToString(value.asLargestUInt()));
   4547     break;
   4548   case realValue:
   4549     pushValue(valueToString(value.asDouble()));
   4550     break;
   4551   case stringValue:
   4552   {
   4553     // Is NULL possible for value.string_?
   4554     char const* str;
   4555     char const* end;
   4556     bool ok = value.getString(&str, &end);
   4557     if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
   4558     else pushValue("");
   4559     break;
   4560   }
   4561   case booleanValue:
   4562     pushValue(valueToString(value.asBool()));
   4563     break;
   4564   case arrayValue:
   4565     writeArrayValue(value);
   4566     break;
   4567   case objectValue: {
   4568     Value::Members members(value.getMemberNames());
   4569     if (members.empty())
   4570       pushValue("{}");
   4571     else {
   4572       writeWithIndent("{");
   4573       indent();
   4574       Value::Members::iterator it = members.begin();
   4575       for (;;) {
   4576         const std::string& name = *it;
   4577         const Value& childValue = value[name];
   4578         writeCommentBeforeValue(childValue);
   4579         writeWithIndent(valueToQuotedString(name.c_str()));
   4580         *document_ << " : ";
   4581         writeValue(childValue);
   4582         if (++it == members.end()) {
   4583           writeCommentAfterValueOnSameLine(childValue);
   4584           break;
   4585         }
   4586         *document_ << ",";
   4587         writeCommentAfterValueOnSameLine(childValue);
   4588       }
   4589       unindent();
   4590       writeWithIndent("}");
   4591     }
   4592   } break;
   4593   }
   4594 }
   4595 
   4596 void StyledStreamWriter::writeArrayValue(const Value& value) {
   4597   unsigned size = value.size();
   4598   if (size == 0)
   4599     pushValue("[]");
   4600   else {
   4601     bool isArrayMultiLine = isMultineArray(value);
   4602     if (isArrayMultiLine) {
   4603       writeWithIndent("[");
   4604       indent();
   4605       bool hasChildValue = !childValues_.empty();
   4606       unsigned index = 0;
   4607       for (;;) {
   4608         const Value& childValue = value[index];
   4609         writeCommentBeforeValue(childValue);
   4610         if (hasChildValue)
   4611           writeWithIndent(childValues_[index]);
   4612         else {
   4613           if (!indented_) writeIndent();
   4614           indented_ = true;
   4615           writeValue(childValue);
   4616           indented_ = false;
   4617         }
   4618         if (++index == size) {
   4619           writeCommentAfterValueOnSameLine(childValue);
   4620           break;
   4621         }
   4622         *document_ << ",";
   4623         writeCommentAfterValueOnSameLine(childValue);
   4624       }
   4625       unindent();
   4626       writeWithIndent("]");
   4627     } else // output on a single line
   4628     {
   4629       assert(childValues_.size() == size);
   4630       *document_ << "[ ";
   4631       for (unsigned index = 0; index < size; ++index) {
   4632         if (index > 0)
   4633           *document_ << ", ";
   4634         *document_ << childValues_[index];
   4635       }
   4636       *document_ << " ]";
   4637     }
   4638   }
   4639 }
   4640 
   4641 bool StyledStreamWriter::isMultineArray(const Value& value) {
   4642   int size = value.size();
   4643   bool isMultiLine = size * 3 >= rightMargin_;
   4644   childValues_.clear();
   4645   for (int index = 0; index < size && !isMultiLine; ++index) {
   4646     const Value& childValue = value[index];
   4647     isMultiLine =
   4648         isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
   4649                         childValue.size() > 0);
   4650   }
   4651   if (!isMultiLine) // check if line length > max line length
   4652   {
   4653     childValues_.reserve(size);
   4654     addChildValues_ = true;
   4655     int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
   4656     for (int index = 0; index < size; ++index) {
   4657       if (hasCommentForValue(value[index])) {
   4658         isMultiLine = true;
   4659       }
   4660       writeValue(value[index]);
   4661       lineLength += int(childValues_[index].length());
   4662     }
   4663     addChildValues_ = false;
   4664     isMultiLine = isMultiLine || lineLength >= rightMargin_;
   4665   }
   4666   return isMultiLine;
   4667 }
   4668 
   4669 void StyledStreamWriter::pushValue(const std::string& value) {
   4670   if (addChildValues_)
   4671     childValues_.push_back(value);
   4672   else
   4673     *document_ << value;
   4674 }
   4675 
   4676 void StyledStreamWriter::writeIndent() {
   4677   // blep intended this to look at the so-far-written string
   4678   // to determine whether we are already indented, but
   4679   // with a stream we cannot do that. So we rely on some saved state.
   4680   // The caller checks indented_.
   4681   *document_ << '\n' << indentString_;
   4682 }
   4683 
   4684 void StyledStreamWriter::writeWithIndent(const std::string& value) {
   4685   if (!indented_) writeIndent();
   4686   *document_ << value;
   4687   indented_ = false;
   4688 }
   4689 
   4690 void StyledStreamWriter::indent() { indentString_ += indentation_; }
   4691 
   4692 void StyledStreamWriter::unindent() {
   4693   assert(indentString_.size() >= indentation_.size());
   4694   indentString_.resize(indentString_.size() - indentation_.size());
   4695 }
   4696 
   4697 void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
   4698   if (!root.hasComment(commentBefore))
   4699     return;
   4700 
   4701   if (!indented_) writeIndent();
   4702   const std::string& comment = root.getComment(commentBefore);
   4703   std::string::const_iterator iter = comment.begin();
   4704   while (iter != comment.end()) {
   4705     *document_ << *iter;
   4706     if (*iter == '\n' &&
   4707        (iter != comment.end() && *(iter + 1) == '/'))
   4708       // writeIndent();  // would include newline
   4709       *document_ << indentString_;
   4710     ++iter;
   4711   }
   4712   indented_ = false;
   4713 }
   4714 
   4715 void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) {
   4716   if (root.hasComment(commentAfterOnSameLine))
   4717     *document_ << ' ' << root.getComment(commentAfterOnSameLine);
   4718 
   4719   if (root.hasComment(commentAfter)) {
   4720     writeIndent();
   4721     *document_ << root.getComment(commentAfter);
   4722   }
   4723   indented_ = false;
   4724 }
   4725 
   4726 bool StyledStreamWriter::hasCommentForValue(const Value& value) {
   4727   return value.hasComment(commentBefore) ||
   4728          value.hasComment(commentAfterOnSameLine) ||
   4729          value.hasComment(commentAfter);
   4730 }
   4731 
   4732 //////////////////////////
   4733 // BuiltStyledStreamWriter
   4734 
   4735 /// Scoped enums are not available until C++11.
   4736 struct CommentStyle {
   4737   /// Decide whether to write comments.
   4738   enum Enum {
   4739     None,  ///< Drop all comments.
   4740     Most,  ///< Recover odd behavior of previous versions (not implemented yet).
   4741     All  ///< Keep all comments.
   4742   };
   4743 };
   4744 
   4745 struct BuiltStyledStreamWriter : public StreamWriter
   4746 {
   4747   BuiltStyledStreamWriter(
   4748       std::string const& indentation,
   4749       CommentStyle::Enum cs,
   4750       std::string const& colonSymbol,
   4751       std::string const& nullSymbol,
   4752       std::string const& endingLineFeedSymbol);
   4753   virtual int write(Value const& root, std::ostream* sout);
   4754 private:
   4755   void writeValue(Value const& value);
   4756   void writeArrayValue(Value const& value);
   4757   bool isMultineArray(Value const& value);
   4758   void pushValue(std::string const& value);
   4759   void writeIndent();
   4760   void writeWithIndent(std::string const& value);
   4761   void indent();
   4762   void unindent();
   4763   void writeCommentBeforeValue(Value const& root);
   4764   void writeCommentAfterValueOnSameLine(Value const& root);
   4765   static bool hasCommentForValue(const Value& value);
   4766 
   4767   typedef std::vector<std::string> ChildValues;
   4768 
   4769   ChildValues childValues_;
   4770   std::string indentString_;
   4771   int rightMargin_;
   4772   std::string indentation_;
   4773   CommentStyle::Enum cs_;
   4774   std::string colonSymbol_;
   4775   std::string nullSymbol_;
   4776   std::string endingLineFeedSymbol_;
   4777   bool addChildValues_ : 1;
   4778   bool indented_ : 1;
   4779 };
   4780 BuiltStyledStreamWriter::BuiltStyledStreamWriter(
   4781       std::string const& indentation,
   4782       CommentStyle::Enum cs,
   4783       std::string const& colonSymbol,
   4784       std::string const& nullSymbol,
   4785       std::string const& endingLineFeedSymbol)
   4786   : rightMargin_(74)
   4787   , indentation_(indentation)
   4788   , cs_(cs)
   4789   , colonSymbol_(colonSymbol)
   4790   , nullSymbol_(nullSymbol)
   4791   , endingLineFeedSymbol_(endingLineFeedSymbol)
   4792   , addChildValues_(false)
   4793   , indented_(false)
   4794 {
   4795 }
   4796 int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout)
   4797 {
   4798   sout_ = sout;
   4799   addChildValues_ = false;
   4800   indented_ = true;
   4801   indentString_ = "";
   4802   writeCommentBeforeValue(root);
   4803   if (!indented_) writeIndent();
   4804   indented_ = true;
   4805   writeValue(root);
   4806   writeCommentAfterValueOnSameLine(root);
   4807   *sout_ << endingLineFeedSymbol_;
   4808   sout_ = NULL;
   4809   return 0;
   4810 }
   4811 void BuiltStyledStreamWriter::writeValue(Value const& value) {
   4812   switch (value.type()) {
   4813   case nullValue:
   4814     pushValue(nullSymbol_);
   4815     break;
   4816   case intValue:
   4817     pushValue(valueToString(value.asLargestInt()));
   4818     break;
   4819   case uintValue:
   4820     pushValue(valueToString(value.asLargestUInt()));
   4821     break;
   4822   case realValue:
   4823     pushValue(valueToString(value.asDouble()));
   4824     break;
   4825   case stringValue:
   4826   {
   4827     // Is NULL is possible for value.string_?
   4828     char const* str;
   4829     char const* end;
   4830     bool ok = value.getString(&str, &end);
   4831     if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
   4832     else pushValue("");
   4833     break;
   4834   }
   4835   case booleanValue:
   4836     pushValue(valueToString(value.asBool()));
   4837     break;
   4838   case arrayValue:
   4839     writeArrayValue(value);
   4840     break;
   4841   case objectValue: {
   4842     Value::Members members(value.getMemberNames());
   4843     if (members.empty())
   4844       pushValue("{}");
   4845     else {
   4846       writeWithIndent("{");
   4847       indent();
   4848       Value::Members::iterator it = members.begin();
   4849       for (;;) {
   4850         std::string const& name = *it;
   4851         Value const& childValue = value[name];
   4852         writeCommentBeforeValue(childValue);
   4853         writeWithIndent(valueToQuotedStringN(name.data(), name.length()));
   4854         *sout_ << colonSymbol_;
   4855         writeValue(childValue);
   4856         if (++it == members.end()) {
   4857           writeCommentAfterValueOnSameLine(childValue);
   4858           break;
   4859         }
   4860         *sout_ << ",";
   4861         writeCommentAfterValueOnSameLine(childValue);
   4862       }
   4863       unindent();
   4864       writeWithIndent("}");
   4865     }
   4866   } break;
   4867   }
   4868 }
   4869 
   4870 void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
   4871   unsigned size = value.size();
   4872   if (size == 0)
   4873     pushValue("[]");
   4874   else {
   4875     bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
   4876     if (isMultiLine) {
   4877       writeWithIndent("[");
   4878       indent();
   4879       bool hasChildValue = !childValues_.empty();
   4880       unsigned index = 0;
   4881       for (;;) {
   4882         Value const& childValue = value[index];
   4883         writeCommentBeforeValue(childValue);
   4884         if (hasChildValue)
   4885           writeWithIndent(childValues_[index]);
   4886         else {
   4887           if (!indented_) writeIndent();
   4888           indented_ = true;
   4889           writeValue(childValue);
   4890           indented_ = false;
   4891         }
   4892         if (++index == size) {
   4893           writeCommentAfterValueOnSameLine(childValue);
   4894           break;
   4895         }
   4896         *sout_ << ",";
   4897         writeCommentAfterValueOnSameLine(childValue);
   4898       }
   4899       unindent();
   4900       writeWithIndent("]");
   4901     } else // output on a single line
   4902     {
   4903       assert(childValues_.size() == size);
   4904       *sout_ << "[";
   4905       if (!indentation_.empty()) *sout_ << " ";
   4906       for (unsigned index = 0; index < size; ++index) {
   4907         if (index > 0)
   4908           *sout_ << ", ";
   4909         *sout_ << childValues_[index];
   4910       }
   4911       if (!indentation_.empty()) *sout_ << " ";
   4912       *sout_ << "]";
   4913     }
   4914   }
   4915 }
   4916 
   4917 bool BuiltStyledStreamWriter::isMultineArray(Value const& value) {
   4918   int size = value.size();
   4919   bool isMultiLine = size * 3 >= rightMargin_;
   4920   childValues_.clear();
   4921   for (int index = 0; index < size && !isMultiLine; ++index) {
   4922     Value const& childValue = value[index];
   4923     isMultiLine =
   4924         isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
   4925                         childValue.size() > 0);
   4926   }
   4927   if (!isMultiLine) // check if line length > max line length
   4928   {
   4929     childValues_.reserve(size);
   4930     addChildValues_ = true;
   4931     int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
   4932     for (int index = 0; index < size; ++index) {
   4933       if (hasCommentForValue(value[index])) {
   4934         isMultiLine = true;
   4935       }
   4936       writeValue(value[index]);
   4937       lineLength += int(childValues_[index].length());
   4938     }
   4939     addChildValues_ = false;
   4940     isMultiLine = isMultiLine || lineLength >= rightMargin_;
   4941   }
   4942   return isMultiLine;
   4943 }
   4944 
   4945 void BuiltStyledStreamWriter::pushValue(std::string const& value) {
   4946   if (addChildValues_)
   4947     childValues_.push_back(value);
   4948   else
   4949     *sout_ << value;
   4950 }
   4951 
   4952 void BuiltStyledStreamWriter::writeIndent() {
   4953   // blep intended this to look at the so-far-written string
   4954   // to determine whether we are already indented, but
   4955   // with a stream we cannot do that. So we rely on some saved state.
   4956   // The caller checks indented_.
   4957 
   4958   if (!indentation_.empty()) {
   4959     // In this case, drop newlines too.
   4960     *sout_ << '\n' << indentString_;
   4961   }
   4962 }
   4963 
   4964 void BuiltStyledStreamWriter::writeWithIndent(std::string const& value) {
   4965   if (!indented_) writeIndent();
   4966   *sout_ << value;
   4967   indented_ = false;
   4968 }
   4969 
   4970 void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
   4971 
   4972 void BuiltStyledStreamWriter::unindent() {
   4973   assert(indentString_.size() >= indentation_.size());
   4974   indentString_.resize(indentString_.size() - indentation_.size());
   4975 }
   4976 
   4977 void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
   4978   if (cs_ == CommentStyle::None) return;
   4979   if (!root.hasComment(commentBefore))
   4980     return;
   4981 
   4982   if (!indented_) writeIndent();
   4983   const std::string& comment = root.getComment(commentBefore);
   4984   std::string::const_iterator iter = comment.begin();
   4985   while (iter != comment.end()) {
   4986     *sout_ << *iter;
   4987     if (*iter == '\n' &&
   4988        (iter != comment.end() && *(iter + 1) == '/'))
   4989       // writeIndent();  // would write extra newline
   4990       *sout_ << indentString_;
   4991     ++iter;
   4992   }
   4993   indented_ = false;
   4994 }
   4995 
   4996 void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) {
   4997   if (cs_ == CommentStyle::None) return;
   4998   if (root.hasComment(commentAfterOnSameLine))
   4999     *sout_ << " " + root.getComment(commentAfterOnSameLine);
   5000 
   5001   if (root.hasComment(commentAfter)) {
   5002     writeIndent();
   5003     *sout_ << root.getComment(commentAfter);
   5004   }
   5005 }
   5006 
   5007 // static
   5008 bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
   5009   return value.hasComment(commentBefore) ||
   5010          value.hasComment(commentAfterOnSameLine) ||
   5011          value.hasComment(commentAfter);
   5012 }
   5013 
   5014 ///////////////
   5015 // StreamWriter
   5016 
   5017 StreamWriter::StreamWriter()
   5018     : sout_(NULL)
   5019 {
   5020 }
   5021 StreamWriter::~StreamWriter()
   5022 {
   5023 }
   5024 StreamWriter::Factory::~Factory()
   5025 {}
   5026 StreamWriterBuilder::StreamWriterBuilder()
   5027 {
   5028   setDefaults(&settings_);
   5029 }
   5030 StreamWriterBuilder::~StreamWriterBuilder()
   5031 {}
   5032 StreamWriter* StreamWriterBuilder::newStreamWriter() const
   5033 {
   5034   std::string indentation = settings_["indentation"].asString();
   5035   std::string cs_str = settings_["commentStyle"].asString();
   5036   bool eyc = settings_["enableYAMLCompatibility"].asBool();
   5037   bool dnp = settings_["dropNullPlaceholders"].asBool();
   5038   CommentStyle::Enum cs = CommentStyle::All;
   5039   if (cs_str == "All") {
   5040     cs = CommentStyle::All;
   5041   } else if (cs_str == "None") {
   5042     cs = CommentStyle::None;
   5043   } else {
   5044     throwRuntimeError("commentStyle must be 'All' or 'None'");
   5045   }
   5046   std::string colonSymbol = " : ";
   5047   if (eyc) {
   5048     colonSymbol = ": ";
   5049   } else if (indentation.empty()) {
   5050     colonSymbol = ":";
   5051   }
   5052   std::string nullSymbol = "null";
   5053   if (dnp) {
   5054     nullSymbol = "";
   5055   }
   5056   std::string endingLineFeedSymbol = "";
   5057   return new BuiltStyledStreamWriter(
   5058       indentation, cs,
   5059       colonSymbol, nullSymbol, endingLineFeedSymbol);
   5060 }
   5061 static void getValidWriterKeys(std::set<std::string>* valid_keys)
   5062 {
   5063   valid_keys->clear();
   5064   valid_keys->insert("indentation");
   5065   valid_keys->insert("commentStyle");
   5066   valid_keys->insert("enableYAMLCompatibility");
   5067   valid_keys->insert("dropNullPlaceholders");
   5068 }
   5069 bool StreamWriterBuilder::validate(Json::Value* invalid) const
   5070 {
   5071   Json::Value my_invalid;
   5072   if (!invalid) invalid = &my_invalid;  // so we do not need to test for NULL
   5073   Json::Value& inv = *invalid;
   5074   std::set<std::string> valid_keys;
   5075   getValidWriterKeys(&valid_keys);
   5076   Value::Members keys = settings_.getMemberNames();
   5077   size_t n = keys.size();
   5078   for (size_t i = 0; i < n; ++i) {
   5079     std::string const& key = keys[i];
   5080     if (valid_keys.find(key) == valid_keys.end()) {
   5081       inv[key] = settings_[key];
   5082     }
   5083   }
   5084   return 0u == inv.size();
   5085 }
   5086 Value& StreamWriterBuilder::operator[](std::string key)
   5087 {
   5088   return settings_[key];
   5089 }
   5090 // static
   5091 void StreamWriterBuilder::setDefaults(Json::Value* settings)
   5092 {
   5093   //! [StreamWriterBuilderDefaults]
   5094   (*settings)["commentStyle"] = "All";
   5095   (*settings)["indentation"] = "\t";
   5096   (*settings)["enableYAMLCompatibility"] = false;
   5097   (*settings)["dropNullPlaceholders"] = false;
   5098   //! [StreamWriterBuilderDefaults]
   5099 }
   5100 
   5101 std::string writeString(StreamWriter::Factory const& builder, Value const& root) {
   5102   std::ostringstream sout;
   5103   StreamWriterPtr const writer(builder.newStreamWriter());
   5104   writer->write(root, &sout);
   5105   return sout.str();
   5106 }
   5107 
   5108 std::ostream& operator<<(std::ostream& sout, Value const& root) {
   5109   StreamWriterBuilder builder;
   5110   StreamWriterPtr const writer(builder.newStreamWriter());
   5111   writer->write(root, &sout);
   5112   return sout;
   5113 }
   5114 
   5115 } // namespace Json
   5116 
   5117 // //////////////////////////////////////////////////////////////////////
   5118 // End of content of file: src/lib_json/json_writer.cpp
   5119 // //////////////////////////////////////////////////////////////////////
   5120 
   5121 
   5122 
   5123 
   5124 
   5125