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