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


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:26