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