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