Unreviewed, silence -Wimplicit-fallthrough in openvr
[WebKit-https.git] / Source / ThirdParty / openvr / src / jsoncpp.cpp
1 /// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).
2 /// It is intended to be used with #include "json/json.h"
3
4 // //////////////////////////////////////////////////////////////////////
5 // Beginning of content of file: LICENSE
6 // //////////////////////////////////////////////////////////////////////
7
8 /*
9 The JsonCpp library's source code, including accompanying documentation, 
10 tests and demonstration applications, are licensed under the following
11 conditions...
12
13 The author (Baptiste Lepilleur) explicitly disclaims copyright in all 
14 jurisdictions which recognize such a disclaimer. In such jurisdictions, 
15 this software is released into the Public Domain.
16
17 In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
18 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
19 released under the terms of the MIT License (see below).
20
21 In jurisdictions which recognize Public Domain property, the user of this 
22 software may choose to accept it either as 1) Public Domain, 2) under the 
23 conditions of the MIT License (see below), or 3) under the terms of dual 
24 Public Domain/MIT License conditions described here, as they choose.
25
26 The MIT License is about as close to Public Domain as a license can get, and is
27 described in clear, concise terms at:
28
29    http://en.wikipedia.org/wiki/MIT_License
30    
31 The full text of the MIT License follows:
32
33 ========================================================================
34 Copyright (c) 2007-2010 Baptiste Lepilleur
35
36 Permission is hereby granted, free of charge, to any person
37 obtaining a copy of this software and associated documentation
38 files (the "Software"), to deal in the Software without
39 restriction, including without limitation the rights to use, copy,
40 modify, merge, publish, distribute, sublicense, and/or sell copies
41 of the Software, and to permit persons to whom the Software is
42 furnished to do so, subject to the following conditions:
43
44 The above copyright notice and this permission notice shall be
45 included in all copies or substantial portions of the Software.
46
47 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
48 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
50 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
51 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
52 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
53 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
54 SOFTWARE.
55 ========================================================================
56 (END LICENSE TEXT)
57
58 The MIT license is compatible with both the GPL and commercial
59 software, affording one all of the rights of Public Domain with the
60 minor nuisance of being required to keep the above copyright notice
61 and license text in the source code. Note also that by accepting the
62 Public Domain "license" you can re-license your copy using whatever
63 license you like.
64
65 */
66
67 // //////////////////////////////////////////////////////////////////////
68 // End of content of file: LICENSE
69 // //////////////////////////////////////////////////////////////////////
70
71
72
73
74
75
76 #include "json/json.h"
77
78 #ifndef JSON_IS_AMALGAMATION
79 #error "Compile with -I PATH_TO_JSON_DIRECTORY"
80 #endif
81
82
83 // //////////////////////////////////////////////////////////////////////
84 // Beginning of content of file: src/lib_json/json_tool.h
85 // //////////////////////////////////////////////////////////////////////
86
87 // Copyright 2007-2010 Baptiste Lepilleur
88 // Distributed under MIT license, or public domain if desired and
89 // recognized in your jurisdiction.
90 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
91
92 #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
93 #define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
94
95 /* This header provides common string manipulation support, such as UTF-8,
96  * portable conversion from/to string...
97  *
98  * It is an internal header that must not be exposed.
99  */
100
101 namespace Json {
102
103 /// Converts a unicode code-point to UTF-8.
104 static inline std::string codePointToUTF8(unsigned int cp) {
105   std::string result;
106
107   // based on description from http://en.wikipedia.org/wiki/UTF-8
108
109   if (cp <= 0x7f) {
110     result.resize(1);
111     result[0] = static_cast<char>(cp);
112   } else if (cp <= 0x7FF) {
113     result.resize(2);
114     result[1] = static_cast<char>(0x80 | (0x3f & cp));
115     result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
116   } else if (cp <= 0xFFFF) {
117     result.resize(3);
118     result[2] = static_cast<char>(0x80 | (0x3f & cp));
119     result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
120     result[0] = static_cast<char>(0xE0 | (0xf & (cp >> 12)));
121   } else if (cp <= 0x10FFFF) {
122     result.resize(4);
123     result[3] = static_cast<char>(0x80 | (0x3f & cp));
124     result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
125     result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
126     result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
127   }
128
129   return result;
130 }
131
132 /// Returns true if ch is a control character (in range [1,31]).
133 static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; }
134
135 enum {
136   /// Constant that specify the size of the buffer that must be passed to
137   /// uintToString.
138   uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1
139 };
140
141 // Defines a char buffer for use with uintToString().
142 typedef char UIntToStringBuffer[uintToStringBufferSize];
143
144 /** Converts an unsigned integer to string.
145  * @param value Unsigned interger to convert to string
146  * @param current Input/Output string buffer.
147  *        Must have at least uintToStringBufferSize chars free.
148  */
149 static inline void uintToString(LargestUInt value, char*& current) {
150   *--current = 0;
151   do {
152     *--current = static_cast<signed char>(value % 10U + static_cast<unsigned>('0'));
153     value /= 10;
154   } while (value != 0);
155 }
156
157 /** Change ',' to '.' everywhere in buffer.
158  *
159  * We had a sophisticated way, but it did not work in WinCE.
160  * @see https://github.com/open-source-parsers/jsoncpp/pull/9
161  */
162 static inline void fixNumericLocale(char* begin, char* end) {
163   while (begin < end) {
164     if (*begin == ',') {
165       *begin = '.';
166     }
167     ++begin;
168   }
169 }
170
171 } // namespace Json {
172
173 #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
174
175 // //////////////////////////////////////////////////////////////////////
176 // End of content of file: src/lib_json/json_tool.h
177 // //////////////////////////////////////////////////////////////////////
178
179
180
181
182
183
184 // //////////////////////////////////////////////////////////////////////
185 // Beginning of content of file: src/lib_json/json_reader.cpp
186 // //////////////////////////////////////////////////////////////////////
187
188 // Copyright 2007-2011 Baptiste Lepilleur
189 // Distributed under MIT license, or public domain if desired and
190 // recognized in your jurisdiction.
191 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
192
193 #if !defined(JSON_IS_AMALGAMATION)
194 #include <json/assertions.h>
195 #include <json/reader.h>
196 #include <json/value.h>
197 #include "json_tool.h"
198 #endif // if !defined(JSON_IS_AMALGAMATION)
199 #include <utility>
200 #include <cstdio>
201 #include <cassert>
202 #include <cstring>
203 #include <istream>
204 #include <sstream>
205 #include <memory>
206 #include <set>
207 #include <limits>
208
209 #if defined(_MSC_VER)
210 #if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above 
211 #define snprintf sprintf_s
212 #elif _MSC_VER >= 1900 // VC++ 14.0 and above
213 #define snprintf std::snprintf
214 #else
215 #define snprintf _snprintf
216 #endif
217 #elif defined(__ANDROID__) || defined(__QNXNTO__)
218 #define snprintf snprintf
219 #elif __cplusplus >= 201103L
220 #define snprintf std::snprintf
221 #endif
222
223 #if defined(__QNXNTO__)
224 #define sscanf std::sscanf
225 #endif
226
227 #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
228 // Disable warning about strdup being deprecated.
229 #pragma warning(disable : 4996)
230 #endif
231
232 static int const stackLimit_g = 1000;
233 static int       stackDepth_g = 0;  // see readValue()
234
235 namespace Json {
236
237 #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
238 typedef std::unique_ptr<CharReader> CharReaderPtr;
239 #else
240 typedef std::auto_ptr<CharReader>   CharReaderPtr;
241 #endif
242
243 // Implementation of class Features
244 // ////////////////////////////////
245
246 Features::Features()
247     : allowComments_(true), strictRoot_(false),
248       allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}
249
250 Features Features::all() { return Features(); }
251
252 Features Features::strictMode() {
253   Features features;
254   features.allowComments_ = false;
255   features.strictRoot_ = true;
256   features.allowDroppedNullPlaceholders_ = false;
257   features.allowNumericKeys_ = false;
258   return features;
259 }
260
261 // Implementation of class Reader
262 // ////////////////////////////////
263
264 static bool containsNewLine(Reader::Location begin, Reader::Location end) {
265   for (; begin < end; ++begin)
266     if (*begin == '\n' || *begin == '\r')
267       return true;
268   return false;
269 }
270
271 // Class Reader
272 // //////////////////////////////////////////////////////////////////
273
274 Reader::Reader()
275     : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
276       lastValue_(), commentsBefore_(), features_(Features::all()),
277       collectComments_() {}
278
279 Reader::Reader(const Features& features)
280     : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
281       lastValue_(), commentsBefore_(), features_(features), collectComments_() {
282 }
283
284 bool
285 Reader::parse(const std::string& document, Value& root, bool collectComments) {
286   document_ = document;
287   const char* begin = document_.c_str();
288   const char* end = begin + document_.length();
289   return parse(begin, end, root, collectComments);
290 }
291
292 bool Reader::parse(std::istream& sin, Value& root, bool collectComments) {
293   // std::istream_iterator<char> begin(sin);
294   // std::istream_iterator<char> end;
295   // Those would allow streamed input from a file, if parse() were a
296   // template function.
297
298   // Since std::string is reference-counted, this at least does not
299   // create an extra copy.
300   std::string doc;
301   std::getline(sin, doc, (char)EOF);
302   return parse(doc, root, collectComments);
303 }
304
305 bool Reader::parse(const char* beginDoc,
306                    const char* endDoc,
307                    Value& root,
308                    bool collectComments) {
309   if (!features_.allowComments_) {
310     collectComments = false;
311   }
312
313   begin_ = beginDoc;
314   end_ = endDoc;
315   collectComments_ = collectComments;
316   current_ = begin_;
317   lastValueEnd_ = 0;
318   lastValue_ = 0;
319   commentsBefore_ = "";
320   errors_.clear();
321   while (!nodes_.empty())
322     nodes_.pop();
323   nodes_.push(&root);
324
325   stackDepth_g = 0;  // Yes, this is bad coding, but options are limited.
326   bool successful = readValue();
327   Token token;
328   skipCommentTokens(token);
329   if (collectComments_ && !commentsBefore_.empty())
330     root.setComment(commentsBefore_, commentAfter);
331   if (features_.strictRoot_) {
332     if (!root.isArray() && !root.isObject()) {
333       // Set error location to start of doc, ideally should be first token found
334       // in doc
335       token.type_ = tokenError;
336       token.start_ = beginDoc;
337       token.end_ = endDoc;
338       addError(
339           "A valid JSON document must be either an array or an object value.",
340           token);
341       return false;
342     }
343   }
344   return successful;
345 }
346
347 bool Reader::readValue() {
348   // This is a non-reentrant way to support a stackLimit. Terrible!
349   // But this deprecated class has a security problem: Bad input can
350   // cause a seg-fault. This seems like a fair, binary-compatible way
351   // to prevent the problem.
352   if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
353   ++stackDepth_g;
354
355   Token token;
356   skipCommentTokens(token);
357   bool successful = true;
358
359   if (collectComments_ && !commentsBefore_.empty()) {
360     currentValue().setComment(commentsBefore_, commentBefore);
361     commentsBefore_ = "";
362   }
363
364   switch (token.type_) {
365   case tokenObjectBegin:
366     successful = readObject(token);
367     currentValue().setOffsetLimit(current_ - begin_);
368     break;
369   case tokenArrayBegin:
370     successful = readArray(token);
371     currentValue().setOffsetLimit(current_ - begin_);
372     break;
373   case tokenNumber:
374     successful = decodeNumber(token);
375     break;
376   case tokenString:
377     successful = decodeString(token);
378     break;
379   case tokenTrue:
380     {
381     Value v(true);
382     currentValue().swapPayload(v);
383     currentValue().setOffsetStart(token.start_ - begin_);
384     currentValue().setOffsetLimit(token.end_ - begin_);
385     }
386     break;
387   case tokenFalse:
388     {
389     Value v(false);
390     currentValue().swapPayload(v);
391     currentValue().setOffsetStart(token.start_ - begin_);
392     currentValue().setOffsetLimit(token.end_ - begin_);
393     }
394     break;
395   case tokenNull:
396     {
397     Value v;
398     currentValue().swapPayload(v);
399     currentValue().setOffsetStart(token.start_ - begin_);
400     currentValue().setOffsetLimit(token.end_ - begin_);
401     }
402     break;
403   case tokenArraySeparator:
404   case tokenObjectEnd:
405   case tokenArrayEnd:
406     if (features_.allowDroppedNullPlaceholders_) {
407       // "Un-read" the current token and mark the current value as a null
408       // token.
409       current_--;
410       Value v;
411       currentValue().swapPayload(v);
412       currentValue().setOffsetStart(current_ - begin_ - 1);
413       currentValue().setOffsetLimit(current_ - begin_);
414       break;
415     } // Else, fall through...
416   default:
417     currentValue().setOffsetStart(token.start_ - begin_);
418     currentValue().setOffsetLimit(token.end_ - begin_);
419     return addError("Syntax error: value, object or array expected.", token);
420   }
421
422   if (collectComments_) {
423     lastValueEnd_ = current_;
424     lastValue_ = &currentValue();
425   }
426
427   --stackDepth_g;
428   return successful;
429 }
430
431 void Reader::skipCommentTokens(Token& token) {
432   if (features_.allowComments_) {
433     do {
434       readToken(token);
435     } while (token.type_ == tokenComment);
436   } else {
437     readToken(token);
438   }
439 }
440
441 bool Reader::readToken(Token& token) {
442   skipSpaces();
443   token.start_ = current_;
444   Char c = getNextChar();
445   bool ok = true;
446   switch (c) {
447   case '{':
448     token.type_ = tokenObjectBegin;
449     break;
450   case '}':
451     token.type_ = tokenObjectEnd;
452     break;
453   case '[':
454     token.type_ = tokenArrayBegin;
455     break;
456   case ']':
457     token.type_ = tokenArrayEnd;
458     break;
459   case '"':
460     token.type_ = tokenString;
461     ok = readString();
462     break;
463   case '/':
464     token.type_ = tokenComment;
465     ok = readComment();
466     break;
467   case '0':
468   case '1':
469   case '2':
470   case '3':
471   case '4':
472   case '5':
473   case '6':
474   case '7':
475   case '8':
476   case '9':
477   case '-':
478     token.type_ = tokenNumber;
479     readNumber();
480     break;
481   case 't':
482     token.type_ = tokenTrue;
483     ok = match("rue", 3);
484     break;
485   case 'f':
486     token.type_ = tokenFalse;
487     ok = match("alse", 4);
488     break;
489   case 'n':
490     token.type_ = tokenNull;
491     ok = match("ull", 3);
492     break;
493   case ',':
494     token.type_ = tokenArraySeparator;
495     break;
496   case ':':
497     token.type_ = tokenMemberSeparator;
498     break;
499   case 0:
500     token.type_ = tokenEndOfStream;
501     break;
502   default:
503     ok = false;
504     break;
505   }
506   if (!ok)
507     token.type_ = tokenError;
508   token.end_ = current_;
509   return true;
510 }
511
512 void Reader::skipSpaces() {
513   while (current_ != end_) {
514     Char c = *current_;
515     if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
516       ++current_;
517     else
518       break;
519   }
520 }
521
522 bool Reader::match(Location pattern, int patternLength) {
523   if (end_ - current_ < patternLength)
524     return false;
525   int index = patternLength;
526   while (index--)
527     if (current_[index] != pattern[index])
528       return false;
529   current_ += patternLength;
530   return true;
531 }
532
533 bool Reader::readComment() {
534   Location commentBegin = current_ - 1;
535   Char c = getNextChar();
536   bool successful = false;
537   if (c == '*')
538     successful = readCStyleComment();
539   else if (c == '/')
540     successful = readCppStyleComment();
541   if (!successful)
542     return false;
543
544   if (collectComments_) {
545     CommentPlacement placement = commentBefore;
546     if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
547       if (c != '*' || !containsNewLine(commentBegin, current_))
548         placement = commentAfterOnSameLine;
549     }
550
551     addComment(commentBegin, current_, placement);
552   }
553   return true;
554 }
555
556 static std::string normalizeEOL(Reader::Location begin, Reader::Location end) {
557   std::string normalized;
558   normalized.reserve(end - begin);
559   Reader::Location current = begin;
560   while (current != end) {
561     char c = *current++;
562     if (c == '\r') {
563       if (current != end && *current == '\n')
564          // convert dos EOL
565          ++current;
566       // convert Mac EOL
567       normalized += '\n';
568     } else {
569       normalized += c;
570     }
571   }
572   return normalized;
573 }
574
575 void
576 Reader::addComment(Location begin, Location end, CommentPlacement placement) {
577   assert(collectComments_);
578   const std::string& normalized = normalizeEOL(begin, end);
579   if (placement == commentAfterOnSameLine) {
580     assert(lastValue_ != 0);
581     lastValue_->setComment(normalized, placement);
582   } else {
583     commentsBefore_ += normalized;
584   }
585 }
586
587 bool Reader::readCStyleComment() {
588   while (current_ != end_) {
589     Char c = getNextChar();
590     if (c == '*' && *current_ == '/')
591       break;
592   }
593   return getNextChar() == '/';
594 }
595
596 bool Reader::readCppStyleComment() {
597   while (current_ != end_) {
598     Char c = getNextChar();
599     if (c == '\n')
600       break;
601     if (c == '\r') {
602       // Consume DOS EOL. It will be normalized in addComment.
603       if (current_ != end_ && *current_ == '\n')
604         getNextChar();
605       // Break on Moc OS 9 EOL.
606       break;
607     }
608   }
609   return true;
610 }
611
612 void Reader::readNumber() {
613   const char *p = current_;
614   char c = '0'; // stopgap for already consumed character
615   // integral part
616   while (c >= '0' && c <= '9')
617     c = (current_ = p) < end_ ? *p++ : 0;
618   // fractional part
619   if (c == '.') {
620     c = (current_ = p) < end_ ? *p++ : 0;
621     while (c >= '0' && c <= '9')
622       c = (current_ = p) < end_ ? *p++ : 0;
623   }
624   // exponential part
625   if (c == 'e' || c == 'E') {
626     c = (current_ = p) < end_ ? *p++ : 0;
627     if (c == '+' || c == '-')
628       c = (current_ = p) < end_ ? *p++ : 0;
629     while (c >= '0' && c <= '9')
630       c = (current_ = p) < end_ ? *p++ : 0;
631   }
632 }
633
634 bool Reader::readString() {
635   Char c = 0;
636   while (current_ != end_) {
637     c = getNextChar();
638     if (c == '\\')
639       getNextChar();
640     else if (c == '"')
641       break;
642   }
643   return c == '"';
644 }
645
646 bool Reader::readObject(Token& tokenStart) {
647   Token tokenName;
648   std::string name;
649   Value init(objectValue);
650   currentValue().swapPayload(init);
651   currentValue().setOffsetStart(tokenStart.start_ - begin_);
652   while (readToken(tokenName)) {
653     bool initialTokenOk = true;
654     while (tokenName.type_ == tokenComment && initialTokenOk)
655       initialTokenOk = readToken(tokenName);
656     if (!initialTokenOk)
657       break;
658     if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
659       return true;
660     name = "";
661     if (tokenName.type_ == tokenString) {
662       if (!decodeString(tokenName, name))
663         return recoverFromError(tokenObjectEnd);
664     } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
665       Value numberName;
666       if (!decodeNumber(tokenName, numberName))
667         return recoverFromError(tokenObjectEnd);
668       name = numberName.asString();
669     } else {
670       break;
671     }
672
673     Token colon;
674     if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
675       return addErrorAndRecover(
676           "Missing ':' after object member name", colon, tokenObjectEnd);
677     }
678     Value& value = currentValue()[name];
679     nodes_.push(&value);
680     bool ok = readValue();
681     nodes_.pop();
682     if (!ok) // error already set
683       return recoverFromError(tokenObjectEnd);
684
685     Token comma;
686     if (!readToken(comma) ||
687         (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
688          comma.type_ != tokenComment)) {
689       return addErrorAndRecover(
690           "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
691     }
692     bool finalizeTokenOk = true;
693     while (comma.type_ == tokenComment && finalizeTokenOk)
694       finalizeTokenOk = readToken(comma);
695     if (comma.type_ == tokenObjectEnd)
696       return true;
697   }
698   return addErrorAndRecover(
699       "Missing '}' or object member name", tokenName, tokenObjectEnd);
700 }
701
702 bool Reader::readArray(Token& tokenStart) {
703   Value init(arrayValue);
704   currentValue().swapPayload(init);
705   currentValue().setOffsetStart(tokenStart.start_ - begin_);
706   skipSpaces();
707   if (*current_ == ']') // empty array
708   {
709     Token endArray;
710     readToken(endArray);
711     return true;
712   }
713   int index = 0;
714   for (;;) {
715     Value& value = currentValue()[index++];
716     nodes_.push(&value);
717     bool ok = readValue();
718     nodes_.pop();
719     if (!ok) // error already set
720       return recoverFromError(tokenArrayEnd);
721
722     Token token;
723     // Accept Comment after last item in the array.
724     ok = readToken(token);
725     while (token.type_ == tokenComment && ok) {
726       ok = readToken(token);
727     }
728     bool badTokenType =
729         (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
730     if (!ok || badTokenType) {
731       return addErrorAndRecover(
732           "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
733     }
734     if (token.type_ == tokenArrayEnd)
735       break;
736   }
737   return true;
738 }
739
740 bool Reader::decodeNumber(Token& token) {
741   Value decoded;
742   if (!decodeNumber(token, decoded))
743     return false;
744   currentValue().swapPayload(decoded);
745   currentValue().setOffsetStart(token.start_ - begin_);
746   currentValue().setOffsetLimit(token.end_ - begin_);
747   return true;
748 }
749
750 bool Reader::decodeNumber(Token& token, Value& decoded) {
751   // Attempts to parse the number as an integer. If the number is
752   // larger than the maximum supported value of an integer then
753   // we decode the number as a double.
754   Location current = token.start_;
755   bool isNegative = *current == '-';
756   if (isNegative)
757     ++current;
758   // TODO: Help the compiler do the div and mod at compile time or get rid of them.
759   Value::LargestUInt maxIntegerValue =
760       isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
761                  : Value::maxLargestUInt;
762   Value::LargestUInt threshold = maxIntegerValue / 10;
763   Value::LargestUInt value = 0;
764   while (current < token.end_) {
765     Char c = *current++;
766     if (c < '0' || c > '9')
767       return decodeDouble(token, decoded);
768     Value::UInt digit(c - '0');
769     if (value >= threshold) {
770       // We've hit or exceeded the max value divided by 10 (rounded down). If
771       // a) we've only just touched the limit, b) this is the last digit, and
772       // c) it's small enough to fit in that rounding delta, we're okay.
773       // Otherwise treat this number as a double to avoid overflow.
774       if (value > threshold || current != token.end_ ||
775           digit > maxIntegerValue % 10) {
776         return decodeDouble(token, decoded);
777       }
778     }
779     value = value * 10 + digit;
780   }
781   if (isNegative && value == maxIntegerValue)
782     decoded = Value::minLargestInt;
783   else if (isNegative)
784     decoded = -Value::LargestInt(value);
785   else if (value <= Value::LargestUInt(Value::maxInt))
786     decoded = Value::LargestInt(value);
787   else
788     decoded = value;
789   return true;
790 }
791
792 bool Reader::decodeDouble(Token& token) {
793   Value decoded;
794   if (!decodeDouble(token, decoded))
795     return false;
796   currentValue().swapPayload(decoded);
797   currentValue().setOffsetStart(token.start_ - begin_);
798   currentValue().setOffsetLimit(token.end_ - begin_);
799   return true;
800 }
801
802 bool Reader::decodeDouble(Token& token, Value& decoded) {
803   double value = 0;
804   std::string buffer(token.start_, token.end_);
805   std::istringstream is(buffer);
806   if (!(is >> value))
807     return addError("'" + std::string(token.start_, token.end_) +
808                         "' is not a number.",
809                     token);
810   decoded = value;
811   return true;
812 }
813
814 bool Reader::decodeString(Token& token) {
815   std::string decoded_string;
816   if (!decodeString(token, decoded_string))
817     return false;
818   Value decoded(decoded_string);
819   currentValue().swapPayload(decoded);
820   currentValue().setOffsetStart(token.start_ - begin_);
821   currentValue().setOffsetLimit(token.end_ - begin_);
822   return true;
823 }
824
825 bool Reader::decodeString(Token& token, std::string& decoded) {
826   decoded.reserve(token.end_ - token.start_ - 2);
827   Location current = token.start_ + 1; // skip '"'
828   Location end = token.end_ - 1;       // do not include '"'
829   while (current != end) {
830     Char c = *current++;
831     if (c == '"')
832       break;
833     else if (c == '\\') {
834       if (current == end)
835         return addError("Empty escape sequence in string", token, current);
836       Char escape = *current++;
837       switch (escape) {
838       case '"':
839         decoded += '"';
840         break;
841       case '/':
842         decoded += '/';
843         break;
844       case '\\':
845         decoded += '\\';
846         break;
847       case 'b':
848         decoded += '\b';
849         break;
850       case 'f':
851         decoded += '\f';
852         break;
853       case 'n':
854         decoded += '\n';
855         break;
856       case 'r':
857         decoded += '\r';
858         break;
859       case 't':
860         decoded += '\t';
861         break;
862       case 'u': {
863         unsigned int unicode;
864         if (!decodeUnicodeCodePoint(token, current, end, unicode))
865           return false;
866         decoded += codePointToUTF8(unicode);
867       } break;
868       default:
869         return addError("Bad escape sequence in string", token, current);
870       }
871     } else {
872       decoded += c;
873     }
874   }
875   return true;
876 }
877
878 bool Reader::decodeUnicodeCodePoint(Token& token,
879                                     Location& current,
880                                     Location end,
881                                     unsigned int& unicode) {
882
883   if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
884     return false;
885   if (unicode >= 0xD800 && unicode <= 0xDBFF) {
886     // surrogate pairs
887     if (end - current < 6)
888       return addError(
889           "additional six characters expected to parse unicode surrogate pair.",
890           token,
891           current);
892     unsigned int surrogatePair;
893     if (*(current++) == '\\' && *(current++) == 'u') {
894       if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
895         unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
896       } else
897         return false;
898     } else
899       return addError("expecting another \\u token to begin the second half of "
900                       "a unicode surrogate pair",
901                       token,
902                       current);
903   }
904   return true;
905 }
906
907 bool Reader::decodeUnicodeEscapeSequence(Token& token,
908                                          Location& current,
909                                          Location end,
910                                          unsigned int& unicode) {
911   if (end - current < 4)
912     return addError(
913         "Bad unicode escape sequence in string: four digits expected.",
914         token,
915         current);
916   unicode = 0;
917   for (int index = 0; index < 4; ++index) {
918     Char c = *current++;
919     unicode *= 16;
920     if (c >= '0' && c <= '9')
921       unicode += c - '0';
922     else if (c >= 'a' && c <= 'f')
923       unicode += c - 'a' + 10;
924     else if (c >= 'A' && c <= 'F')
925       unicode += c - 'A' + 10;
926     else
927       return addError(
928           "Bad unicode escape sequence in string: hexadecimal digit expected.",
929           token,
930           current);
931   }
932   return true;
933 }
934
935 bool
936 Reader::addError(const std::string& message, Token& token, Location extra) {
937   ErrorInfo info;
938   info.token_ = token;
939   info.message_ = message;
940   info.extra_ = extra;
941   errors_.push_back(info);
942   return false;
943 }
944
945 bool Reader::recoverFromError(TokenType skipUntilToken) {
946   int errorCount = int(errors_.size());
947   Token skip;
948   for (;;) {
949     if (!readToken(skip))
950       errors_.resize(errorCount); // discard errors caused by recovery
951     if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
952       break;
953   }
954   errors_.resize(errorCount);
955   return false;
956 }
957
958 bool Reader::addErrorAndRecover(const std::string& message,
959                                 Token& token,
960                                 TokenType skipUntilToken) {
961   addError(message, token);
962   return recoverFromError(skipUntilToken);
963 }
964
965 Value& Reader::currentValue() { return *(nodes_.top()); }
966
967 Reader::Char Reader::getNextChar() {
968   if (current_ == end_)
969     return 0;
970   return *current_++;
971 }
972
973 void Reader::getLocationLineAndColumn(Location location,
974                                       int& line,
975                                       int& column) const {
976   Location current = begin_;
977   Location lastLineStart = current;
978   line = 0;
979   while (current < location && current != end_) {
980     Char c = *current++;
981     if (c == '\r') {
982       if (*current == '\n')
983         ++current;
984       lastLineStart = current;
985       ++line;
986     } else if (c == '\n') {
987       lastLineStart = current;
988       ++line;
989     }
990   }
991   // column & line start at 1
992   column = int(location - lastLineStart) + 1;
993   ++line;
994 }
995
996 std::string Reader::getLocationLineAndColumn(Location location) const {
997   int line, column;
998   getLocationLineAndColumn(location, line, column);
999   char buffer[18 + 16 + 16 + 1];
1000   snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
1001   return buffer;
1002 }
1003
1004 std::string Reader::getLocationSnippet(Location location) const {
1005        std::string snippet = "";
1006        std::istringstream docStream(document_);
1007        int lin, col;
1008        getLocationLineAndColumn(location, lin, col);
1009        std::string line;
1010        for (int i=1; i<lin+2 && std::getline(docStream, line); i++)
1011        {
1012               if (lin-i < 2)
1013               {
1014                      snippet += "  " + std::to_string(i) + ": " + line + "\n";
1015               }
1016        }
1017        return snippet;
1018 }
1019
1020 // Deprecated. Preserved for backward compatibility
1021 std::string Reader::getFormatedErrorMessages() const {
1022   return getFormattedErrorMessages();
1023 }
1024
1025 std::string Reader::getFormattedErrorMessages() const {
1026   std::string formattedMessage;
1027   for (Errors::const_iterator itError = errors_.begin();
1028        itError != errors_.end();
1029        ++itError) {
1030     const ErrorInfo& error = *itError;
1031     formattedMessage +=
1032         "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
1033        formattedMessage += getLocationSnippet(error.token_.start_) + "\n";
1034     formattedMessage += "  " + error.message_ + "\n";
1035     if (error.extra_)
1036       formattedMessage +=
1037           "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
1038   }
1039   return formattedMessage;
1040 }
1041
1042 std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
1043   std::vector<Reader::StructuredError> allErrors;
1044   for (Errors::const_iterator itError = errors_.begin();
1045        itError != errors_.end();
1046        ++itError) {
1047     const ErrorInfo& error = *itError;
1048     Reader::StructuredError structured;
1049     structured.offset_start = error.token_.start_ - begin_;
1050     structured.offset_limit = error.token_.end_ - begin_;
1051     structured.message = error.message_;
1052     allErrors.push_back(structured);
1053   }
1054   return allErrors;
1055 }
1056
1057 bool Reader::pushError(const Value& value, const std::string& message) {
1058   size_t length = end_ - begin_;
1059   if(value.getOffsetStart() > length
1060     || value.getOffsetLimit() > length)
1061     return false;
1062   Token token;
1063   token.type_ = tokenError;
1064   token.start_ = begin_ + value.getOffsetStart();
1065   token.end_ = end_ + value.getOffsetLimit();
1066   ErrorInfo info;
1067   info.token_ = token;
1068   info.message_ = message;
1069   info.extra_ = 0;
1070   errors_.push_back(info);
1071   return true;
1072 }
1073
1074 bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) {
1075   size_t length = end_ - begin_;
1076   if(value.getOffsetStart() > length
1077     || value.getOffsetLimit() > length
1078     || extra.getOffsetLimit() > length)
1079     return false;
1080   Token token;
1081   token.type_ = tokenError;
1082   token.start_ = begin_ + value.getOffsetStart();
1083   token.end_ = begin_ + value.getOffsetLimit();
1084   ErrorInfo info;
1085   info.token_ = token;
1086   info.message_ = message;
1087   info.extra_ = begin_ + extra.getOffsetStart();
1088   errors_.push_back(info);
1089   return true;
1090 }
1091
1092 bool Reader::good() const {
1093   return !errors_.size();
1094 }
1095
1096 // exact copy of Features
1097 class OurFeatures {
1098 public:
1099   static OurFeatures all();
1100   bool allowComments_;
1101   bool strictRoot_;
1102   bool allowDroppedNullPlaceholders_;
1103   bool allowNumericKeys_;
1104   bool allowSingleQuotes_;
1105   bool failIfExtra_;
1106   bool rejectDupKeys_;
1107   bool allowSpecialFloats_;
1108   int stackLimit_;
1109 };  // OurFeatures
1110
1111 // exact copy of Implementation of class Features
1112 // ////////////////////////////////
1113
1114 OurFeatures OurFeatures::all() { return OurFeatures(); }
1115
1116 // Implementation of class Reader
1117 // ////////////////////////////////
1118
1119 // exact copy of Reader, renamed to OurReader
1120 class OurReader {
1121 public:
1122   typedef char Char;
1123   typedef const Char* Location;
1124   struct StructuredError {
1125     size_t offset_start;
1126     size_t offset_limit;
1127     std::string message;
1128   };
1129
1130   OurReader(OurFeatures const& features);
1131   bool parse(const char* beginDoc,
1132              const char* endDoc,
1133              Value& root,
1134              bool collectComments = true);
1135   std::string getFormattedErrorMessages() const;
1136   std::vector<StructuredError> getStructuredErrors() const;
1137   bool pushError(const Value& value, const std::string& message);
1138   bool pushError(const Value& value, const std::string& message, const Value& extra);
1139   bool good() const;
1140
1141 private:
1142   OurReader(OurReader const&);  // no impl
1143   void operator=(OurReader const&);  // no impl
1144
1145   enum TokenType {
1146     tokenEndOfStream = 0,
1147     tokenObjectBegin,
1148     tokenObjectEnd,
1149     tokenArrayBegin,
1150     tokenArrayEnd,
1151     tokenString,
1152     tokenNumber,
1153     tokenTrue,
1154     tokenFalse,
1155     tokenNull,
1156     tokenNaN,
1157     tokenPosInf,
1158     tokenNegInf,
1159     tokenArraySeparator,
1160     tokenMemberSeparator,
1161     tokenComment,
1162     tokenError
1163   };
1164
1165   class Token {
1166   public:
1167     TokenType type_;
1168     Location start_;
1169     Location end_;
1170   };
1171
1172   class ErrorInfo {
1173   public:
1174     Token token_;
1175     std::string message_;
1176     Location extra_;
1177   };
1178
1179   typedef std::deque<ErrorInfo> Errors;
1180
1181   bool readToken(Token& token);
1182   void skipSpaces();
1183   bool match(Location pattern, int patternLength);
1184   bool readComment();
1185   bool readCStyleComment();
1186   bool readCppStyleComment();
1187   bool readString();
1188   bool readStringSingleQuote();
1189   bool readNumber(bool checkInf);
1190   bool readValue();
1191   bool readObject(Token& token);
1192   bool readArray(Token& token);
1193   bool decodeNumber(Token& token);
1194   bool decodeNumber(Token& token, Value& decoded);
1195   bool decodeString(Token& token);
1196   bool decodeString(Token& token, std::string& decoded);
1197   bool decodeDouble(Token& token);
1198   bool decodeDouble(Token& token, Value& decoded);
1199   bool decodeUnicodeCodePoint(Token& token,
1200                               Location& current,
1201                               Location end,
1202                               unsigned int& unicode);
1203   bool decodeUnicodeEscapeSequence(Token& token,
1204                                    Location& current,
1205                                    Location end,
1206                                    unsigned int& unicode);
1207   bool addError(const std::string& message, Token& token, Location extra = 0);
1208   bool recoverFromError(TokenType skipUntilToken);
1209   bool addErrorAndRecover(const std::string& message,
1210                           Token& token,
1211                           TokenType skipUntilToken);
1212   void skipUntilSpace();
1213   Value& currentValue();
1214   Char getNextChar();
1215   void
1216   getLocationLineAndColumn(Location location, int& line, int& column) const;
1217   std::string getLocationLineAndColumn(Location location) const;
1218   void addComment(Location begin, Location end, CommentPlacement placement);
1219   void skipCommentTokens(Token& token);
1220
1221   typedef std::stack<Value*> Nodes;
1222   Nodes nodes_;
1223   Errors errors_;
1224   std::string document_;
1225   Location begin_;
1226   Location end_;
1227   Location current_;
1228   Location lastValueEnd_;
1229   Value* lastValue_;
1230   std::string commentsBefore_;
1231   int stackDepth_;
1232
1233   OurFeatures const features_;
1234   bool collectComments_;
1235 };  // OurReader
1236
1237 // complete copy of Read impl, for OurReader
1238
1239 OurReader::OurReader(OurFeatures const& features)
1240     : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
1241       lastValue_(), commentsBefore_(),
1242       stackDepth_(0),
1243       features_(features), collectComments_() {
1244 }
1245
1246 bool OurReader::parse(const char* beginDoc,
1247                    const char* endDoc,
1248                    Value& root,
1249                    bool collectComments) {
1250   if (!features_.allowComments_) {
1251     collectComments = false;
1252   }
1253
1254   begin_ = beginDoc;
1255   end_ = endDoc;
1256   collectComments_ = collectComments;
1257   current_ = begin_;
1258   lastValueEnd_ = 0;
1259   lastValue_ = 0;
1260   commentsBefore_ = "";
1261   errors_.clear();
1262   while (!nodes_.empty())
1263     nodes_.pop();
1264   nodes_.push(&root);
1265
1266   stackDepth_ = 0;
1267   bool successful = readValue();
1268   Token token;
1269   skipCommentTokens(token);
1270   if (features_.failIfExtra_) {
1271     if (token.type_ != tokenError && token.type_ != tokenEndOfStream) {
1272       addError("Extra non-whitespace after JSON value.", token);
1273       return false;
1274     }
1275   }
1276   if (collectComments_ && !commentsBefore_.empty())
1277     root.setComment(commentsBefore_, commentAfter);
1278   if (features_.strictRoot_) {
1279     if (!root.isArray() && !root.isObject()) {
1280       // Set error location to start of doc, ideally should be first token found
1281       // in doc
1282       token.type_ = tokenError;
1283       token.start_ = beginDoc;
1284       token.end_ = endDoc;
1285       addError(
1286           "A valid JSON document must be either an array or an object value.",
1287           token);
1288       return false;
1289     }
1290   }
1291   return successful;
1292 }
1293
1294 bool OurReader::readValue() {
1295   if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
1296   ++stackDepth_;
1297   Token token;
1298   skipCommentTokens(token);
1299   bool successful = true;
1300
1301   if (collectComments_ && !commentsBefore_.empty()) {
1302     currentValue().setComment(commentsBefore_, commentBefore);
1303     commentsBefore_ = "";
1304   }
1305
1306   switch (token.type_) {
1307   case tokenObjectBegin:
1308     successful = readObject(token);
1309     currentValue().setOffsetLimit(current_ - begin_);
1310     break;
1311   case tokenArrayBegin:
1312     successful = readArray(token);
1313     currentValue().setOffsetLimit(current_ - begin_);
1314     break;
1315   case tokenNumber:
1316     successful = decodeNumber(token);
1317     break;
1318   case tokenString:
1319     successful = decodeString(token);
1320     break;
1321   case tokenTrue:
1322     {
1323     Value v(true);
1324     currentValue().swapPayload(v);
1325     currentValue().setOffsetStart(token.start_ - begin_);
1326     currentValue().setOffsetLimit(token.end_ - begin_);
1327     }
1328     break;
1329   case tokenFalse:
1330     {
1331     Value v(false);
1332     currentValue().swapPayload(v);
1333     currentValue().setOffsetStart(token.start_ - begin_);
1334     currentValue().setOffsetLimit(token.end_ - begin_);
1335     }
1336     break;
1337   case tokenNull:
1338     {
1339     Value v;
1340     currentValue().swapPayload(v);
1341     currentValue().setOffsetStart(token.start_ - begin_);
1342     currentValue().setOffsetLimit(token.end_ - begin_);
1343     }
1344     break;
1345   case tokenNaN:
1346     {
1347     Value v(std::numeric_limits<double>::quiet_NaN());
1348     currentValue().swapPayload(v);
1349     currentValue().setOffsetStart(token.start_ - begin_);
1350     currentValue().setOffsetLimit(token.end_ - begin_);
1351     }
1352     break;
1353   case tokenPosInf:
1354     {
1355     Value v(std::numeric_limits<double>::infinity());
1356     currentValue().swapPayload(v);
1357     currentValue().setOffsetStart(token.start_ - begin_);
1358     currentValue().setOffsetLimit(token.end_ - begin_);
1359     }
1360     break;
1361   case tokenNegInf:
1362     {
1363     Value v(-std::numeric_limits<double>::infinity());
1364     currentValue().swapPayload(v);
1365     currentValue().setOffsetStart(token.start_ - begin_);
1366     currentValue().setOffsetLimit(token.end_ - begin_);
1367     }
1368     break;
1369   case tokenArraySeparator:
1370   case tokenObjectEnd:
1371   case tokenArrayEnd:
1372     if (features_.allowDroppedNullPlaceholders_) {
1373       // "Un-read" the current token and mark the current value as a null
1374       // token.
1375       current_--;
1376       Value v;
1377       currentValue().swapPayload(v);
1378       currentValue().setOffsetStart(current_ - begin_ - 1);
1379       currentValue().setOffsetLimit(current_ - begin_);
1380       break;
1381     } // else, fall through ...
1382   default:
1383     currentValue().setOffsetStart(token.start_ - begin_);
1384     currentValue().setOffsetLimit(token.end_ - begin_);
1385     return addError("Syntax error: value, object or array expected.", token);
1386   }
1387
1388   if (collectComments_) {
1389     lastValueEnd_ = current_;
1390     lastValue_ = &currentValue();
1391   }
1392
1393   --stackDepth_;
1394   return successful;
1395 }
1396
1397 void OurReader::skipCommentTokens(Token& token) {
1398   if (features_.allowComments_) {
1399     do {
1400       readToken(token);
1401     } while (token.type_ == tokenComment);
1402   } else {
1403     readToken(token);
1404   }
1405 }
1406
1407 bool OurReader::readToken(Token& token) {
1408   skipSpaces();
1409   token.start_ = current_;
1410   Char c = getNextChar();
1411   bool ok = true;
1412   switch (c) {
1413   case '{':
1414     token.type_ = tokenObjectBegin;
1415     break;
1416   case '}':
1417     token.type_ = tokenObjectEnd;
1418     break;
1419   case '[':
1420     token.type_ = tokenArrayBegin;
1421     break;
1422   case ']':
1423     token.type_ = tokenArrayEnd;
1424     break;
1425   case '"':
1426     token.type_ = tokenString;
1427     ok = readString();
1428     break;
1429   case '\'':
1430     if (features_.allowSingleQuotes_) {
1431     token.type_ = tokenString;
1432     ok = readStringSingleQuote();
1433     break;
1434     } // else continue
1435   case '/':
1436     token.type_ = tokenComment;
1437     ok = readComment();
1438     break;
1439   case '0':
1440   case '1':
1441   case '2':
1442   case '3':
1443   case '4':
1444   case '5':
1445   case '6':
1446   case '7':
1447   case '8':
1448   case '9':
1449     token.type_ = tokenNumber;
1450     readNumber(false);
1451     break;
1452   case '-':
1453     if (readNumber(true)) {
1454       token.type_ = tokenNumber;
1455     } else {
1456       token.type_ = tokenNegInf;
1457       ok = features_.allowSpecialFloats_ && match("nfinity", 7);
1458     }
1459     break;
1460   case 't':
1461     token.type_ = tokenTrue;
1462     ok = match("rue", 3);
1463     break;
1464   case 'f':
1465     token.type_ = tokenFalse;
1466     ok = match("alse", 4);
1467     break;
1468   case 'n':
1469     token.type_ = tokenNull;
1470     ok = match("ull", 3);
1471     break;
1472   case 'N':
1473     if (features_.allowSpecialFloats_) {
1474       token.type_ = tokenNaN;
1475       ok = match("aN", 2);
1476     } else {
1477       ok = false;
1478     }
1479     break;
1480   case 'I':
1481     if (features_.allowSpecialFloats_) {
1482       token.type_ = tokenPosInf;
1483       ok = match("nfinity", 7);
1484     } else {
1485       ok = false;
1486     }
1487     break;
1488   case ',':
1489     token.type_ = tokenArraySeparator;
1490     break;
1491   case ':':
1492     token.type_ = tokenMemberSeparator;
1493     break;
1494   case 0:
1495     token.type_ = tokenEndOfStream;
1496     break;
1497   default:
1498     ok = false;
1499     break;
1500   }
1501   if (!ok)
1502     token.type_ = tokenError;
1503   token.end_ = current_;
1504   return true;
1505 }
1506
1507 void OurReader::skipSpaces() {
1508   while (current_ != end_) {
1509     Char c = *current_;
1510     if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
1511       ++current_;
1512     else
1513       break;
1514   }
1515 }
1516
1517 bool OurReader::match(Location pattern, int patternLength) {
1518   if (end_ - current_ < patternLength)
1519     return false;
1520   int index = patternLength;
1521   while (index--)
1522     if (current_[index] != pattern[index])
1523       return false;
1524   current_ += patternLength;
1525   return true;
1526 }
1527
1528 bool OurReader::readComment() {
1529   Location commentBegin = current_ - 1;
1530   Char c = getNextChar();
1531   bool successful = false;
1532   if (c == '*')
1533     successful = readCStyleComment();
1534   else if (c == '/')
1535     successful = readCppStyleComment();
1536   if (!successful)
1537     return false;
1538
1539   if (collectComments_) {
1540     CommentPlacement placement = commentBefore;
1541     if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
1542       if (c != '*' || !containsNewLine(commentBegin, current_))
1543         placement = commentAfterOnSameLine;
1544     }
1545
1546     addComment(commentBegin, current_, placement);
1547   }
1548   return true;
1549 }
1550
1551 void
1552 OurReader::addComment(Location begin, Location end, CommentPlacement placement) {
1553   assert(collectComments_);
1554   const std::string& normalized = normalizeEOL(begin, end);
1555   if (placement == commentAfterOnSameLine) {
1556     assert(lastValue_ != 0);
1557     lastValue_->setComment(normalized, placement);
1558   } else {
1559     commentsBefore_ += normalized;
1560   }
1561 }
1562
1563 bool OurReader::readCStyleComment() {
1564   while (current_ != end_) {
1565     Char c = getNextChar();
1566     if (c == '*' && *current_ == '/')
1567       break;
1568   }
1569   return getNextChar() == '/';
1570 }
1571
1572 bool OurReader::readCppStyleComment() {
1573   while (current_ != end_) {
1574     Char c = getNextChar();
1575     if (c == '\n')
1576       break;
1577     if (c == '\r') {
1578       // Consume DOS EOL. It will be normalized in addComment.
1579       if (current_ != end_ && *current_ == '\n')
1580         getNextChar();
1581       // Break on Moc OS 9 EOL.
1582       break;
1583     }
1584   }
1585   return true;
1586 }
1587
1588 bool OurReader::readNumber(bool checkInf) {
1589   const char *p = current_;
1590   if (checkInf && p != end_ && *p == 'I') {
1591     current_ = ++p;
1592     return false;
1593   }
1594   char c = '0'; // stopgap for already consumed character
1595   // integral part
1596   while (c >= '0' && c <= '9')
1597     c = (current_ = p) < end_ ? *p++ : 0;
1598   // fractional part
1599   if (c == '.') {
1600     c = (current_ = p) < end_ ? *p++ : 0;
1601     while (c >= '0' && c <= '9')
1602       c = (current_ = p) < end_ ? *p++ : 0;
1603   }
1604   // exponential part
1605   if (c == 'e' || c == 'E') {
1606     c = (current_ = p) < end_ ? *p++ : 0;
1607     if (c == '+' || c == '-')
1608       c = (current_ = p) < end_ ? *p++ : 0;
1609     while (c >= '0' && c <= '9')
1610       c = (current_ = p) < end_ ? *p++ : 0;
1611   }
1612   return true;
1613 }
1614 bool OurReader::readString() {
1615   Char c = 0;
1616   while (current_ != end_) {
1617     c = getNextChar();
1618     if (c == '\\')
1619       getNextChar();
1620     else if (c == '"')
1621       break;
1622   }
1623   return c == '"';
1624 }
1625
1626
1627 bool OurReader::readStringSingleQuote() {
1628   Char c = 0;
1629   while (current_ != end_) {
1630     c = getNextChar();
1631     if (c == '\\')
1632       getNextChar();
1633     else if (c == '\'')
1634       break;
1635   }
1636   return c == '\'';
1637 }
1638
1639 bool OurReader::readObject(Token& tokenStart) {
1640   Token tokenName;
1641   std::string name;
1642   Value init(objectValue);
1643   currentValue().swapPayload(init);
1644   currentValue().setOffsetStart(tokenStart.start_ - begin_);
1645   while (readToken(tokenName)) {
1646     bool initialTokenOk = true;
1647     while (tokenName.type_ == tokenComment && initialTokenOk)
1648       initialTokenOk = readToken(tokenName);
1649     if (!initialTokenOk)
1650       break;
1651     if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
1652       return true;
1653     name = "";
1654     if (tokenName.type_ == tokenString) {
1655       if (!decodeString(tokenName, name))
1656         return recoverFromError(tokenObjectEnd);
1657     } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
1658       Value numberName;
1659       if (!decodeNumber(tokenName, numberName))
1660         return recoverFromError(tokenObjectEnd);
1661       name = numberName.asString();
1662     } else {
1663       break;
1664     }
1665
1666     Token colon;
1667     if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
1668       return addErrorAndRecover(
1669           "Missing ':' after object member name", colon, tokenObjectEnd);
1670     }
1671     if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
1672     if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
1673       std::string msg = "Duplicate key: '" + name + "'";
1674       return addErrorAndRecover(
1675           msg, tokenName, tokenObjectEnd);
1676     }
1677     Value& value = currentValue()[name];
1678     nodes_.push(&value);
1679     bool ok = readValue();
1680     nodes_.pop();
1681     if (!ok) // error already set
1682       return recoverFromError(tokenObjectEnd);
1683
1684     Token comma;
1685     if (!readToken(comma) ||
1686         (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
1687          comma.type_ != tokenComment)) {
1688       return addErrorAndRecover(
1689           "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
1690     }
1691     bool finalizeTokenOk = true;
1692     while (comma.type_ == tokenComment && finalizeTokenOk)
1693       finalizeTokenOk = readToken(comma);
1694     if (comma.type_ == tokenObjectEnd)
1695       return true;
1696   }
1697   return addErrorAndRecover(
1698       "Missing '}' or object member name", tokenName, tokenObjectEnd);
1699 }
1700
1701 bool OurReader::readArray(Token& tokenStart) {
1702   Value init(arrayValue);
1703   currentValue().swapPayload(init);
1704   currentValue().setOffsetStart(tokenStart.start_ - begin_);
1705   skipSpaces();
1706   if (*current_ == ']') // empty array
1707   {
1708     Token endArray;
1709     readToken(endArray);
1710     return true;
1711   }
1712   int index = 0;
1713   for (;;) {
1714     Value& value = currentValue()[index++];
1715     nodes_.push(&value);
1716     bool ok = readValue();
1717     nodes_.pop();
1718     if (!ok) // error already set
1719       return recoverFromError(tokenArrayEnd);
1720
1721     Token token;
1722     // Accept Comment after last item in the array.
1723     ok = readToken(token);
1724     while (token.type_ == tokenComment && ok) {
1725       ok = readToken(token);
1726     }
1727     bool badTokenType =
1728         (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
1729     if (!ok || badTokenType) {
1730       return addErrorAndRecover(
1731           "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
1732     }
1733     if (token.type_ == tokenArrayEnd)
1734       break;
1735   }
1736   return true;
1737 }
1738
1739 bool OurReader::decodeNumber(Token& token) {
1740   Value decoded;
1741   if (!decodeNumber(token, decoded))
1742     return false;
1743   currentValue().swapPayload(decoded);
1744   currentValue().setOffsetStart(token.start_ - begin_);
1745   currentValue().setOffsetLimit(token.end_ - begin_);
1746   return true;
1747 }
1748
1749 bool OurReader::decodeNumber(Token& token, Value& decoded) {
1750   // Attempts to parse the number as an integer. If the number is
1751   // larger than the maximum supported value of an integer then
1752   // we decode the number as a double.
1753   Location current = token.start_;
1754   bool isNegative = *current == '-';
1755   if (isNegative)
1756     ++current;
1757   // TODO: Help the compiler do the div and mod at compile time or get rid of them.
1758   Value::LargestUInt maxIntegerValue =
1759       isNegative ? Value::LargestUInt(-Value::minLargestInt)
1760                  : Value::maxLargestUInt;
1761   Value::LargestUInt threshold = maxIntegerValue / 10;
1762   Value::LargestUInt value = 0;
1763   while (current < token.end_) {
1764     Char c = *current++;
1765     if (c < '0' || c > '9')
1766       return decodeDouble(token, decoded);
1767     Value::UInt digit(c - '0');
1768     if (value >= threshold) {
1769       // We've hit or exceeded the max value divided by 10 (rounded down). If
1770       // a) we've only just touched the limit, b) this is the last digit, and
1771       // c) it's small enough to fit in that rounding delta, we're okay.
1772       // Otherwise treat this number as a double to avoid overflow.
1773       if (value > threshold || current != token.end_ ||
1774           digit > maxIntegerValue % 10) {
1775         return decodeDouble(token, decoded);
1776       }
1777     }
1778     value = value * 10 + digit;
1779   }
1780   if (isNegative)
1781     decoded = -Value::LargestInt(value);
1782   else if (value <= Value::LargestUInt(Value::maxInt))
1783     decoded = Value::LargestInt(value);
1784   else
1785     decoded = value;
1786   return true;
1787 }
1788
1789 bool OurReader::decodeDouble(Token& token) {
1790   Value decoded;
1791   if (!decodeDouble(token, decoded))
1792     return false;
1793   currentValue().swapPayload(decoded);
1794   currentValue().setOffsetStart(token.start_ - begin_);
1795   currentValue().setOffsetLimit(token.end_ - begin_);
1796   return true;
1797 }
1798
1799 bool OurReader::decodeDouble(Token& token, Value& decoded) {
1800   double value = 0;
1801   const int bufferSize = 32;
1802   int count;
1803   int length = int(token.end_ - token.start_);
1804
1805   // Sanity check to avoid buffer overflow exploits.
1806   if (length < 0) {
1807     return addError("Unable to parse token length", token);
1808   }
1809
1810   // Avoid using a string constant for the format control string given to
1811   // sscanf, as this can cause hard to debug crashes on OS X. See here for more
1812   // info:
1813   //
1814   //     http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
1815   char format[] = "%lf";
1816
1817   if (length <= bufferSize) {
1818     Char buffer[bufferSize + 1];
1819     memcpy(buffer, token.start_, length);
1820     buffer[length] = 0;
1821     count = sscanf(buffer, format, &value);
1822   } else {
1823     std::string buffer(token.start_, token.end_);
1824     count = sscanf(buffer.c_str(), format, &value);
1825   }
1826
1827   if (count != 1)
1828     return addError("'" + std::string(token.start_, token.end_) +
1829                         "' is not a number.",
1830                     token);
1831   decoded = value;
1832   return true;
1833 }
1834
1835 bool OurReader::decodeString(Token& token) {
1836   std::string decoded_string;
1837   if (!decodeString(token, decoded_string))
1838     return false;
1839   Value decoded(decoded_string);
1840   currentValue().swapPayload(decoded);
1841   currentValue().setOffsetStart(token.start_ - begin_);
1842   currentValue().setOffsetLimit(token.end_ - begin_);
1843   return true;
1844 }
1845
1846 bool OurReader::decodeString(Token& token, std::string& decoded) {
1847   decoded.reserve(token.end_ - token.start_ - 2);
1848   Location current = token.start_ + 1; // skip '"'
1849   Location end = token.end_ - 1;       // do not include '"'
1850   while (current != end) {
1851     Char c = *current++;
1852     if (c == '"')
1853       break;
1854     else if (c == '\\') {
1855       if (current == end)
1856         return addError("Empty escape sequence in string", token, current);
1857       Char escape = *current++;
1858       switch (escape) {
1859       case '"':
1860         decoded += '"';
1861         break;
1862       case '/':
1863         decoded += '/';
1864         break;
1865       case '\\':
1866         decoded += '\\';
1867         break;
1868       case 'b':
1869         decoded += '\b';
1870         break;
1871       case 'f':
1872         decoded += '\f';
1873         break;
1874       case 'n':
1875         decoded += '\n';
1876         break;
1877       case 'r':
1878         decoded += '\r';
1879         break;
1880       case 't':
1881         decoded += '\t';
1882         break;
1883       case 'u': {
1884         unsigned int unicode;
1885         if (!decodeUnicodeCodePoint(token, current, end, unicode))
1886           return false;
1887         decoded += codePointToUTF8(unicode);
1888       } break;
1889       default:
1890         return addError("Bad escape sequence in string", token, current);
1891       }
1892     } else {
1893       decoded += c;
1894     }
1895   }
1896   return true;
1897 }
1898
1899 bool OurReader::decodeUnicodeCodePoint(Token& token,
1900                                     Location& current,
1901                                     Location end,
1902                                     unsigned int& unicode) {
1903
1904   if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
1905     return false;
1906   if (unicode >= 0xD800 && unicode <= 0xDBFF) {
1907     // surrogate pairs
1908     if (end - current < 6)
1909       return addError(
1910           "additional six characters expected to parse unicode surrogate pair.",
1911           token,
1912           current);
1913     unsigned int surrogatePair;
1914     if (*(current++) == '\\' && *(current++) == 'u') {
1915       if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
1916         unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
1917       } else
1918         return false;
1919     } else
1920       return addError("expecting another \\u token to begin the second half of "
1921                       "a unicode surrogate pair",
1922                       token,
1923                       current);
1924   }
1925   return true;
1926 }
1927
1928 bool OurReader::decodeUnicodeEscapeSequence(Token& token,
1929                                          Location& current,
1930                                          Location end,
1931                                          unsigned int& unicode) {
1932   if (end - current < 4)
1933     return addError(
1934         "Bad unicode escape sequence in string: four digits expected.",
1935         token,
1936         current);
1937   unicode = 0;
1938   for (int index = 0; index < 4; ++index) {
1939     Char c = *current++;
1940     unicode *= 16;
1941     if (c >= '0' && c <= '9')
1942       unicode += c - '0';
1943     else if (c >= 'a' && c <= 'f')
1944       unicode += c - 'a' + 10;
1945     else if (c >= 'A' && c <= 'F')
1946       unicode += c - 'A' + 10;
1947     else
1948       return addError(
1949           "Bad unicode escape sequence in string: hexadecimal digit expected.",
1950           token,
1951           current);
1952   }
1953   return true;
1954 }
1955
1956 bool
1957 OurReader::addError(const std::string& message, Token& token, Location extra) {
1958   ErrorInfo info;
1959   info.token_ = token;
1960   info.message_ = message;
1961   info.extra_ = extra;
1962   errors_.push_back(info);
1963   return false;
1964 }
1965
1966 bool OurReader::recoverFromError(TokenType skipUntilToken) {
1967   int errorCount = int(errors_.size());
1968   Token skip;
1969   for (;;) {
1970     if (!readToken(skip))
1971       errors_.resize(errorCount); // discard errors caused by recovery
1972     if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
1973       break;
1974   }
1975   errors_.resize(errorCount);
1976   return false;
1977 }
1978
1979 bool OurReader::addErrorAndRecover(const std::string& message,
1980                                 Token& token,
1981                                 TokenType skipUntilToken) {
1982   addError(message, token);
1983   return recoverFromError(skipUntilToken);
1984 }
1985
1986 Value& OurReader::currentValue() { return *(nodes_.top()); }
1987
1988 OurReader::Char OurReader::getNextChar() {
1989   if (current_ == end_)
1990     return 0;
1991   return *current_++;
1992 }
1993
1994 void OurReader::getLocationLineAndColumn(Location location,
1995                                       int& line,
1996                                       int& column) const {
1997   Location current = begin_;
1998   Location lastLineStart = current;
1999   line = 0;
2000   while (current < location && current != end_) {
2001     Char c = *current++;
2002     if (c == '\r') {
2003       if (*current == '\n')
2004         ++current;
2005       lastLineStart = current;
2006       ++line;
2007     } else if (c == '\n') {
2008       lastLineStart = current;
2009       ++line;
2010     }
2011   }
2012   // column & line start at 1
2013   column = int(location - lastLineStart) + 1;
2014   ++line;
2015 }
2016
2017 std::string OurReader::getLocationLineAndColumn(Location location) const {
2018   int line, column;
2019   getLocationLineAndColumn(location, line, column);
2020   char buffer[18 + 16 + 16 + 1];
2021   snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
2022   return buffer;
2023 }
2024
2025 std::string OurReader::getFormattedErrorMessages() const {
2026   std::string formattedMessage;
2027   for (Errors::const_iterator itError = errors_.begin();
2028        itError != errors_.end();
2029        ++itError) {
2030     const ErrorInfo& error = *itError;
2031     formattedMessage +=
2032         "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
2033     formattedMessage += "  " + error.message_ + "\n";
2034     if (error.extra_)
2035       formattedMessage +=
2036           "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
2037   }
2038   return formattedMessage;
2039 }
2040
2041 std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
2042   std::vector<OurReader::StructuredError> allErrors;
2043   for (Errors::const_iterator itError = errors_.begin();
2044        itError != errors_.end();
2045        ++itError) {
2046     const ErrorInfo& error = *itError;
2047     OurReader::StructuredError structured;
2048     structured.offset_start = error.token_.start_ - begin_;
2049     structured.offset_limit = error.token_.end_ - begin_;
2050     structured.message = error.message_;
2051     allErrors.push_back(structured);
2052   }
2053   return allErrors;
2054 }
2055
2056 bool OurReader::pushError(const Value& value, const std::string& message) {
2057   size_t length = end_ - begin_;
2058   if(value.getOffsetStart() > length
2059     || value.getOffsetLimit() > length)
2060     return false;
2061   Token token;
2062   token.type_ = tokenError;
2063   token.start_ = begin_ + value.getOffsetStart();
2064   token.end_ = end_ + value.getOffsetLimit();
2065   ErrorInfo info;
2066   info.token_ = token;
2067   info.message_ = message;
2068   info.extra_ = 0;
2069   errors_.push_back(info);
2070   return true;
2071 }
2072
2073 bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) {
2074   size_t length = end_ - begin_;
2075   if(value.getOffsetStart() > length
2076     || value.getOffsetLimit() > length
2077     || extra.getOffsetLimit() > length)
2078     return false;
2079   Token token;
2080   token.type_ = tokenError;
2081   token.start_ = begin_ + value.getOffsetStart();
2082   token.end_ = begin_ + value.getOffsetLimit();
2083   ErrorInfo info;
2084   info.token_ = token;
2085   info.message_ = message;
2086   info.extra_ = begin_ + extra.getOffsetStart();
2087   errors_.push_back(info);
2088   return true;
2089 }
2090
2091 bool OurReader::good() const {
2092   return !errors_.size();
2093 }
2094
2095
2096 class OurCharReader : public CharReader {
2097   bool const collectComments_;
2098   OurReader reader_;
2099 public:
2100   OurCharReader(
2101     bool collectComments,
2102     OurFeatures const& features)
2103   : collectComments_(collectComments)
2104   , reader_(features)
2105   {}
2106   bool parse(
2107       char const* beginDoc, char const* endDoc,
2108       Value* root, std::string* errs) {
2109     bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
2110     if (errs) {
2111       *errs = reader_.getFormattedErrorMessages();
2112     }
2113     return ok;
2114   }
2115 };
2116
2117 CharReaderBuilder::CharReaderBuilder()
2118 {
2119   setDefaults(&settings_);
2120 }
2121 CharReaderBuilder::~CharReaderBuilder()
2122 {}
2123 CharReader* CharReaderBuilder::newCharReader() const
2124 {
2125   bool collectComments = settings_["collectComments"].asBool();
2126   OurFeatures features = OurFeatures::all();
2127   features.allowComments_ = settings_["allowComments"].asBool();
2128   features.strictRoot_ = settings_["strictRoot"].asBool();
2129   features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool();
2130   features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
2131   features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
2132   features.stackLimit_ = settings_["stackLimit"].asInt();
2133   features.failIfExtra_ = settings_["failIfExtra"].asBool();
2134   features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool();
2135   features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
2136   return new OurCharReader(collectComments, features);
2137 }
2138 static void getValidReaderKeys(std::set<std::string>* valid_keys)
2139 {
2140   valid_keys->clear();
2141   valid_keys->insert("collectComments");
2142   valid_keys->insert("allowComments");
2143   valid_keys->insert("strictRoot");
2144   valid_keys->insert("allowDroppedNullPlaceholders");
2145   valid_keys->insert("allowNumericKeys");
2146   valid_keys->insert("allowSingleQuotes");
2147   valid_keys->insert("stackLimit");
2148   valid_keys->insert("failIfExtra");
2149   valid_keys->insert("rejectDupKeys");
2150   valid_keys->insert("allowSpecialFloats");
2151 }
2152 bool CharReaderBuilder::validate(Json::Value* invalid) const
2153 {
2154   Json::Value my_invalid;
2155   if (!invalid) invalid = &my_invalid;  // so we do not need to test for NULL
2156   Json::Value& inv = *invalid;
2157   std::set<std::string> valid_keys;
2158   getValidReaderKeys(&valid_keys);
2159   Value::Members keys = settings_.getMemberNames();
2160   size_t n = keys.size();
2161   for (size_t i = 0; i < n; ++i) {
2162     std::string const& key = keys[i];
2163     if (valid_keys.find(key) == valid_keys.end()) {
2164       inv[key] = settings_[key];
2165     }
2166   }
2167   return 0u == inv.size();
2168 }
2169 Value& CharReaderBuilder::operator[](std::string key)
2170 {
2171   return settings_[key];
2172 }
2173 // static
2174 void CharReaderBuilder::strictMode(Json::Value* settings)
2175 {
2176 //! [CharReaderBuilderStrictMode]
2177   (*settings)["allowComments"] = false;
2178   (*settings)["strictRoot"] = true;
2179   (*settings)["allowDroppedNullPlaceholders"] = false;
2180   (*settings)["allowNumericKeys"] = false;
2181   (*settings)["allowSingleQuotes"] = false;
2182   (*settings)["stackLimit"] = 1000;
2183   (*settings)["failIfExtra"] = true;
2184   (*settings)["rejectDupKeys"] = true;
2185   (*settings)["allowSpecialFloats"] = false;
2186 //! [CharReaderBuilderStrictMode]
2187 }
2188 // static
2189 void CharReaderBuilder::setDefaults(Json::Value* settings)
2190 {
2191 //! [CharReaderBuilderDefaults]
2192   (*settings)["collectComments"] = true;
2193   (*settings)["allowComments"] = true;
2194   (*settings)["strictRoot"] = false;
2195   (*settings)["allowDroppedNullPlaceholders"] = false;
2196   (*settings)["allowNumericKeys"] = false;
2197   (*settings)["allowSingleQuotes"] = false;
2198   (*settings)["stackLimit"] = 1000;
2199   (*settings)["failIfExtra"] = false;
2200   (*settings)["rejectDupKeys"] = false;
2201   (*settings)["allowSpecialFloats"] = false;
2202 //! [CharReaderBuilderDefaults]
2203 }
2204
2205 //////////////////////////////////
2206 // global functions
2207
2208 bool parseFromStream(
2209     CharReader::Factory const& fact, std::istream& sin,
2210     Value* root, std::string* errs)
2211 {
2212   std::ostringstream ssin;
2213   ssin << sin.rdbuf();
2214   std::string doc = ssin.str();
2215   char const* begin = doc.data();
2216   char const* end = begin + doc.size();
2217   // Note that we do not actually need a null-terminator.
2218   CharReaderPtr const reader(fact.newCharReader());
2219   return reader->parse(begin, end, root, errs);
2220 }
2221
2222 std::istream& operator>>(std::istream& sin, Value& root) {
2223   CharReaderBuilder b;
2224   std::string errs;
2225   bool ok = parseFromStream(b, sin, &root, &errs);
2226   if (!ok) {
2227     fprintf(stderr,
2228             "Error from reader: %s",
2229             errs.c_str());
2230
2231     throwRuntimeError(errs);
2232   }
2233   return sin;
2234 }
2235
2236 } // namespace Json
2237
2238 // //////////////////////////////////////////////////////////////////////
2239 // End of content of file: src/lib_json/json_reader.cpp
2240 // //////////////////////////////////////////////////////////////////////
2241
2242
2243
2244
2245
2246
2247 // //////////////////////////////////////////////////////////////////////
2248 // Beginning of content of file: src/lib_json/json_valueiterator.inl
2249 // //////////////////////////////////////////////////////////////////////
2250
2251 // Copyright 2007-2010 Baptiste Lepilleur
2252 // Distributed under MIT license, or public domain if desired and
2253 // recognized in your jurisdiction.
2254 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
2255
2256 // included by json_value.cpp
2257
2258 namespace Json {
2259
2260 // //////////////////////////////////////////////////////////////////
2261 // //////////////////////////////////////////////////////////////////
2262 // //////////////////////////////////////////////////////////////////
2263 // class ValueIteratorBase
2264 // //////////////////////////////////////////////////////////////////
2265 // //////////////////////////////////////////////////////////////////
2266 // //////////////////////////////////////////////////////////////////
2267
2268 ValueIteratorBase::ValueIteratorBase()
2269     : current_(), isNull_(true) {
2270 }
2271
2272 ValueIteratorBase::ValueIteratorBase(
2273     const Value::ObjectValues::iterator& current)
2274     : current_(current), isNull_(false) {}
2275
2276 Value& ValueIteratorBase::deref() const {
2277   return current_->second;
2278 }
2279
2280 void ValueIteratorBase::increment() {
2281   ++current_;
2282 }
2283
2284 void ValueIteratorBase::decrement() {
2285   --current_;
2286 }
2287
2288 ValueIteratorBase::difference_type
2289 ValueIteratorBase::computeDistance(const SelfType& other) const {
2290 #ifdef JSON_USE_CPPTL_SMALLMAP
2291   return other.current_ - current_;
2292 #else
2293   // Iterator for null value are initialized using the default
2294   // constructor, which initialize current_ to the default
2295   // std::map::iterator. As begin() and end() are two instance
2296   // of the default std::map::iterator, they can not be compared.
2297   // To allow this, we handle this comparison specifically.
2298   if (isNull_ && other.isNull_) {
2299     return 0;
2300   }
2301
2302   // Usage of std::distance is not portable (does not compile with Sun Studio 12
2303   // RogueWave STL,
2304   // which is the one used by default).
2305   // Using a portable hand-made version for non random iterator instead:
2306   //   return difference_type( std::distance( current_, other.current_ ) );
2307   difference_type myDistance = 0;
2308   for (Value::ObjectValues::iterator it = current_; it != other.current_;
2309        ++it) {
2310     ++myDistance;
2311   }
2312   return myDistance;
2313 #endif
2314 }
2315
2316 bool ValueIteratorBase::isEqual(const SelfType& other) const {
2317   if (isNull_) {
2318     return other.isNull_;
2319   }
2320   return current_ == other.current_;
2321 }
2322
2323 void ValueIteratorBase::copy(const SelfType& other) {
2324   current_ = other.current_;
2325   isNull_ = other.isNull_;
2326 }
2327
2328 Value ValueIteratorBase::key() const {
2329   const Value::CZString czstring = (*current_).first;
2330   if (czstring.data()) {
2331     if (czstring.isStaticString())
2332       return Value(StaticString(czstring.data()));
2333     return Value(czstring.data(), czstring.data() + czstring.length());
2334   }
2335   return Value(czstring.index());
2336 }
2337
2338 UInt ValueIteratorBase::index() const {
2339   const Value::CZString czstring = (*current_).first;
2340   if (!czstring.data())
2341     return czstring.index();
2342   return Value::UInt(-1);
2343 }
2344
2345 std::string ValueIteratorBase::name() const {
2346   char const* keey;
2347   char const* end;
2348   keey = memberName(&end);
2349   if (!keey) return std::string();
2350   return std::string(keey, end);
2351 }
2352
2353 char const* ValueIteratorBase::memberName() const {
2354   const char* cname = (*current_).first.data();
2355   return cname ? cname : "";
2356 }
2357
2358 char const* ValueIteratorBase::memberName(char const** end) const {
2359   const char* cname = (*current_).first.data();
2360   if (!cname) {
2361     *end = NULL;
2362     return NULL;
2363   }
2364   *end = cname + (*current_).first.length();
2365   return cname;
2366 }
2367
2368 // //////////////////////////////////////////////////////////////////
2369 // //////////////////////////////////////////////////////////////////
2370 // //////////////////////////////////////////////////////////////////
2371 // class ValueConstIterator
2372 // //////////////////////////////////////////////////////////////////
2373 // //////////////////////////////////////////////////////////////////
2374 // //////////////////////////////////////////////////////////////////
2375
2376 ValueConstIterator::ValueConstIterator() {}
2377
2378 ValueConstIterator::ValueConstIterator(
2379     const Value::ObjectValues::iterator& current)
2380     : ValueIteratorBase(current) {}
2381
2382 ValueConstIterator::ValueConstIterator(ValueIterator const& other)
2383     : ValueIteratorBase(other) {}
2384
2385 ValueConstIterator& ValueConstIterator::
2386 operator=(const ValueIteratorBase& other) {
2387   copy(other);
2388   return *this;
2389 }
2390
2391 // //////////////////////////////////////////////////////////////////
2392 // //////////////////////////////////////////////////////////////////
2393 // //////////////////////////////////////////////////////////////////
2394 // class ValueIterator
2395 // //////////////////////////////////////////////////////////////////
2396 // //////////////////////////////////////////////////////////////////
2397 // //////////////////////////////////////////////////////////////////
2398
2399 ValueIterator::ValueIterator() {}
2400
2401 ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
2402     : ValueIteratorBase(current) {}
2403
2404 ValueIterator::ValueIterator(const ValueConstIterator& other)
2405     : ValueIteratorBase(other) {
2406   throwRuntimeError("ConstIterator to Iterator should never be allowed.");
2407 }
2408
2409 ValueIterator::ValueIterator(const ValueIterator& other)
2410     : ValueIteratorBase(other) {}
2411
2412 ValueIterator& ValueIterator::operator=(const SelfType& other) {
2413   copy(other);
2414   return *this;
2415 }
2416
2417 } // namespace Json
2418
2419 // //////////////////////////////////////////////////////////////////////
2420 // End of content of file: src/lib_json/json_valueiterator.inl
2421 // //////////////////////////////////////////////////////////////////////
2422
2423
2424
2425
2426
2427
2428 // //////////////////////////////////////////////////////////////////////
2429 // Beginning of content of file: src/lib_json/json_value.cpp
2430 // //////////////////////////////////////////////////////////////////////
2431
2432 // Copyright 2011 Baptiste Lepilleur
2433 // Distributed under MIT license, or public domain if desired and
2434 // recognized in your jurisdiction.
2435 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
2436
2437 #if !defined(JSON_IS_AMALGAMATION)
2438 #include <json/assertions.h>
2439 #include <json/value.h>
2440 #include <json/writer.h>
2441 #endif // if !defined(JSON_IS_AMALGAMATION)
2442 #include <math.h>
2443 #include <sstream>
2444 #include <utility>
2445 #include <cstring>
2446 #include <cassert>
2447 #ifdef JSON_USE_CPPTL
2448 #include <cpptl/conststring.h>
2449 #endif
2450 #include <cstddef> // size_t
2451 #include <algorithm> // min()
2452
2453 #define JSON_ASSERT_UNREACHABLE assert(false)
2454
2455 /*
2456 -- Valve 1/7/16
2457 4702 unreachable code
2458 */
2459 #pragma warning (push)
2460 #pragma warning (disable: 4702)
2461
2462 namespace Json {
2463
2464 // This is a walkaround to avoid the static initialization of Value::null.
2465 // kNull must be word-aligned to avoid crashing on ARM.  We use an alignment of
2466 // 8 (instead of 4) as a bit of future-proofing.
2467 #if defined(__ARMEL__)
2468 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
2469 #else
2470 #define ALIGNAS(byte_alignment)
2471 #endif
2472 static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
2473 const unsigned char& kNullRef = kNull[0];
2474 const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
2475 const Value& Value::nullRef = null;
2476
2477 const Int Value::minInt = Int(~(UInt(-1) / 2));
2478 const Int Value::maxInt = Int(UInt(-1) / 2);
2479 const UInt Value::maxUInt = UInt(-1);
2480 #if defined(JSON_HAS_INT64)
2481 const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
2482 const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
2483 const UInt64 Value::maxUInt64 = UInt64(-1);
2484 // The constant is hard-coded because some compiler have trouble
2485 // converting Value::maxUInt64 to a double correctly (AIX/xlC).
2486 // Assumes that UInt64 is a 64 bits integer.
2487 static const double maxUInt64AsDouble = 18446744073709551615.0;
2488 #endif // defined(JSON_HAS_INT64)
2489 const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
2490 const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
2491 const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
2492
2493 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
2494 template <typename T, typename U>
2495 static inline bool InRange(double d, T min, U max) {
2496   return d >= min && d <= max;
2497 }
2498 #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
2499 static inline double integerToDouble(Json::UInt64 value) {
2500   return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1);
2501 }
2502
2503 template <typename T> static inline double integerToDouble(T value) {
2504   return static_cast<double>(value);
2505 }
2506
2507 template <typename T, typename U>
2508 static inline bool InRange(double d, T min, U max) {
2509   return d >= integerToDouble(min) && d <= integerToDouble(max);
2510 }
2511 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
2512
2513 /** Duplicates the specified string value.
2514  * @param value Pointer to the string to duplicate. Must be zero-terminated if
2515  *              length is "unknown".
2516  * @param length Length of the value. if equals to unknown, then it will be
2517  *               computed using strlen(value).
2518  * @return Pointer on the duplicate instance of string.
2519  */
2520 static inline char* duplicateStringValue(const char* value,
2521                                          size_t length) {
2522   // Avoid an integer overflow in the call to malloc below by limiting length
2523   // to a sane value.
2524   if (length >= (size_t)Value::maxInt)
2525     length = Value::maxInt - 1;
2526
2527   char* newString = static_cast<char*>(malloc(length + 1));
2528   if (newString == NULL) {
2529     throwRuntimeError(
2530         "in Json::Value::duplicateStringValue(): "
2531         "Failed to allocate string value buffer");
2532   }
2533   memcpy(newString, value, length);
2534   newString[length] = 0;
2535   return newString;
2536 }
2537
2538 /* Record the length as a prefix.
2539  */
2540 static inline char* duplicateAndPrefixStringValue(
2541     const char* value,
2542     unsigned int length)
2543 {
2544   // Avoid an integer overflow in the call to malloc below by limiting length
2545   // to a sane value.
2546   JSON_ASSERT_MESSAGE(length <= (unsigned)Value::maxInt - sizeof(unsigned) - 1U,
2547                       "in Json::Value::duplicateAndPrefixStringValue(): "
2548                       "length too big for prefixing");
2549   unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
2550   char* newString = static_cast<char*>(malloc(actualLength));
2551   if (newString == 0) {
2552     throwRuntimeError(
2553         "in Json::Value::duplicateAndPrefixStringValue(): "
2554         "Failed to allocate string value buffer");
2555   }
2556   *reinterpret_cast<unsigned*>(newString) = length;
2557   memcpy(newString + sizeof(unsigned), value, length);
2558   newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
2559   return newString;
2560 }
2561 inline static void decodePrefixedString(
2562     bool isPrefixed, char const* prefixed,
2563     unsigned* length, char const** value)
2564 {
2565   if (!isPrefixed) {
2566     *length = static_cast<unsigned>(strlen(prefixed));
2567     *value = prefixed;
2568   } else {
2569     *length = *reinterpret_cast<unsigned const*>(prefixed);
2570     *value = prefixed + sizeof(unsigned);
2571   }
2572 }
2573 /** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
2574  */
2575 static inline void releaseStringValue(char* value) { free(value); }
2576
2577 } // namespace Json
2578
2579 // //////////////////////////////////////////////////////////////////
2580 // //////////////////////////////////////////////////////////////////
2581 // //////////////////////////////////////////////////////////////////
2582 // ValueInternals...
2583 // //////////////////////////////////////////////////////////////////
2584 // //////////////////////////////////////////////////////////////////
2585 // //////////////////////////////////////////////////////////////////
2586 #if !defined(JSON_IS_AMALGAMATION)
2587
2588 #include "json_valueiterator.inl"
2589 #endif // if !defined(JSON_IS_AMALGAMATION)
2590
2591 namespace Json {
2592
2593 Exception::Exception(std::string const& msg)
2594   : msg_(msg)
2595 {}
2596 Exception::~Exception() throw()
2597 {}
2598 char const* Exception::what() const throw()
2599 {
2600   return msg_.c_str();
2601 }
2602 RuntimeError::RuntimeError(std::string const& msg)
2603   : Exception(msg)
2604 {}
2605 LogicError::LogicError(std::string const& msg)
2606   : Exception(msg)
2607 {}
2608 void throwRuntimeError(std::string const& msg)
2609 {
2610   throw RuntimeError(msg);
2611 }
2612 void throwLogicError(std::string const& msg)
2613 {
2614   throw LogicError(msg);
2615 }
2616
2617 // //////////////////////////////////////////////////////////////////
2618 // //////////////////////////////////////////////////////////////////
2619 // //////////////////////////////////////////////////////////////////
2620 // class Value::CommentInfo
2621 // //////////////////////////////////////////////////////////////////
2622 // //////////////////////////////////////////////////////////////////
2623 // //////////////////////////////////////////////////////////////////
2624
2625 Value::CommentInfo::CommentInfo() : comment_(0) {}
2626
2627 Value::CommentInfo::~CommentInfo() {
2628   if (comment_)
2629     releaseStringValue(comment_);
2630 }
2631
2632 void Value::CommentInfo::setComment(const char* text, size_t len) {
2633   if (comment_) {
2634     releaseStringValue(comment_);
2635     comment_ = 0;
2636   }
2637   JSON_ASSERT(text != 0);
2638   JSON_ASSERT_MESSAGE(
2639       text[0] == '\0' || text[0] == '/',
2640       "in Json::Value::setComment(): Comments must start with /");
2641   // It seems that /**/ style comments are acceptable as well.
2642   comment_ = duplicateStringValue(text, len);
2643 }
2644
2645 // //////////////////////////////////////////////////////////////////
2646 // //////////////////////////////////////////////////////////////////
2647 // //////////////////////////////////////////////////////////////////
2648 // class Value::CZString
2649 // //////////////////////////////////////////////////////////////////
2650 // //////////////////////////////////////////////////////////////////
2651 // //////////////////////////////////////////////////////////////////
2652
2653 // Notes: policy_ indicates if the string was allocated when
2654 // a string is stored.
2655
2656 Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}
2657
2658 Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate)
2659     : cstr_(str) {
2660   // allocate != duplicate
2661   storage_.policy_ = allocate & 0x3;
2662   storage_.length_ = ulength & 0x3FFFFFFF;
2663 }
2664
2665 Value::CZString::CZString(const CZString& other)
2666     : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
2667                 ? duplicateStringValue(other.cstr_, other.storage_.length_)
2668                 : other.cstr_) {
2669   storage_.policy_ = (other.cstr_
2670                  ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
2671                      ? noDuplication : duplicate)
2672                  : static_cast<DuplicationPolicy>(other.storage_.policy_));
2673   storage_.length_ = other.storage_.length_;
2674 }
2675
2676 #if JSON_HAS_RVALUE_REFERENCES
2677 Value::CZString::CZString(CZString&& other)
2678   : cstr_(other.cstr_), index_(other.index_) {
2679   other.cstr_ = nullptr;
2680 }
2681 #endif
2682
2683 Value::CZString::~CZString() {
2684   if (cstr_ && storage_.policy_ == duplicate)
2685     releaseStringValue(const_cast<char*>(cstr_));
2686 }
2687
2688 void Value::CZString::swap(CZString& other) {
2689   std::swap(cstr_, other.cstr_);
2690   std::swap(index_, other.index_);
2691 }
2692
2693 Value::CZString& Value::CZString::operator=(CZString other) {
2694   swap(other);
2695   return *this;
2696 }
2697
2698 bool Value::CZString::operator<(const CZString& other) const {
2699   if (!cstr_) return index_ < other.index_;
2700   //return strcmp(cstr_, other.cstr_) < 0;
2701   // Assume both are strings.
2702   unsigned this_len = this->storage_.length_;
2703   unsigned other_len = other.storage_.length_;
2704   unsigned min_len = std::min(this_len, other_len);
2705   int comp = memcmp(this->cstr_, other.cstr_, min_len);
2706   if (comp < 0) return true;
2707   if (comp > 0) return false;
2708   return (this_len < other_len);
2709 }
2710
2711 bool Value::CZString::operator==(const CZString& other) const {
2712   if (!cstr_) return index_ == other.index_;
2713   //return strcmp(cstr_, other.cstr_) == 0;
2714   // Assume both are strings.
2715   unsigned this_len = this->storage_.length_;
2716   unsigned other_len = other.storage_.length_;
2717   if (this_len != other_len) return false;
2718   int comp = memcmp(this->cstr_, other.cstr_, this_len);
2719   return comp == 0;
2720 }
2721
2722 ArrayIndex Value::CZString::index() const { return index_; }
2723
2724 //const char* Value::CZString::c_str() const { return cstr_; }
2725 const char* Value::CZString::data() const { return cstr_; }
2726 unsigned Value::CZString::length() const { return storage_.length_; }
2727 bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; }
2728
2729 // //////////////////////////////////////////////////////////////////
2730 // //////////////////////////////////////////////////////////////////
2731 // //////////////////////////////////////////////////////////////////
2732 // class Value::Value
2733 // //////////////////////////////////////////////////////////////////
2734 // //////////////////////////////////////////////////////////////////
2735 // //////////////////////////////////////////////////////////////////
2736
2737 /*! \internal Default constructor initialization must be equivalent to:
2738  * memset( this, 0, sizeof(Value) )
2739  * This optimization is used in ValueInternalMap fast allocator.
2740  */
2741 Value::Value(ValueType vtype) {
2742   initBasic(vtype);
2743   switch (vtype) {
2744   case nullValue:
2745     break;
2746   case intValue:
2747   case uintValue:
2748     value_.int_ = 0;
2749     break;
2750   case realValue:
2751     value_.real_ = 0.0;
2752     break;
2753   case stringValue:
2754     value_.string_ = 0;
2755     break;
2756   case arrayValue:
2757   case objectValue:
2758     value_.map_ = new ObjectValues();
2759     break;
2760   case booleanValue:
2761     value_.bool_ = false;
2762     break;
2763   default:
2764     JSON_ASSERT_UNREACHABLE;
2765   }
2766 }
2767
2768 Value::Value(Int value) {
2769   initBasic(intValue);
2770   value_.int_ = value;
2771 }
2772
2773 Value::Value(UInt value) {
2774   initBasic(uintValue);
2775   value_.uint_ = value;
2776 }
2777 #if defined(JSON_HAS_INT64)
2778 Value::Value(Int64 value) {
2779   initBasic(intValue);
2780   value_.int_ = value;
2781 }
2782 Value::Value(UInt64 value) {
2783   initBasic(uintValue);
2784   value_.uint_ = value;
2785 }
2786 #endif // defined(JSON_HAS_INT64)
2787
2788 Value::Value(double value) {
2789   initBasic(realValue);
2790   value_.real_ = value;
2791 }
2792
2793 Value::Value(const char* value) {
2794   initBasic(stringValue, true);
2795   value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
2796 }
2797
2798 Value::Value(const char* beginValue, const char* endValue) {
2799   initBasic(stringValue, true);
2800   value_.string_ =
2801       duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
2802 }
2803
2804 Value::Value(const std::string& value) {
2805   initBasic(stringValue, true);
2806   value_.string_ =
2807       duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
2808 }
2809
2810 Value::Value(const StaticString& value) {
2811   initBasic(stringValue);
2812   value_.string_ = const_cast<char*>(value.c_str());
2813 }
2814
2815 #ifdef JSON_USE_CPPTL
2816 Value::Value(const CppTL::ConstString& value) {
2817   initBasic(stringValue, true);
2818   value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
2819 }
2820 #endif
2821
2822 Value::Value(bool value) {
2823   initBasic(booleanValue);
2824   value_.bool_ = value;
2825 }
2826
2827 Value::Value(Value const& other)
2828     : type_(other.type_), allocated_(false)
2829       ,
2830       comments_(nullptr), default_value_(nullptr), start_(other.start_), limit_(other.limit_)
2831 {
2832   switch (type_) {
2833   case nullValue:
2834   case intValue:
2835   case uintValue:
2836   case realValue:
2837   case booleanValue:
2838     value_ = other.value_;
2839     break;
2840   case stringValue:
2841     if (other.value_.string_ && other.allocated_) {
2842       unsigned len;
2843       char const* str;
2844       decodePrefixedString(other.allocated_, other.value_.string_,
2845           &len, &str);
2846       value_.string_ = duplicateAndPrefixStringValue(str, len);
2847       allocated_ = true;
2848     } else {
2849       value_.string_ = other.value_.string_;
2850       allocated_ = false;
2851     }
2852     break;
2853   case arrayValue:
2854   case objectValue:
2855     value_.map_ = new ObjectValues(*other.value_.map_);
2856     break;
2857   default:
2858     JSON_ASSERT_UNREACHABLE;
2859   }
2860   if (other.comments_) {
2861     comments_ = new CommentInfo[numberOfCommentPlacement];
2862     for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
2863       const CommentInfo& otherComment = other.comments_[comment];
2864       if (otherComment.comment_)
2865         comments_[comment].setComment(
2866             otherComment.comment_, strlen(otherComment.comment_));
2867     }
2868   }
2869
2870   if ( other.default_value_ )
2871   {
2872          default_value_ = new Value( *other.default_value_ );
2873   }
2874
2875 }
2876
2877 #if JSON_HAS_RVALUE_REFERENCES
2878 // Move constructor
2879 Value::Value(Value&& other) {
2880   initBasic(nullValue);
2881   swap(other);
2882 }
2883 #endif
2884
2885 Value::~Value() {
2886   switch (type_) {
2887   case nullValue:
2888   case intValue:
2889   case uintValue:
2890   case realValue:
2891   case booleanValue:
2892     break;
2893   case stringValue:
2894     if (allocated_)
2895       releaseStringValue(value_.string_);
2896     break;
2897   case arrayValue:
2898   case objectValue:
2899     delete value_.map_;
2900     break;
2901   default:
2902     JSON_ASSERT_UNREACHABLE;
2903   }
2904
2905   if (comments_)
2906     delete[] comments_;
2907
2908   if ( default_value_)
2909          delete default_value_;
2910 }
2911
2912 Value& Value::operator=(Value other) {
2913   swap(other);
2914   return *this;
2915 }
2916
2917 void Value::swapPayload(Value& other) {
2918   ValueType temp = type_;
2919   type_ = other.type_;
2920   other.type_ = temp;
2921   std::swap(value_, other.value_);
2922   int temp2 = allocated_;
2923   allocated_ = other.allocated_;
2924   other.allocated_ = temp2 & 0x1;
2925 }
2926
2927 void Value::swap(Value& other) {
2928   swapPayload(other);
2929   std::swap(comments_, other.comments_);
2930   std::swap(default_value_, other.default_value_);
2931   std::swap(start_, other.start_);
2932   std::swap(limit_, other.limit_);
2933 }
2934
2935 ValueType Value::type() const { return type_; }
2936
2937 int Value::compare(const Value& other) const {
2938   if (*this < other)
2939     return -1;
2940   if (*this > other)
2941     return 1;
2942   return 0;
2943 }
2944
2945 bool Value::operator<(const Value& other) const {
2946   int typeDelta = type_ - other.type_;
2947   if (typeDelta)
2948     return typeDelta < 0 ? true : false;
2949   switch (type_) {
2950   case nullValue:
2951     return false;
2952   case intValue:
2953     return value_.int_ < other.value_.int_;
2954   case uintValue:
2955     return value_.uint_ < other.value_.uint_;
2956   case realValue:
2957     return value_.real_ < other.value_.real_;
2958   case booleanValue:
2959     return value_.bool_ < other.value_.bool_;
2960   case stringValue:
2961   {
2962     if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
2963       if (other.value_.string_) return true;
2964       else return false;
2965     }
2966     unsigned this_len;
2967     unsigned other_len;
2968     char const* this_str;
2969     char const* other_str;
2970     decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
2971     decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
2972     unsigned min_len = std::min(this_len, other_len);
2973     int comp = memcmp(this_str, other_str, min_len);
2974     if (comp < 0) return true;
2975     if (comp > 0) return false;
2976     return (this_len < other_len);
2977   }
2978   case arrayValue:
2979   case objectValue: {
2980     int delta = int(value_.map_->size() - other.value_.map_->size());
2981     if (delta)
2982       return delta < 0;
2983     return (*value_.map_) < (*other.value_.map_);
2984   }
2985   default:
2986     JSON_ASSERT_UNREACHABLE;
2987   }
2988   return false; // unreachable
2989 }
2990
2991 bool Value::operator<=(const Value& other) const { return !(other < *this); }
2992
2993 bool Value::operator>=(const Value& other) const { return !(*this < other); }
2994
2995 bool Value::operator>(const Value& other) const { return other < *this; }
2996
2997 bool Value::operator==(const Value& other) const {
2998   // if ( type_ != other.type_ )
2999   // GCC 2.95.3 says:
3000   // attempt to take address of bit-field structure member `Json::Value::type_'
3001   // Beats me, but a temp solves the problem.
3002   int temp = other.type_;
3003   if (type_ != temp)
3004     return false;
3005   switch (type_) {
3006   case nullValue:
3007     return true;
3008   case intValue:
3009     return value_.int_ == other.value_.int_;
3010   case uintValue:
3011     return value_.uint_ == other.value_.uint_;
3012   case realValue:
3013     return value_.real_ == other.value_.real_;
3014   case booleanValue:
3015     return value_.bool_ == other.value_.bool_;
3016   case stringValue:
3017   {
3018     if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
3019       return (value_.string_ == other.value_.string_);
3020     }
3021     unsigned this_len;
3022     unsigned other_len;
3023     char const* this_str;
3024     char const* other_str;
3025     decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
3026     decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
3027     if (this_len != other_len) return false;
3028     int comp = memcmp(this_str, other_str, this_len);
3029     return comp == 0;
3030   }
3031   case arrayValue:
3032   case objectValue:
3033     return value_.map_->size() == other.value_.map_->size() &&
3034            (*value_.map_) == (*other.value_.map_);
3035   default:
3036     JSON_ASSERT_UNREACHABLE;
3037   }
3038   return false; // unreachable
3039 }
3040
3041 bool Value::operator!=(const Value& other) const { return !(*this == other); }
3042
3043 const char* Value::asCString() const {
3044   JSON_ASSERT_MESSAGE(type_ == stringValue,
3045                       "in Json::Value::asCString(): requires stringValue");
3046   if (value_.string_ == 0) return 0;
3047   unsigned this_len;
3048   char const* this_str;
3049   decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
3050   return this_str;
3051 }
3052
3053 bool Value::getString(char const** str, char const** cend) const {
3054   if (type_ != stringValue) return false;
3055   if (value_.string_ == 0) return false;
3056   unsigned length;
3057   decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
3058   *cend = *str + length;
3059   return true;
3060 }
3061
3062 std::string Value::asString() const {
3063   switch (type_) {
3064   case nullValue:
3065     return "";
3066   case stringValue:
3067   {
3068     if (value_.string_ == 0) return "";
3069     unsigned this_len;
3070     char const* this_str;
3071     decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
3072     return std::string(this_str, this_len);
3073   }
3074   case booleanValue:
3075     return value_.bool_ ? "true" : "false";
3076   case intValue:
3077     return valueToString(value_.int_);
3078   case uintValue:
3079     return valueToString(value_.uint_);
3080   case realValue:
3081     return valueToString(value_.real_);
3082   default:
3083          if ( default_value_ )
3084                 return default_value_->asString();
3085          else
3086                 return "";
3087   }
3088 }
3089
3090 #ifdef JSON_USE_CPPTL
3091 CppTL::ConstString Value::asConstString() const {
3092   unsigned len;
3093   char const* str;
3094   decodePrefixedString(allocated_, value_.string_,
3095       &len, &str);
3096   return CppTL::ConstString(str, len);
3097 }
3098 #endif
3099
3100 Value::Int Value::asInt() const {
3101   switch (type_) {
3102   case intValue:
3103     JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
3104     return Int(value_.int_);
3105   case uintValue:
3106     JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
3107     return Int(value_.uint_);
3108   case realValue:
3109     JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
3110                         "double out of Int range");
3111     return Int(value_.real_);
3112   case nullValue:
3113     return 0;
3114   case booleanValue:
3115     return value_.bool_ ? 1 : 0;
3116   default:
3117          if ( default_value_ )
3118                 return default_value_->asInt();
3119          else
3120                 return 0;
3121   }
3122 }
3123
3124 Value::UInt Value::asUInt() const {
3125   switch (type_) {
3126   case intValue:
3127     JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
3128     return UInt(value_.int_);
3129   case uintValue:
3130     JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
3131     return UInt(value_.uint_);
3132   case realValue:
3133     JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
3134                         "double out of UInt range");
3135     return UInt(value_.real_);
3136   case nullValue:
3137     return 0;
3138   case booleanValue:
3139     return value_.bool_ ? 1 : 0;
3140   default:
3141          if ( default_value_ )
3142                 return default_value_->asUInt();
3143          else
3144                 return 0u;
3145   }
3146 }
3147
3148 #if defined(JSON_HAS_INT64)
3149
3150 Value::Int64 Value::asInt64() const {
3151   switch (type_) {
3152   case intValue:
3153     return Int64(value_.int_);
3154   case uintValue:
3155     JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
3156     return Int64(value_.uint_);
3157   case realValue:
3158     JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
3159                         "double out of Int64 range");
3160     return Int64(value_.real_);
3161   case nullValue:
3162     return 0;
3163   case booleanValue:
3164     return value_.bool_ ? 1 : 0;
3165   default:
3166          if ( default_value_ )
3167                 return default_value_->asInt64();
3168          else
3169                 return 0l;
3170   }
3171 }
3172
3173 Value::UInt64 Value::asUInt64() const {
3174   switch (type_) {
3175   case intValue:
3176     JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
3177     return UInt64(value_.int_);
3178   case uintValue:
3179     return UInt64(value_.uint_);
3180   case realValue:
3181     JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
3182                         "double out of UInt64 range");
3183     return UInt64(value_.real_);
3184   case nullValue:
3185     return 0;
3186   case booleanValue:
3187     return value_.bool_ ? 1 : 0;
3188   default:
3189          if ( default_value_ )
3190                 return default_value_->asUInt64();
3191          else
3192                 return 0ul;
3193   }
3194 }
3195 #endif // if defined(JSON_HAS_INT64)
3196
3197 LargestInt Value::asLargestInt() const {
3198 #if defined(JSON_NO_INT64)
3199   return asInt();
3200 #else
3201   return asInt64();
3202 #endif
3203 }
3204
3205 LargestUInt Value::asLargestUInt() const {
3206 #if defined(JSON_NO_INT64)
3207   return asUInt();
3208 #else
3209   return asUInt64();
3210 #endif
3211 }
3212
3213 double Value::asDouble() const {
3214   switch (type_) {
3215   case intValue:
3216     return static_cast<double>(value_.int_);
3217   case uintValue:
3218 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
3219     return static_cast<double>(value_.uint_);
3220 #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
3221     return integerToDouble(value_.uint_);
3222 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
3223   case realValue:
3224     return value_.real_;
3225   case nullValue:
3226     return 0.0;
3227   case booleanValue:
3228     return value_.bool_ ? 1.0 : 0.0;
3229   default:
3230          if ( default_value_ )
3231                 return default_value_->asDouble();
3232          else
3233                 return 0.0;
3234   }
3235 }
3236
3237 float Value::asFloat() const {
3238   switch (type_) {
3239   case intValue:
3240     return static_cast<float>(value_.int_);
3241   case uintValue:
3242 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
3243     return static_cast<float>(value_.uint_);
3244 #else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
3245     return integerToDouble(value_.uint_);
3246 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
3247   case realValue:
3248     return static_cast<float>(value_.real_);
3249   case nullValue:
3250     return 0.0;
3251   case booleanValue:
3252     return value_.bool_ ? 1.0f : 0.0f;
3253   default:
3254        if ( default_value_ )
3255               return default_value_->asFloat();
3256        else
3257               return 0.0f;
3258   }
3259 }
3260
3261 bool Value::asBool() const {
3262   switch (type_) {
3263   case booleanValue:
3264     return value_.bool_;
3265   case nullValue:
3266     return false;
3267   case intValue:
3268     return value_.int_ ? true : false;
3269   case uintValue:
3270     return value_.uint_ ? true : false;
3271   case realValue:
3272     // This is kind of strange. Not recommended.
3273     return (value_.real_ != 0.0) ? true : false;
3274   default:
3275        if ( default_value_ )
3276               return default_value_->asBool();
3277        else
3278               return false;
3279   }
3280 }
3281
3282 bool Value::isConvertibleTo(ValueType other) const {
3283   switch (other) {
3284   case nullValue:
3285     return (isNumeric() && asDouble() == 0.0) ||
3286            (type_ == booleanValue && value_.bool_ == false) ||
3287            (type_ == stringValue && asString() == "") ||
3288            (type_ == arrayValue && value_.map_->size() == 0) ||
3289            (type_ == objectValue && value_.map_->size() == 0) ||
3290            type_ == nullValue;
3291   case intValue:
3292     return isInt() ||
3293            (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
3294            type_ == booleanValue || type_ == nullValue;
3295   case uintValue:
3296     return isUInt() ||
3297            (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
3298            type_ == booleanValue || type_ == nullValue;
3299   case realValue:
3300     return isNumeric() || type_ == booleanValue || type_ == nullValue;
3301   case booleanValue:
3302     return isNumeric() || type_ == booleanValue || type_ == nullValue;
3303   case stringValue:
3304     return isNumeric() || type_ == booleanValue || type_ == stringValue ||
3305            type_ == nullValue;
3306   case arrayValue:
3307     return type_ == arrayValue || type_ == nullValue;
3308   case objectValue:
3309     return type_ == objectValue || type_ == nullValue;
3310   }
3311   JSON_ASSERT_UNREACHABLE;
3312   return false;
3313 }
3314
3315 /// Number of values in array or object
3316 ArrayIndex Value::size() const {
3317   switch (type_) {
3318   case nullValue:
3319   case intValue:
3320   case uintValue:
3321   case realValue:
3322   case booleanValue:
3323   case stringValue:
3324     return 0;
3325   case arrayValue: // size of the array is highest index + 1
3326     if (!value_.map_->empty()) {
3327       ObjectValues::const_iterator itLast = value_.map_->end();
3328       --itLast;
3329       return (*itLast).first.index() + 1;
3330     }
3331     return 0;
3332   case objectValue:
3333     return ArrayIndex(value_.map_->size());
3334   }
3335   JSON_ASSERT_UNREACHABLE;
3336   return 0; // unreachable;
3337 }
3338
3339 bool Value::empty() const {
3340   if (isNull() || isArray() || isObject())
3341     return size() == 0u;
3342   else
3343     return false;
3344 }
3345
3346 bool Value::operator!() const { return isNull(); }
3347
3348 void Value::clear() {
3349   JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
3350                           type_ == objectValue,
3351                       "in Json::Value::clear(): requires complex value");
3352   start_ = 0;
3353   limit_ = 0;
3354   delete default_value_;
3355   default_value_ = nullptr;
3356   switch (type_) {
3357   case arrayValue:
3358   case objectValue:
3359     value_.map_->clear();
3360     break;
3361   default:
3362     break;
3363   }
3364 }
3365
3366 void Value::resize(ArrayIndex newSize) {
3367   JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
3368                       "in Json::Value::resize(): requires arrayValue");
3369   if (type_ == nullValue)
3370     *this = Value(arrayValue);
3371   ArrayIndex oldSize = size();
3372   if (newSize == 0)
3373     clear();
3374   else if (newSize > oldSize)
3375     (*this)[newSize - 1];
3376   else {
3377     for (ArrayIndex index = newSize; index < oldSize; ++index) {
3378       value_.map_->erase(index);
3379     }
3380     assert(size() == newSize);
3381   }
3382 }
3383
3384 Value& Value::operator[](ArrayIndex index) {
3385   JSON_ASSERT_MESSAGE(
3386       type_ == nullValue || type_ == arrayValue,
3387       "in Json::Value::operator[](ArrayIndex): requires arrayValue");
3388   if (type_ == nullValue)
3389     *this = Value(arrayValue);
3390   CZString key(index);
3391   ObjectValues::iterator it = value_.map_->lower_bound(key);
3392   if (it != value_.map_->end() && (*it).first == key)
3393     return (*it).second;
3394
3395   ObjectValues::value_type defaultValue(key, nullRef);
3396   it = value_.map_->insert(it, defaultValue);
3397   return (*it).second;
3398 }
3399
3400 Value& Value::operator[](int index) {
3401   JSON_ASSERT_MESSAGE(
3402       index >= 0,
3403       "in Json::Value::operator[](int index): index cannot be negative");
3404   return (*this)[ArrayIndex(index)];
3405 }
3406
3407 const Value& Value::operator[](ArrayIndex index) const {
3408   JSON_ASSERT_MESSAGE(
3409       type_ == nullValue || type_ == arrayValue,
3410       "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
3411   if (type_ == nullValue)
3412     return nullRef;
3413   CZString key(index);
3414   ObjectValues::const_iterator it = value_.map_->find(key);
3415   if (it == value_.map_->end())
3416     return nullRef;
3417   return (*it).second;
3418 }
3419
3420 const Value& Value::operator[](int index) const {
3421   JSON_ASSERT_MESSAGE(
3422       index >= 0,
3423       "in Json::Value::operator[](int index) const: index cannot be negative");
3424   return (*this)[ArrayIndex(index)];
3425 }
3426
3427 void Value::initBasic(ValueType vtype, bool allocated) {
3428   type_ = vtype;
3429   allocated_ = allocated;
3430   comments_ = 0;
3431   start_ = 0;
3432   limit_ = 0;
3433   default_value_ = nullptr;
3434 }
3435
3436 // Access an object value by name, create a null member if it does not exist.
3437 // @pre Type of '*this' is object or null.
3438 // @param key is null-terminated.
3439 Value& Value::resolveReference(const char* key) {
3440   JSON_ASSERT_MESSAGE(
3441       type_ == nullValue || type_ == objectValue,
3442       "in Json::Value::resolveReference(): requires objectValue");
3443   if (type_ == nullValue)
3444     *this = Value(objectValue);
3445   CZString actualKey(
3446       key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!
3447   ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
3448   if (it != value_.map_->end() && (*it).first == actualKey)
3449     return (*it).second;
3450
3451   ObjectValues::value_type defaultValue(actualKey, nullRef);
3452   it = value_.map_->insert(it, defaultValue);
3453   Value& value = (*it).second;
3454   return value;
3455 }
3456
3457 // @param key is not null-terminated.
3458 Value& Value::resolveReference(char const* key, char const* cend)
3459 {
3460   JSON_ASSERT_MESSAGE(
3461       type_ == nullValue || type_ == objectValue,
3462       "in Json::Value::resolveReference(key, end): requires objectValue");
3463   if (type_ == nullValue)
3464     *this = Value(objectValue);
3465   CZString actualKey(
3466       key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
3467   ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
3468   if (it != value_.map_->end() && (*it).first == actualKey)
3469     return (*it).second;
3470
3471   ObjectValues::value_type defaultValue(actualKey, nullRef);
3472   it = value_.map_->insert(it, defaultValue);
3473   Value& value = (*it).second;
3474   return value;
3475 }
3476
3477 Value Value::get(ArrayIndex index, const Value& defaultValue) const {
3478   const Value* value = &((*this)[index]);
3479   if ( value == &nullRef )
3480   {
3481          return defaultValue;
3482   }
3483   else
3484   {
3485          Value result = *value;
3486          result.default_value_ = new Value( defaultValue );
3487          return result;
3488   }
3489 }
3490
3491 bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
3492
3493 Value const* Value::find(char const* key, char const* cend) const
3494 {
3495   JSON_ASSERT_MESSAGE(
3496       type_ == nullValue || type_ == objectValue,
3497       "in Json::Value::find(key, end, found): requires objectValue or nullValue");
3498   if (type_ == nullValue) return NULL;
3499   CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
3500   ObjectValues::const_iterator it = value_.map_->find(actualKey);
3501   if (it == value_.map_->end()) return NULL;
3502   return &(*it).second;
3503 }
3504 const Value& Value::operator[](const char* key) const
3505 {
3506   Value const* found = find(key, key + strlen(key));
3507   if (!found) return nullRef;
3508   return *found;
3509 }
3510 Value const& Value::operator[](std::string const& key) const
3511 {
3512   Value const* found = find(key.data(), key.data() + key.length());
3513   if (!found) return nullRef;
3514   return *found;
3515 }
3516
3517 Value& Value::operator[](const char* key) {
3518   return resolveReference(key, key + strlen(key));
3519 }
3520
3521 Value& Value::operator[](const std::string& key) {
3522   return resolveReference(key.data(), key.data() + key.length());
3523 }
3524
3525 Value& Value::operator[](const StaticString& key) {
3526   return resolveReference(key.c_str());
3527 }
3528
3529 #ifdef JSON_USE_CPPTL
3530 Value& Value::operator[](const CppTL::ConstString& key) {
3531   return resolveReference(key.c_str(), key.end_c_str());
3532 }
3533 Value const& Value::operator[](CppTL::ConstString const& key) const
3534 {
3535   Value const* found = find(key.c_str(), key.end_c_str());
3536   if (!found) return nullRef;
3537   return *found;
3538 }
3539 #endif
3540
3541 Value& Value::append(const Value& value) { return (*this)[size()] = value; }
3542
3543 Value Value::get(char const* key, char const* cend, Value const& defaultValue) const
3544 {
3545   Value const* found = find(key, cend);
3546   if ( !found )
3547   {
3548          return defaultValue;
3549   }
3550   else
3551   {
3552          Value result = *found;
3553          result.default_value_ = new Value( defaultValue );
3554          return result;
3555   }
3556 }
3557 Value Value::get(char const* key, Value const& defaultValue) const
3558 {
3559   return get(key, key + strlen(key), defaultValue);
3560 }
3561 Value Value::get(std::string const& key, Value const& defaultValue) const
3562 {
3563   return get(key.data(), key.data() + key.length(), defaultValue);
3564 }
3565
3566
3567 bool Value::removeMember(const char* key, const char* cend, Value* removed)
3568 {
3569   if (type_ != objectValue) {
3570     return false;
3571   }
3572   CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
3573   ObjectValues::iterator it = value_.map_->find(actualKey);
3574   if (it == value_.map_->end())
3575     return false;
3576   *removed = it->second;
3577   value_.map_->erase(it);
3578   return true;
3579 }
3580 bool Value::removeMember(const char* key, Value* removed)
3581 {
3582   return removeMember(key, key + strlen(key), removed);
3583 }
3584 bool Value::removeMember(std::string const& key, Value* removed)
3585 {
3586   return removeMember(key.data(), key.data() + key.length(), removed);
3587 }
3588 Value Value::removeMember(const char* key)
3589 {
3590   JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
3591                       "in Json::Value::removeMember(): requires objectValue");
3592   if (type_ == nullValue)
3593     return nullRef;
3594
3595   Value removed;  // null
3596   removeMember(key, key + strlen(key), &removed);
3597   return removed; // still null if removeMember() did nothing
3598 }
3599 Value Value::removeMember(const std::string& key)
3600 {
3601   return removeMember(key.c_str());
3602 }
3603
3604 bool Value::removeIndex(ArrayIndex index, Value* removed) {
3605   if (type_ != arrayValue) {
3606     return false;
3607   }
3608   CZString key(index);
3609   ObjectValues::iterator it = value_.map_->find(key);
3610   if (it == value_.map_->end()) {
3611     return false;
3612   }
3613   *removed = it->second;
3614   ArrayIndex oldSize = size();
3615   // shift left all items left, into the place of the "removed"
3616   for (ArrayIndex i = index; i < (oldSize - 1); ++i){
3617     CZString keey(i);
3618     (*value_.map_)[keey] = (*this)[i + 1];
3619   }
3620   // erase the last one ("leftover")
3621   CZString keyLast(oldSize - 1);
3622   ObjectValues::iterator itLast = value_.map_->find(keyLast);
3623   value_.map_->erase(itLast);
3624   return true;
3625 }
3626
3627 #ifdef JSON_USE_CPPTL
3628 Value Value::get(const CppTL::ConstString& key,
3629                  const Value& defaultValue) const {
3630   return get(key.c_str(), key.end_c_str(), defaultValue);
3631 }
3632 #endif
3633
3634 bool Value::isMember(char const* key, char const* cend) const