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