Medical Imaging Interaction Toolkit  2018.4.99-87d68d9f
Medical Imaging Interaction Toolkit
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 <jsoncpp.h>
77 
78 
79 // //////////////////////////////////////////////////////////////////////
80 // Beginning of content of file: src/lib_json/json_tool.h
81 // //////////////////////////////////////////////////////////////////////
82 
83 // Copyright 2007-2010 Baptiste Lepilleur
84 // Distributed under MIT license, or public domain if desired and
85 // recognized in your jurisdiction.
86 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
87 
88 #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
89 # define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
90 
91 /* This header provides common string manipulation support, such as UTF-8,
92  * portable conversion from/to string...
93  *
94  * It is an internal header that must not be exposed.
95  */
96 
97 namespace Json {
98 
100 static inline std::string
101 codePointToUTF8(unsigned int cp)
102 {
103  std::string result;
104 
105  // based on description from http://en.wikipedia.org/wiki/UTF-8
106 
107  if (cp <= 0x7f)
108  {
109  result.resize(1);
110  result[0] = static_cast<char>(cp);
111  }
112  else if (cp <= 0x7FF)
113  {
114  result.resize(2);
115  result[1] = static_cast<char>(0x80 | (0x3f & cp));
116  result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
117  }
118  else if (cp <= 0xFFFF)
119  {
120  result.resize(3);
121  result[2] = static_cast<char>(0x80 | (0x3f & cp));
122  result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6)));
123  result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12)));
124  }
125  else if (cp <= 0x10FFFF)
126  {
127  result.resize(4);
128  result[3] = static_cast<char>(0x80 | (0x3f & cp));
129  result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
130  result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
131  result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
132  }
133 
134  return result;
135 }
136 
137 
139 static inline bool
141 {
142  return ch > 0 && ch <= 0x1F;
143 }
144 
145 
146 enum {
149 };
150 
151 // Defines a char buffer for use with uintToString().
153 
154 
160 static inline void
162  char *&current )
163 {
164  *--current = 0;
165  do
166  {
167  *--current = char(value % 10) + '0';
168  value /= 10;
169  }
170  while ( value != 0 );
171 }
172 
173 } // namespace Json {
174 
175 #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
176 
177 // //////////////////////////////////////////////////////////////////////
178 // End of content of file: src/lib_json/json_tool.h
179 // //////////////////////////////////////////////////////////////////////
180 
181 
182 
183 
184 
185 
186 // //////////////////////////////////////////////////////////////////////
187 // Beginning of content of file: src/lib_json/json_reader.cpp
188 // //////////////////////////////////////////////////////////////////////
189 
190 // Copyright 2007-2010 Baptiste Lepilleur
191 // Distributed under MIT license, or public domain if desired and
192 // recognized in your jurisdiction.
193 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
194 
195 #if !defined(JSON_IS_AMALGAMATION)
196 # include <json/reader.h>
197 # include <json/value.h>
198 # include "json_tool.h"
199 #endif // if !defined(JSON_IS_AMALGAMATION)
200 #include <utility>
201 #include <cstdio>
202 #include <cassert>
203 #include <cstring>
204 #include <iostream>
205 #include <stdexcept>
206 
207 #if _MSC_VER >= 1400 // VC++ 8.0
208 #pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
209 #endif
210 
211 namespace Json {
212 
213 // Implementation of class Features
214 // ////////////////////////////////
215 
217  : allowComments_( true )
218  , strictRoot_( false )
219 {
220 }
221 
222 
223 Features
225 {
226  return Features();
227 }
228 
229 
230 Features
232 {
233  Features features;
234  features.allowComments_ = false;
235  features.strictRoot_ = true;
236  return features;
237 }
238 
239 // Implementation of class Reader
240 // ////////////////////////////////
241 
242 
243 static inline bool
245 {
246  return c == c1 || c == c2 || c == c3 || c == c4;
247 }
248 
249 static inline bool
251 {
252  return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
253 }
254 
255 
256 static bool
258  Reader::Location end )
259 {
260  for ( ;begin < end; ++begin )
261  if ( *begin == '\n' || *begin == '\r' )
262  return true;
263  return false;
264 }
265 
266 
267 // Class Reader
268 // //////////////////////////////////////////////////////////////////
269 
271  : features_( Features::all() )
272 {
273 }
274 
275 
276 Reader::Reader( const Features &features )
277  : features_( features )
278 {
279 }
280 
281 
282 bool
283 Reader::parse( const std::string &document,
284  Value &root,
285  bool collectComments )
286 {
287  document_ = document;
288  const char *begin = document_.c_str();
289  const char *end = begin + document_.length();
290  return parse( begin, end, root, collectComments );
291 }
292 
293 
294 bool
295 Reader::parse( std::istream& sin,
296  Value &root,
297  bool collectComments )
298 {
299  //std::istream_iterator<char> begin(sin);
300  //std::istream_iterator<char> end;
301  // Those would allow streamed input from a file, if parse() were a
302  // template function.
303 
304  // Since std::string is reference-counted, this at least does not
305  // create an extra copy.
306  std::string doc;
307  std::getline(sin, doc, static_cast<char>(EOF));
308  return parse( doc, root, collectComments );
309 }
310 
311 bool
312 Reader::parse( const char *beginDoc, const char *endDoc,
313  Value &root,
314  bool collectComments )
315 {
316  if ( !features_.allowComments_ )
317  {
318  collectComments = false;
319  }
320 
321  begin_ = beginDoc;
322  end_ = endDoc;
323  collectComments_ = collectComments;
324  current_ = begin_;
325  lastValueEnd_ = nullptr;
326  lastValue_ = nullptr;
327  commentsBefore_ = "";
328  errors_.clear();
329  while ( !nodes_.empty() )
330  nodes_.pop();
331  nodes_.push( &root );
332 
333  bool successful = readValue();
334  Token token;
335  skipCommentTokens( token );
336  if ( collectComments_ && !commentsBefore_.empty() )
337  root.setComment( commentsBefore_, commentAfter );
338  if ( features_.strictRoot_ )
339  {
340  if ( !root.isArray() && !root.isObject() )
341  {
342  // Set error location to start of doc, ideally should be first token found in doc
343  token.type_ = tokenError;
344  token.start_ = beginDoc;
345  token.end_ = endDoc;
346  addError( "A valid JSON document must be either an array or an object value.",
347  token );
348  return false;
349  }
350  }
351  return successful;
352 }
353 
354 
355 bool
356 Reader::readValue()
357 {
358  Token token;
359  skipCommentTokens( token );
360  bool successful = true;
361 
362  if ( collectComments_ && !commentsBefore_.empty() )
363  {
364  currentValue().setComment( commentsBefore_, commentBefore );
365  commentsBefore_ = "";
366  }
367 
368 
369  switch ( token.type_ )
370  {
371  case tokenObjectBegin:
372  successful = readObject( token );
373  break;
374  case tokenArrayBegin:
375  successful = readArray( token );
376  break;
377  case tokenNumber:
378  successful = decodeNumber( token );
379  break;
380  case tokenString:
381  successful = decodeString( token );
382  break;
383  case tokenTrue:
384  currentValue() = true;
385  break;
386  case tokenFalse:
387  currentValue() = false;
388  break;
389  case tokenNull:
390  currentValue() = Value();
391  break;
392  default:
393  return addError( "Syntax error: value, object or array expected.", token );
394  }
395 
396  if ( collectComments_ )
397  {
398  lastValueEnd_ = current_;
399  lastValue_ = &currentValue();
400  }
401 
402  return successful;
403 }
404 
405 
406 void
407 Reader::skipCommentTokens( Token &token )
408 {
409  if ( features_.allowComments_ )
410  {
411  do
412  {
413  readToken( token );
414  }
415  while ( token.type_ == tokenComment );
416  }
417  else
418  {
419  readToken( token );
420  }
421 }
422 
423 
424 bool
425 Reader::expectToken( TokenType type, Token &token, const char *message )
426 {
427  readToken( token );
428  if ( token.type_ != type )
429  return addError( message, token );
430  return true;
431 }
432 
433 
434 bool
435 Reader::readToken( Token &token )
436 {
437  skipSpaces();
438  token.start_ = current_;
439  Char c = getNextChar();
440  bool ok = true;
441  switch ( c )
442  {
443  case '{':
444  token.type_ = tokenObjectBegin;
445  break;
446  case '}':
447  token.type_ = tokenObjectEnd;
448  break;
449  case '[':
450  token.type_ = tokenArrayBegin;
451  break;
452  case ']':
453  token.type_ = tokenArrayEnd;
454  break;
455  case '"':
456  token.type_ = tokenString;
457  ok = readString();
458  break;
459  case '/':
460  token.type_ = tokenComment;
461  ok = readComment();
462  break;
463  case '0':
464  case '1':
465  case '2':
466  case '3':
467  case '4':
468  case '5':
469  case '6':
470  case '7':
471  case '8':
472  case '9':
473  case '-':
474  token.type_ = tokenNumber;
475  readNumber();
476  break;
477  case 't':
478  token.type_ = tokenTrue;
479  ok = match( "rue", 3 );
480  break;
481  case 'f':
482  token.type_ = tokenFalse;
483  ok = match( "alse", 4 );
484  break;
485  case 'n':
486  token.type_ = tokenNull;
487  ok = match( "ull", 3 );
488  break;
489  case ',':
490  token.type_ = tokenArraySeparator;
491  break;
492  case ':':
493  token.type_ = tokenMemberSeparator;
494  break;
495  case 0:
496  token.type_ = tokenEndOfStream;
497  break;
498  default:
499  ok = false;
500  break;
501  }
502  if ( !ok )
503  token.type_ = tokenError;
504  token.end_ = current_;
505  return true;
506 }
507 
508 
509 void
510 Reader::skipSpaces()
511 {
512  while ( current_ != end_ )
513  {
514  Char c = *current_;
515  if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' )
516  ++current_;
517  else
518  break;
519  }
520 }
521 
522 
523 bool
524 Reader::match( Location pattern,
525  int patternLength )
526 {
527  if ( end_ - current_ < patternLength )
528  return false;
529  int index = patternLength;
530  while ( index-- )
531  if ( current_[index] != pattern[index] )
532  return false;
533  current_ += patternLength;
534  return true;
535 }
536 
537 
538 bool
539 Reader::readComment()
540 {
541  Location commentBegin = current_ - 1;
542  Char c = getNextChar();
543  bool successful = false;
544  if ( c == '*' )
545  successful = readCStyleComment();
546  else if ( c == '/' )
547  successful = readCppStyleComment();
548  if ( !successful )
549  return false;
550 
551  if ( collectComments_ )
552  {
553  CommentPlacement placement = commentBefore;
554  if ( lastValueEnd_ && !containsNewLine( lastValueEnd_, commentBegin ) )
555  {
556  if ( c != '*' || !containsNewLine( commentBegin, current_ ) )
557  placement = commentAfterOnSameLine;
558  }
559 
560  addComment( commentBegin, current_, placement );
561  }
562  return true;
563 }
564 
565 
566 void
567 Reader::addComment( Location begin,
568  Location end,
569  CommentPlacement placement )
570 {
571  assert( collectComments_ );
572  if ( placement == commentAfterOnSameLine )
573  {
574  assert( lastValue_ != nullptr );
575  lastValue_->setComment( std::string( begin, end ), placement );
576  }
577  else
578  {
579  if ( !commentsBefore_.empty() )
580  commentsBefore_ += "\n";
581  commentsBefore_ += std::string( begin, end );
582  }
583 }
584 
585 
586 bool
587 Reader::readCStyleComment()
588 {
589  while ( current_ != end_ )
590  {
591  Char c = getNextChar();
592  if ( c == '*' && *current_ == '/' )
593  break;
594  }
595  return getNextChar() == '/';
596 }
597 
598 
599 bool
600 Reader::readCppStyleComment()
601 {
602  while ( current_ != end_ )
603  {
604  Char c = getNextChar();
605  if ( c == '\r' || c == '\n' )
606  break;
607  }
608  return true;
609 }
610 
611 
612 void
613 Reader::readNumber()
614 {
615  while ( current_ != end_ )
616  {
617  if ( !(*current_ >= '0' && *current_ <= '9') &&
618  !in( *current_, '.', 'e', 'E', '+', '-' ) )
619  break;
620  ++current_;
621  }
622 }
623 
624 bool
625 Reader::readString()
626 {
627  Char c = 0;
628  while ( current_ != end_ )
629  {
630  c = getNextChar();
631  if ( c == '\\' )
632  getNextChar();
633  else if ( c == '"' )
634  break;
635  }
636  return c == '"';
637 }
638 
639 
640 bool
641 Reader::readObject( Token &/*tokenStart*/ )
642 {
643  Token tokenName;
644  std::string name;
645  currentValue() = Value( objectValue );
646  while ( readToken( tokenName ) )
647  {
648  bool initialTokenOk = true;
649  while ( tokenName.type_ == tokenComment && initialTokenOk )
650  initialTokenOk = readToken( tokenName );
651  if ( !initialTokenOk )
652  break;
653  if ( tokenName.type_ == tokenObjectEnd && name.empty() ) // empty object
654  return true;
655  if ( tokenName.type_ != tokenString )
656  break;
657 
658  name = "";
659  if ( !decodeString( tokenName, name ) )
660  return recoverFromError( tokenObjectEnd );
661 
662  Token colon;
663  if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator )
664  {
665  return addErrorAndRecover( "Missing ':' after object member name",
666  colon,
667  tokenObjectEnd );
668  }
669  Value &value = currentValue()[ name ];
670  nodes_.push( &value );
671  bool ok = readValue();
672  nodes_.pop();
673  if ( !ok ) // error already set
674  return recoverFromError( tokenObjectEnd );
675 
676  Token comma;
677  if ( !readToken( comma )
678  || ( comma.type_ != tokenObjectEnd &&
679  comma.type_ != tokenArraySeparator &&
680  comma.type_ != tokenComment ) )
681  {
682  return addErrorAndRecover( "Missing ',' or '}' in object declaration",
683  comma,
684  tokenObjectEnd );
685  }
686  bool finalizeTokenOk = true;
687  while ( comma.type_ == tokenComment &&
688  finalizeTokenOk )
689  finalizeTokenOk = readToken( comma );
690  if ( comma.type_ == tokenObjectEnd )
691  return true;
692  }
693  return addErrorAndRecover( "Missing '}' or object member name",
694  tokenName,
695  tokenObjectEnd );
696 }
697 
698 
699 bool
700 Reader::readArray( Token &/*tokenStart*/ )
701 {
702  currentValue() = Value( arrayValue );
703  skipSpaces();
704  if ( *current_ == ']' ) // empty array
705  {
706  Token endArray;
707  readToken( endArray );
708  return true;
709  }
710  int index = 0;
711  for (;;)
712  {
713  Value &value = currentValue()[ index++ ];
714  nodes_.push( &value );
715  bool ok = readValue();
716  nodes_.pop();
717  if ( !ok ) // error already set
718  return recoverFromError( tokenArrayEnd );
719 
720  Token token;
721  // Accept Comment after last item in the array.
722  ok = readToken( token );
723  while ( token.type_ == tokenComment && ok )
724  {
725  ok = readToken( token );
726  }
727  bool badTokenType = ( token.type_ != tokenArraySeparator &&
728  token.type_ != tokenArrayEnd );
729  if ( !ok || badTokenType )
730  {
731  return addErrorAndRecover( "Missing ',' or ']' in array declaration",
732  token,
733  tokenArrayEnd );
734  }
735  if ( token.type_ == tokenArrayEnd )
736  break;
737  }
738  return true;
739 }
740 
741 
742 bool
743 Reader::decodeNumber( Token &token )
744 {
745  bool isDouble = false;
746  for ( Location inspect = token.start_; inspect != token.end_; ++inspect )
747  {
748  isDouble = isDouble
749  || in( *inspect, '.', 'e', 'E', '+' )
750  || ( *inspect == '-' && inspect != token.start_ );
751  }
752  if ( isDouble )
753  return decodeDouble( token );
754  // Attempts to parse the number as an integer. If the number is
755  // larger than the maximum supported value of an integer then
756  // we decode the number as a double.
757  Location current = token.start_;
758  bool isNegative = *current == '-';
759  if ( isNegative )
760  ++current;
761  Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(-Value::minLargestInt)
763  Value::LargestUInt threshold = maxIntegerValue / 10;
764  Value::UInt lastDigitThreshold = Value::UInt( maxIntegerValue % 10 );
765  assert(/* lastDigitThreshold >=0 &&*/ lastDigitThreshold <= 9 );
766  Value::LargestUInt value = 0;
767  while ( current < token.end_ )
768  {
769  Char c = *current++;
770  if ( c < '0' || c > '9' )
771  return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
772  Value::UInt digit(c - '0');
773  if ( value >= threshold )
774  {
775  // If the current digit is not the last one, or if it is
776  // greater than the last digit of the maximum integer value,
777  // the parse the number as a double.
778  if ( current != token.end_ || digit > lastDigitThreshold )
779  {
780  return decodeDouble( token );
781  }
782  }
783  value = value * 10 + digit;
784  }
785  if ( isNegative )
786  currentValue() = -Value::LargestInt( value );
787  else if ( value <= Value::LargestUInt(Value::maxInt) )
788  currentValue() = Value::LargestInt( value );
789  else
790  currentValue() = value;
791  return true;
792 }
793 
794 
795 bool
796 Reader::decodeDouble( Token &token )
797 {
798  double value = 0;
799  const int bufferSize = 32;
800  int count;
801  int length = int(token.end_ - token.start_);
802  if ( length <= bufferSize )
803  {
804  Char buffer[bufferSize+1];
805  memcpy( buffer, token.start_, length );
806  buffer[length] = 0;
807  count = sscanf( buffer, "%lf", &value );
808  }
809  else
810  {
811  std::string buffer( token.start_, token.end_ );
812  count = sscanf( buffer.c_str(), "%lf", &value );
813  }
814 
815  if ( count != 1 )
816  return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
817  currentValue() = value;
818  return true;
819 }
820 
821 
822 bool
823 Reader::decodeString( Token &token )
824 {
825  std::string decoded;
826  if ( !decodeString( token, decoded ) )
827  return false;
828  currentValue() = decoded;
829  return true;
830 }
831 
832 
833 bool
834 Reader::decodeString( Token &token, std::string &decoded )
835 {
836  decoded.reserve( token.end_ - token.start_ - 2 );
837  Location current = token.start_ + 1; // skip '"'
838  Location end = token.end_ - 1; // do not include '"'
839  while ( current != end )
840  {
841  Char c = *current++;
842  if ( c == '"' )
843  break;
844  else if ( c == '\\' )
845  {
846  if ( current == end )
847  return addError( "Empty escape sequence in string", token, current );
848  Char escape = *current++;
849  switch ( escape )
850  {
851  case '"': decoded += '"'; break;
852  case '/': decoded += '/'; break;
853  case '\\': decoded += '\\'; break;
854  case 'b': decoded += '\b'; break;
855  case 'f': decoded += '\f'; break;
856  case 'n': decoded += '\n'; break;
857  case 'r': decoded += '\r'; break;
858  case 't': decoded += '\t'; break;
859  case 'u':
860  {
861  unsigned int unicode;
862  if ( !decodeUnicodeCodePoint( token, current, end, unicode ) )
863  return false;
864  decoded += codePointToUTF8(unicode);
865  }
866  break;
867  default:
868  return addError( "Bad escape sequence in string", token, current );
869  }
870  }
871  else
872  {
873  decoded += c;
874  }
875  }
876  return true;
877 }
878 
879 bool
880 Reader::decodeUnicodeCodePoint( Token &token,
881  Location &current,
882  Location end,
883  unsigned int &unicode )
884 {
885 
886  if ( !decodeUnicodeEscapeSequence( token, current, end, unicode ) )
887  return false;
888  if (unicode >= 0xD800 && unicode <= 0xDBFF)
889  {
890  // surrogate pairs
891  if (end - current < 6)
892  return addError( "additional six characters expected to parse unicode surrogate pair.", token, current );
893  unsigned int surrogatePair;
894  if (*(current++) == '\\' && *(current++)== 'u')
895  {
896  if (decodeUnicodeEscapeSequence( token, current, end, surrogatePair ))
897  {
898  unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
899  }
900  else
901  return false;
902  }
903  else
904  return addError( "expecting another \\u token to begin the second half of a unicode surrogate pair", token, current );
905  }
906  return true;
907 }
908 
909 bool
910 Reader::decodeUnicodeEscapeSequence( Token &token,
911  Location &current,
912  Location end,
913  unsigned int &unicode )
914 {
915  if ( end - current < 4 )
916  return addError( "Bad unicode escape sequence in string: four digits expected.", token, current );
917  unicode = 0;
918  for ( int index =0; index < 4; ++index )
919  {
920  Char c = *current++;
921  unicode *= 16;
922  if ( c >= '0' && c <= '9' )
923  unicode += c - '0';
924  else if ( c >= 'a' && c <= 'f' )
925  unicode += c - 'a' + 10;
926  else if ( c >= 'A' && c <= 'F' )
927  unicode += c - 'A' + 10;
928  else
929  return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", token, current );
930  }
931  return true;
932 }
933 
934 
935 bool
936 Reader::addError( const std::string &message,
937  Token &token,
938  Location extra )
939 {
940  ErrorInfo info;
941  info.token_ = token;
942  info.message_ = message;
943  info.extra_ = extra;
944  errors_.push_back( info );
945  return false;
946 }
947 
948 
949 bool
950 Reader::recoverFromError( TokenType skipUntilToken )
951 {
952  int errorCount = int(errors_.size());
953  Token skip;
954  for (;;)
955  {
956  if ( !readToken(skip) )
957  errors_.resize( errorCount ); // discard errors caused by recovery
958  if ( skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream )
959  break;
960  }
961  errors_.resize( errorCount );
962  return false;
963 }
964 
965 
966 bool
967 Reader::addErrorAndRecover( const std::string &message,
968  Token &token,
969  TokenType skipUntilToken )
970 {
971  addError( message, token );
972  return recoverFromError( skipUntilToken );
973 }
974 
975 
976 Value &
977 Reader::currentValue()
978 {
979  return *(nodes_.top());
980 }
981 
982 
984 Reader::getNextChar()
985 {
986  if ( current_ == end_ )
987  return 0;
988  return *current_++;
989 }
990 
991 
992 void
993 Reader::getLocationLineAndColumn( Location location,
994  int &line,
995  int &column ) const
996 {
997  Location current = begin_;
998  Location lastLineStart = current;
999  line = 0;
1000  while ( current < location && current != end_ )
1001  {
1002  Char c = *current++;
1003  if ( c == '\r' )
1004  {
1005  if ( *current == '\n' )
1006  ++current;
1007  lastLineStart = current;
1008  ++line;
1009  }
1010  else if ( c == '\n' )
1011  {
1012  lastLineStart = current;
1013  ++line;
1014  }
1015  }
1016  // column & line start at 1
1017  column = int(location - lastLineStart) + 1;
1018  ++line;
1019 }
1020 
1021 
1022 std::string
1023 Reader::getLocationLineAndColumn( Location location ) const
1024 {
1025  int line, column;
1026  getLocationLineAndColumn( location, line, column );
1027  char buffer[18+16+16+1];
1028  sprintf( buffer, "Line %d, Column %d", line, column );
1029  return buffer;
1030 }
1031 
1032 
1033 // Deprecated. Preserved for backward compatibility
1034 std::string
1036 {
1037  return getFormattedErrorMessages();
1038 }
1039 
1040 
1041 std::string
1043 {
1044  std::string formattedMessage;
1045  for ( Errors::const_iterator itError = errors_.begin();
1046  itError != errors_.end();
1047  ++itError )
1048  {
1049  const ErrorInfo &error = *itError;
1050  formattedMessage += "* " + getLocationLineAndColumn( error.token_.start_ ) + "\n";
1051  formattedMessage += " " + error.message_ + "\n";
1052  if ( error.extra_ )
1053  formattedMessage += "See " + getLocationLineAndColumn( error.extra_ ) + " for detail.\n";
1054  }
1055  return formattedMessage;
1056 }
1057 
1058 
1059 std::istream& operator>>( std::istream &sin, Value &root )
1060 {
1061  Json::Reader reader;
1062  bool ok = reader.parse(sin, root, true);
1063  //JSON_ASSERT( ok );
1064  if (!ok) throw std::runtime_error(reader.getFormattedErrorMessages());
1065  return sin;
1066 }
1067 
1068 
1069 } // namespace Json
1070 
1071 // //////////////////////////////////////////////////////////////////////
1072 // End of content of file: src/lib_json/json_reader.cpp
1073 // //////////////////////////////////////////////////////////////////////
1074 
1075 
1076 
1077 
1078 
1079 
1080 // //////////////////////////////////////////////////////////////////////
1081 // Beginning of content of file: src/lib_json/json_batchallocator.h
1082 // //////////////////////////////////////////////////////////////////////
1083 
1084 // Copyright 2007-2010 Baptiste Lepilleur
1085 // Distributed under MIT license, or public domain if desired and
1086 // recognized in your jurisdiction.
1087 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
1088 
1089 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
1090 # define JSONCPP_BATCHALLOCATOR_H_INCLUDED
1091 
1092 # include <stdlib.h>
1093 # include <assert.h>
1094 
1095 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
1096 
1097 namespace Json {
1098 
1099 /* Fast memory allocator.
1100  *
1101  * This memory allocator allocates memory for a batch of object (specified by
1102  * the page size, the number of object in each page).
1103  *
1104  * It does not allow the destruction of a single object. All the allocated objects
1105  * can be destroyed at once. The memory can be either released or reused for future
1106  * allocation.
1107  *
1108  * The in-place new operator must be used to construct the object using the pointer
1109  * returned by allocate.
1110  */
1111 template<typename AllocatedType
1112  ,const unsigned int objectPerAllocation>
1113 class BatchAllocator
1114 {
1115 public:
1116  typedef AllocatedType Type;
1117 
1118  BatchAllocator( unsigned int objectsPerPage = 255 )
1119  : freeHead_( 0 )
1120  , objectsPerPage_( objectsPerPage )
1121  {
1122 // printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
1123  assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
1124  assert( objectsPerPage >= 16 );
1125  batches_ = allocateBatch( 0 ); // allocated a dummy page
1126  currentBatch_ = batches_;
1127  }
1128 
1129  ~BatchAllocator()
1130  {
1131  for ( BatchInfo *batch = batches_; batch; )
1132  {
1133  BatchInfo *nextBatch = batch->next_;
1134  free( batch );
1135  batch = nextBatch;
1136  }
1137  }
1138 
1141  AllocatedType *allocate()
1142  {
1143  if ( freeHead_ ) // returns node from free list.
1144  {
1145  AllocatedType *object = freeHead_;
1146  freeHead_ = *static_cast<AllocatedType **>(object);
1147  return object;
1148  }
1149  if ( currentBatch_->used_ == currentBatch_->end_ )
1150  {
1151  currentBatch_ = currentBatch_->next_;
1152  while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
1153  currentBatch_ = currentBatch_->next_;
1154 
1155  if ( !currentBatch_ ) // no free batch found, allocate a new one
1156  {
1157  currentBatch_ = allocateBatch( objectsPerPage_ );
1158  currentBatch_->next_ = batches_; // insert at the head of the list
1159  batches_ = currentBatch_;
1160  }
1161  }
1162  AllocatedType *allocated = currentBatch_->used_;
1163  currentBatch_->used_ += objectPerAllocation;
1164  return allocated;
1165  }
1166 
1169  void release( AllocatedType *object )
1170  {
1171  assert( object != 0 );
1172  *static_cast<AllocatedType **>(object) = freeHead_;
1173  freeHead_ = object;
1174  }
1175 
1176 private:
1177  struct BatchInfo
1178  {
1179  BatchInfo *next_;
1180  AllocatedType *used_;
1181  AllocatedType *end_;
1182  AllocatedType buffer_[objectPerAllocation];
1183  };
1184 
1185  // disabled copy constructor and assignement operator.
1186  BatchAllocator( const BatchAllocator & );
1187  void operator =( const BatchAllocator &);
1188 
1189  static BatchInfo *allocateBatch( unsigned int objectsPerPage )
1190  {
1191  const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
1192  + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
1193  BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
1194  batch->next_ = 0;
1195  batch->used_ = batch->buffer_;
1196  batch->end_ = batch->buffer_ + objectsPerPage;
1197  return batch;
1198  }
1199 
1200  BatchInfo *batches_;
1201  BatchInfo *currentBatch_;
1203  AllocatedType *freeHead_;
1204  unsigned int objectsPerPage_;
1205 };
1206 
1207 
1208 } // namespace Json
1209 
1210 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
1211 
1212 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
1213 
1214 
1215 // //////////////////////////////////////////////////////////////////////
1216 // End of content of file: src/lib_json/json_batchallocator.h
1217 // //////////////////////////////////////////////////////////////////////
1218 
1219 
1220 
1221 
1222 
1223 
1224 // //////////////////////////////////////////////////////////////////////
1225 // Beginning of content of file: src/lib_json/json_valueiterator.inl
1226 // //////////////////////////////////////////////////////////////////////
1227 
1228 // Copyright 2007-2010 Baptiste Lepilleur
1229 // Distributed under MIT license, or public domain if desired and
1230 // recognized in your jurisdiction.
1231 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
1232 
1233 // included by json_value.cpp
1234 
1235 namespace Json {
1236 
1237 // //////////////////////////////////////////////////////////////////
1238 // //////////////////////////////////////////////////////////////////
1239 // //////////////////////////////////////////////////////////////////
1240 // class ValueIteratorBase
1241 // //////////////////////////////////////////////////////////////////
1242 // //////////////////////////////////////////////////////////////////
1243 // //////////////////////////////////////////////////////////////////
1244 
1246 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1247  : current_()
1248  , isNull_( true )
1249 {
1250 }
1251 #else
1252  : isArray_( true )
1253  , isNull_( true )
1254 {
1255  iterator_.array_ = ValueInternalArray::IteratorState();
1256 }
1257 #endif
1258 
1259 
1260 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1261 ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator &current )
1262  : current_( current )
1263  , isNull_( false )
1264 {
1265 }
1266 #else
1267 ValueIteratorBase::ValueIteratorBase( const ValueInternalArray::IteratorState &state )
1268  : isArray_( true )
1269 {
1270  iterator_.array_ = state;
1271 }
1272 
1273 
1274 ValueIteratorBase::ValueIteratorBase( const ValueInternalMap::IteratorState &state )
1275  : isArray_( false )
1276 {
1277  iterator_.map_ = state;
1278 }
1279 #endif
1280 
1281 Value &
1283 {
1284 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1285  return current_->second;
1286 #else
1287  if ( isArray_ )
1288  return ValueInternalArray::dereference( iterator_.array_ );
1289  return ValueInternalMap::value( iterator_.map_ );
1290 #endif
1291 }
1292 
1293 
1294 void
1296 {
1297 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1298  ++current_;
1299 #else
1300  if ( isArray_ )
1301  ValueInternalArray::increment( iterator_.array_ );
1302  ValueInternalMap::increment( iterator_.map_ );
1303 #endif
1304 }
1305 
1306 
1307 void
1309 {
1310 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1311  --current_;
1312 #else
1313  if ( isArray_ )
1314  ValueInternalArray::decrement( iterator_.array_ );
1315  ValueInternalMap::decrement( iterator_.map_ );
1316 #endif
1317 }
1318 
1319 
1322 {
1323 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1324 # ifdef JSON_USE_CPPTL_SMALLMAP
1325  return current_ - other.current_;
1326 # else
1327  // Iterator for null value are initialized using the default
1328  // constructor, which initialize current_ to the default
1329  // std::map::iterator. As begin() and end() are two instance
1330  // of the default std::map::iterator, they can not be compared.
1331  // To allow this, we handle this comparison specifically.
1332  if ( isNull_ && other.isNull_ )
1333  {
1334  return 0;
1335  }
1336 
1337 
1338  // Usage of std::distance is not portable (does not compile with Sun Studio 12 RogueWave STL,
1339  // which is the one used by default).
1340  // Using a portable hand-made version for non random iterator instead:
1341  // return difference_type( std::distance( current_, other.current_ ) );
1342  difference_type myDistance = 0;
1343  for ( Value::ObjectValues::iterator it = current_; it != other.current_; ++it )
1344  {
1345  ++myDistance;
1346  }
1347  return myDistance;
1348 # endif
1349 #else
1350  if ( isArray_ )
1351  return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ );
1352  return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ );
1353 #endif
1354 }
1355 
1356 
1357 bool
1359 {
1360 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1361  if ( isNull_ )
1362  {
1363  return other.isNull_;
1364  }
1365  return current_ == other.current_;
1366 #else
1367  if ( isArray_ )
1368  return ValueInternalArray::equals( iterator_.array_, other.iterator_.array_ );
1369  return ValueInternalMap::equals( iterator_.map_, other.iterator_.map_ );
1370 #endif
1371 }
1372 
1373 
1374 void
1376 {
1377 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1378  current_ = other.current_;
1379 #else
1380  if ( isArray_ )
1381  iterator_.array_ = other.iterator_.array_;
1382  iterator_.map_ = other.iterator_.map_;
1383 #endif
1384 }
1385 
1386 
1387 Value
1389 {
1390 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1391  const Value::CZString czstring = (*current_).first;
1392  if ( czstring.c_str() )
1393  {
1394  if ( czstring.isStaticString() )
1395  return Value( StaticString( czstring.c_str() ) );
1396  return Value( czstring.c_str() );
1397  }
1398  return Value( czstring.index() );
1399 #else
1400  if ( isArray_ )
1401  return Value( ValueInternalArray::indexOf( iterator_.array_ ) );
1402  bool isStatic;
1403  const char *memberName = ValueInternalMap::key( iterator_.map_, isStatic );
1404  if ( isStatic )
1405  return Value( StaticString( memberName ) );
1406  return Value( memberName );
1407 #endif
1408 }
1409 
1410 
1411 UInt
1413 {
1414 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1415  const Value::CZString czstring = (*current_).first;
1416  if ( !czstring.c_str() )
1417  return czstring.index();
1418  return Value::UInt( -1 );
1419 #else
1420  if ( isArray_ )
1421  return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) );
1422  return Value::UInt( -1 );
1423 #endif
1424 }
1425 
1426 
1427 const char *
1429 {
1430 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1431  const char *name = (*current_).first.c_str();
1432  return name ? name : "";
1433 #else
1434  if ( !isArray_ )
1435  return ValueInternalMap::key( iterator_.map_ );
1436  return "";
1437 #endif
1438 }
1439 
1440 
1441 // //////////////////////////////////////////////////////////////////
1442 // //////////////////////////////////////////////////////////////////
1443 // //////////////////////////////////////////////////////////////////
1444 // class ValueConstIterator
1445 // //////////////////////////////////////////////////////////////////
1446 // //////////////////////////////////////////////////////////////////
1447 // //////////////////////////////////////////////////////////////////
1448 
1450 {
1451 }
1452 
1453 
1454 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1455 ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator &current )
1456  : ValueIteratorBase( current )
1457 {
1458 }
1459 #else
1460 ValueConstIterator::ValueConstIterator( const ValueInternalArray::IteratorState &state )
1461  : ValueIteratorBase( state )
1462 {
1463 }
1464 
1465 ValueConstIterator::ValueConstIterator( const ValueInternalMap::IteratorState &state )
1466  : ValueIteratorBase( state )
1467 {
1468 }
1469 #endif
1470 
1473 {
1474  copy( other );
1475  return *this;
1476 }
1477 
1478 
1479 // //////////////////////////////////////////////////////////////////
1480 // //////////////////////////////////////////////////////////////////
1481 // //////////////////////////////////////////////////////////////////
1482 // class ValueIterator
1483 // //////////////////////////////////////////////////////////////////
1484 // //////////////////////////////////////////////////////////////////
1485 // //////////////////////////////////////////////////////////////////
1486 
1488 {
1489 }
1490 
1491 
1492 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1493 ValueIterator::ValueIterator( const Value::ObjectValues::iterator &current )
1494  : ValueIteratorBase( current )
1495 {
1496 }
1497 #else
1498 ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state )
1499  : ValueIteratorBase( state )
1500 {
1501 }
1502 
1503 ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state )
1504  : ValueIteratorBase( state )
1505 {
1506 }
1507 #endif
1508 
1510  : ValueIteratorBase( other )
1511 {
1512 }
1513 
1515  : ValueIteratorBase( other )
1516 {
1517 }
1518 
1519 ValueIterator &
1521 {
1522  copy( other );
1523  return *this;
1524 }
1525 
1526 } // namespace Json
1527 
1528 // //////////////////////////////////////////////////////////////////////
1529 // End of content of file: src/lib_json/json_valueiterator.inl
1530 // //////////////////////////////////////////////////////////////////////
1531 
1532 
1533 
1534 
1535 
1536 
1537 // //////////////////////////////////////////////////////////////////////
1538 // Beginning of content of file: src/lib_json/json_value.cpp
1539 // //////////////////////////////////////////////////////////////////////
1540 
1541 // Copyright 2007-2010 Baptiste Lepilleur
1542 // Distributed under MIT license, or public domain if desired and
1543 // recognized in your jurisdiction.
1544 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
1545 
1546 #if !defined(JSON_IS_AMALGAMATION)
1547 # include <json/value.h>
1548 # include <json/writer.h>
1549 # ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
1550 # include "json_batchallocator.h"
1551 # endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
1552 #endif // if !defined(JSON_IS_AMALGAMATION)
1553 #include <iostream>
1554 #include <utility>
1555 #include <stdexcept>
1556 #include <cstring>
1557 #include <cassert>
1558 #ifdef JSON_USE_CPPTL
1559 # include <cpptl/conststring.h>
1560 #endif
1561 #include <cstddef> // size_t
1562 
1563 #define JSON_ASSERT_UNREACHABLE assert( false )
1564 #define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw
1565 #define JSON_FAIL_MESSAGE( message ) throw std::runtime_error( message );
1566 #define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) JSON_FAIL_MESSAGE( message )
1567 
1568 namespace Json {
1569 
1570 const Value Value::null;
1571 const Int Value::minInt = Int( ~(UInt(-1)/2) );
1572 const Int Value::maxInt = Int( UInt(-1)/2 );
1573 const UInt Value::maxUInt = UInt(-1);
1574 const Int64 Value::minInt64 = Int64( ~(UInt64(-1)/2) );
1575 const Int64 Value::maxInt64 = Int64( UInt64(-1)/2 );
1576 const UInt64 Value::maxUInt64 = UInt64(-1);
1580 
1581 
1583 static const unsigned int unknown = -1;
1584 
1585 
1593 static inline char *
1594 duplicateStringValue( const char *value,
1595  unsigned int length = unknown )
1596 {
1597  if ( length == unknown )
1598  length = static_cast<unsigned int>(strlen(value));
1599  char *newString = static_cast<char *>( malloc( length + 1 ) );
1600  JSON_ASSERT_MESSAGE( newString != nullptr, "Failed to allocate string value buffer" );
1601  memcpy( newString, value, length );
1602  newString[length] = 0;
1603  return newString;
1604 }
1605 
1606 
1609 static inline void
1610 releaseStringValue( char *value )
1611 {
1612  if ( value )
1613  free( value );
1614 }
1615 
1616 } // namespace Json
1617 
1618 
1619 // //////////////////////////////////////////////////////////////////
1620 // //////////////////////////////////////////////////////////////////
1621 // //////////////////////////////////////////////////////////////////
1622 // ValueInternals...
1623 // //////////////////////////////////////////////////////////////////
1624 // //////////////////////////////////////////////////////////////////
1625 // //////////////////////////////////////////////////////////////////
1626 #if !defined(JSON_IS_AMALGAMATION)
1627 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1628 # include "json_internalarray.inl"
1629 # include "json_internalmap.inl"
1630 # endif // JSON_VALUE_USE_INTERNAL_MAP
1631 
1632 # include "json_valueiterator.inl"
1633 #endif // if !defined(JSON_IS_AMALGAMATION)
1634 
1635 namespace Json {
1636 
1637 // //////////////////////////////////////////////////////////////////
1638 // //////////////////////////////////////////////////////////////////
1639 // //////////////////////////////////////////////////////////////////
1640 // class Value::CommentInfo
1641 // //////////////////////////////////////////////////////////////////
1642 // //////////////////////////////////////////////////////////////////
1643 // //////////////////////////////////////////////////////////////////
1644 
1645 
1646 Value::CommentInfo::CommentInfo()
1647  : comment_( nullptr )
1648 {
1649 }
1650 
1651 Value::CommentInfo::~CommentInfo()
1652 {
1653  if ( comment_ )
1654  releaseStringValue( comment_ );
1655 }
1656 
1657 
1658 void
1659 Value::CommentInfo::setComment( const char *text )
1660 {
1661  if ( comment_ )
1662  releaseStringValue( comment_ );
1663  JSON_ASSERT( text != nullptr );
1664  JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
1665  // It seems that /**/ style comments are acceptable as well.
1666  comment_ = duplicateStringValue( text );
1667 }
1668 
1669 
1670 // //////////////////////////////////////////////////////////////////
1671 // //////////////////////////////////////////////////////////////////
1672 // //////////////////////////////////////////////////////////////////
1673 // class Value::CZString
1674 // //////////////////////////////////////////////////////////////////
1675 // //////////////////////////////////////////////////////////////////
1676 // //////////////////////////////////////////////////////////////////
1677 # ifndef JSON_VALUE_USE_INTERNAL_MAP
1678 
1679 // Notes: index_ indicates if the string was allocated when
1680 // a string is stored.
1681 
1682 Value::CZString::CZString( ArrayIndex index )
1683  : cstr_( nullptr )
1684  , index_( index )
1685 {
1686 }
1687 
1688 Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
1689  : cstr_( allocate == duplicate ? duplicateStringValue(cstr)
1690  : cstr )
1691  , index_( allocate )
1692 {
1693 }
1694 
1695 Value::CZString::CZString( const CZString &other )
1696 : cstr_( other.index_ != noDuplication && other.cstr_ != nullptr
1697  ? duplicateStringValue( other.cstr_ )
1698  : other.cstr_ )
1699  , index_( other.cstr_ ? (other.index_ == noDuplication ? static_cast<ArrayIndex>(noDuplication) : static_cast<ArrayIndex>(duplicate))
1700  : other.index_ )
1701 {
1702 }
1703 
1704 Value::CZString::~CZString()
1705 {
1706  if ( cstr_ && index_ == duplicate )
1707  releaseStringValue( const_cast<char *>( cstr_ ) );
1708 }
1709 
1710 void
1711 Value::CZString::swap( CZString &other )
1712 {
1713  std::swap( cstr_, other.cstr_ );
1714  std::swap( index_, other.index_ );
1715 }
1716 
1717 Value::CZString &
1718 Value::CZString::operator =( const CZString &other )
1719 {
1720  CZString temp( other );
1721  swap( temp );
1722  return *this;
1723 }
1724 
1725 bool
1726 Value::CZString::operator<( const CZString &other ) const
1727 {
1728  if ( cstr_ )
1729  return strcmp( cstr_, other.cstr_ ) < 0;
1730  return index_ < other.index_;
1731 }
1732 
1733 bool
1734 Value::CZString::operator==( const CZString &other ) const
1735 {
1736  if ( cstr_ )
1737  return strcmp( cstr_, other.cstr_ ) == 0;
1738  return index_ == other.index_;
1739 }
1740 
1741 
1742 ArrayIndex
1743 Value::CZString::index() const
1744 {
1745  return index_;
1746 }
1747 
1748 
1749 const char *
1750 Value::CZString::c_str() const
1751 {
1752  return cstr_;
1753 }
1754 
1755 bool
1756 Value::CZString::isStaticString() const
1757 {
1758  return index_ == noDuplication;
1759 }
1760 
1761 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
1762 
1763 
1764 // //////////////////////////////////////////////////////////////////
1765 // //////////////////////////////////////////////////////////////////
1766 // //////////////////////////////////////////////////////////////////
1767 // class Value::Value
1768 // //////////////////////////////////////////////////////////////////
1769 // //////////////////////////////////////////////////////////////////
1770 // //////////////////////////////////////////////////////////////////
1771 
1777  : type_( type )
1778  , allocated_( 0 )
1779  , comments_( nullptr )
1780 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1781  , itemIsUsed_( 0 )
1782 #endif
1783 {
1784  switch ( type )
1785  {
1786  case nullValue:
1787  break;
1788  case intValue:
1789  case uintValue:
1790  value_.int_ = 0;
1791  break;
1792  case realValue:
1793  value_.real_ = 0.0;
1794  break;
1795  case stringValue:
1796  value_.string_ = nullptr;
1797  break;
1798 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1799  case arrayValue:
1800  case objectValue:
1801  value_.map_ = new ObjectValues();
1802  break;
1803 #else
1804  case arrayValue:
1805  value_.array_ = arrayAllocator()->newArray();
1806  break;
1807  case objectValue:
1808  value_.map_ = mapAllocator()->newMap();
1809  break;
1810 #endif
1811  case booleanValue:
1812  value_.bool_ = false;
1813  break;
1814  default:
1816  }
1817 }
1818 
1819 
1820 #if defined(JSON_HAS_INT64)
1821 Value::Value( UInt value )
1822  : type_( uintValue )
1823  , comments_( nullptr )
1824 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1825  , itemIsUsed_( 0 )
1826 #endif
1827 {
1828  value_.uint_ = value;
1829 }
1830 
1831 Value::Value( Int value )
1832  : type_( intValue )
1833  , comments_( nullptr )
1834 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1835  , itemIsUsed_( 0 )
1836 #endif
1837 {
1838  value_.int_ = value;
1839 }
1840 
1841 #endif // if defined(JSON_HAS_INT64)
1842 
1843 
1845  : type_( intValue )
1846  , comments_( nullptr )
1847 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1848  , itemIsUsed_( 0 )
1849 #endif
1850 {
1851  value_.int_ = value;
1852 }
1853 
1854 
1856  : type_( uintValue )
1857  , comments_( nullptr )
1858 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1859  , itemIsUsed_( 0 )
1860 #endif
1861 {
1862  value_.uint_ = value;
1863 }
1864 
1865 Value::Value( double value )
1866  : type_( realValue )
1867  , comments_( nullptr )
1868 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1869  , itemIsUsed_( 0 )
1870 #endif
1871 {
1872  value_.real_ = value;
1873 }
1874 
1875 Value::Value( const char *value )
1876  : type_( stringValue )
1877  , allocated_( true )
1878  , comments_( nullptr )
1879 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1880  , itemIsUsed_( 0 )
1881 #endif
1882 {
1883  value_.string_ = duplicateStringValue( value );
1884 }
1885 
1886 
1887 Value::Value( const char *beginValue,
1888  const char *endValue )
1889  : type_( stringValue )
1890  , allocated_( true )
1891  , comments_( nullptr )
1892 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1893  , itemIsUsed_( 0 )
1894 #endif
1895 {
1896  value_.string_ = duplicateStringValue( beginValue,
1897  static_cast<unsigned int>(endValue - beginValue) );
1898 }
1899 
1900 
1901 Value::Value( const std::string &value )
1902  : type_( stringValue )
1903  , allocated_( true )
1904  , comments_( nullptr )
1905 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1906  , itemIsUsed_( 0 )
1907 #endif
1908 {
1909  value_.string_ = duplicateStringValue( value.c_str(),
1910  static_cast<unsigned int>(value.length()) );
1911 
1912 }
1913 
1915  : type_( stringValue )
1916  , allocated_( false )
1917  , comments_( nullptr )
1918 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1919  , itemIsUsed_( 0 )
1920 #endif
1921 {
1922  value_.string_ = const_cast<char *>( value.c_str() );
1923 }
1924 
1925 
1926 # ifdef JSON_USE_CPPTL
1927 Value::Value( const CppTL::ConstString &value )
1928  : type_( stringValue )
1929  , allocated_( true )
1930  , comments_( 0 )
1931 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1932  , itemIsUsed_( 0 )
1933 #endif
1934 {
1935  value_.string_ = duplicateStringValue( value, value.length() );
1936 }
1937 # endif
1938 
1939 Value::Value( bool value )
1940  : type_( booleanValue )
1941  , comments_( nullptr )
1942 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1943  , itemIsUsed_( 0 )
1944 #endif
1945 {
1946  value_.bool_ = value;
1947 }
1948 
1949 
1950 Value::Value( const Value &other )
1951  : type_( other.type_ )
1952  , comments_( nullptr )
1953 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1954  , itemIsUsed_( 0 )
1955 #endif
1956 {
1957  switch ( type_ )
1958  {
1959  case nullValue:
1960  case intValue:
1961  case uintValue:
1962  case realValue:
1963  case booleanValue:
1964  value_ = other.value_;
1965  break;
1966  case stringValue:
1967  if ( other.value_.string_ )
1968  {
1969  value_.string_ = duplicateStringValue( other.value_.string_ );
1970  allocated_ = true;
1971  }
1972  else
1973  value_.string_ = nullptr;
1974  break;
1975 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1976  case arrayValue:
1977  case objectValue:
1978  value_.map_ = new ObjectValues( *other.value_.map_ );
1979  break;
1980 #else
1981  case arrayValue:
1982  value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ );
1983  break;
1984  case objectValue:
1985  value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ );
1986  break;
1987 #endif
1988  default:
1990  }
1991  if ( other.comments_ )
1992  {
1993  comments_ = new CommentInfo[numberOfCommentPlacement];
1994  for ( int comment =0; comment < numberOfCommentPlacement; ++comment )
1995  {
1996  const CommentInfo &otherComment = other.comments_[comment];
1997  if ( otherComment.comment_ )
1998  comments_[comment].setComment( otherComment.comment_ );
1999  }
2000  }
2001 }
2002 
2003 
2005 {
2006  switch ( type_ )
2007  {
2008  case nullValue:
2009  case intValue:
2010  case uintValue:
2011  case realValue:
2012  case booleanValue:
2013  break;
2014  case stringValue:
2015  if ( allocated_ )
2016  releaseStringValue( value_.string_ );
2017  break;
2018 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2019  case arrayValue:
2020  case objectValue:
2021  delete value_.map_;
2022  break;
2023 #else
2024  case arrayValue:
2025  arrayAllocator()->destructArray( value_.array_ );
2026  break;
2027  case objectValue:
2028  mapAllocator()->destructMap( value_.map_ );
2029  break;
2030 #endif
2031  default:
2033  }
2034 
2035  if ( comments_ )
2036  delete[] comments_;
2037 }
2038 
2039 Value &
2040 Value::operator=( const Value &other )
2041 {
2042  Value temp( other );
2043  swap( temp );
2044  return *this;
2045 }
2046 
2047 void
2049 {
2050  ValueType temp = type_;
2051  type_ = other.type_;
2052  other.type_ = temp;
2053  std::swap( value_, other.value_ );
2054  int temp2 = allocated_;
2055  allocated_ = other.allocated_;
2056  other.allocated_ = temp2;
2057 }
2058 
2059 ValueType
2061 {
2062  return type_;
2063 }
2064 
2065 
2066 int
2067 Value::compare( const Value &other ) const
2068 {
2069  if ( *this < other )
2070  return -1;
2071  if ( *this > other )
2072  return 1;
2073  return 0;
2074 }
2075 
2076 
2077 bool
2078 Value::operator <( const Value &other ) const
2079 {
2080  int typeDelta = type_ - other.type_;
2081  if ( typeDelta )
2082  return typeDelta < 0 ? true : false;
2083  switch ( type_ )
2084  {
2085  case nullValue:
2086  return false;
2087  case intValue:
2088  return value_.int_ < other.value_.int_;
2089  case uintValue:
2090  return value_.uint_ < other.value_.uint_;
2091  case realValue:
2092  return value_.real_ < other.value_.real_;
2093  case booleanValue:
2094  return value_.bool_ < other.value_.bool_;
2095  case stringValue:
2096  return ( value_.string_ == nullptr && other.value_.string_ )
2097  || ( other.value_.string_
2098  && value_.string_
2099  && strcmp( value_.string_, other.value_.string_ ) < 0 );
2100 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2101  case arrayValue:
2102  case objectValue:
2103  {
2104  int delta = int( value_.map_->size() - other.value_.map_->size() );
2105  if ( delta )
2106  return delta < 0;
2107  return (*value_.map_) < (*other.value_.map_);
2108  }
2109 #else
2110  case arrayValue:
2111  return value_.array_->compare( *(other.value_.array_) ) < 0;
2112  case objectValue:
2113  return value_.map_->compare( *(other.value_.map_) ) < 0;
2114 #endif
2115  default:
2117  }
2118  return false; // unreachable
2119 }
2120 
2121 bool
2122 Value::operator <=( const Value &other ) const
2123 {
2124  return !(other < *this);
2125 }
2126 
2127 bool
2128 Value::operator >=( const Value &other ) const
2129 {
2130  return !(*this < other);
2131 }
2132 
2133 bool
2134 Value::operator >( const Value &other ) const
2135 {
2136  return other < *this;
2137 }
2138 
2139 bool
2140 Value::operator ==( const Value &other ) const
2141 {
2142  //if ( type_ != other.type_ )
2143  // GCC 2.95.3 says:
2144  // attempt to take address of bit-field structure member `Json::Value::type_'
2145  // Beats me, but a temp solves the problem.
2146  int temp = other.type_;
2147  if ( type_ != temp )
2148  return false;
2149  switch ( type_ )
2150  {
2151  case nullValue:
2152  return true;
2153  case intValue:
2154  return value_.int_ == other.value_.int_;
2155  case uintValue:
2156  return value_.uint_ == other.value_.uint_;
2157  case realValue:
2158  return value_.real_ == other.value_.real_;
2159  case booleanValue:
2160  return value_.bool_ == other.value_.bool_;
2161  case stringValue:
2162  return ( value_.string_ == other.value_.string_ )
2163  || ( other.value_.string_
2164  && value_.string_
2165  && strcmp( value_.string_, other.value_.string_ ) == 0 );
2166 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2167  case arrayValue:
2168  case objectValue:
2169  return value_.map_->size() == other.value_.map_->size()
2170  && (*value_.map_) == (*other.value_.map_);
2171 #else
2172  case arrayValue:
2173  return value_.array_->compare( *(other.value_.array_) ) == 0;
2174  case objectValue:
2175  return value_.map_->compare( *(other.value_.map_) ) == 0;
2176 #endif
2177  default:
2179  }
2180  return false; // unreachable
2181 }
2182 
2183 bool
2184 Value::operator !=( const Value &other ) const
2185 {
2186  return !( *this == other );
2187 }
2188 
2189 const char *
2191 {
2192  JSON_ASSERT( type_ == stringValue );
2193  return value_.string_;
2194 }
2195 
2196 
2197 std::string
2199 {
2200  switch ( type_ )
2201  {
2202  case nullValue:
2203  return "";
2204  case stringValue:
2205  return value_.string_ ? value_.string_ : "";
2206  case booleanValue:
2207  return value_.bool_ ? "true" : "false";
2208  case intValue:
2209  case uintValue:
2210  case realValue:
2211  case arrayValue:
2212  case objectValue:
2213  JSON_FAIL_MESSAGE( "Type is not convertible to string" );
2214  default:
2216  }
2217  return ""; // unreachable
2218 }
2219 
2220 # ifdef JSON_USE_CPPTL
2221 CppTL::ConstString
2222 Value::asConstString() const
2223 {
2224  return CppTL::ConstString( asString().c_str() );
2225 }
2226 # endif
2227 
2228 
2229 Value::Int
2231 {
2232  switch ( type_ )
2233  {
2234  case nullValue:
2235  return 0;
2236  case intValue:
2237  JSON_ASSERT_MESSAGE( value_.int_ >= minInt && value_.int_ <= maxInt, "unsigned integer out of signed int range" );
2238  return Int(value_.int_);
2239  case uintValue:
2240  JSON_ASSERT_MESSAGE( value_.uint_ <= UInt(maxInt), "unsigned integer out of signed int range" );
2241  return Int(value_.uint_);
2242  case realValue:
2243  JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
2244  return Int( value_.real_ );
2245  case booleanValue:
2246  return value_.bool_ ? 1 : 0;
2247  case stringValue:
2248  case arrayValue:
2249  case objectValue:
2250  JSON_FAIL_MESSAGE( "Type is not convertible to int" );
2251  default:
2253  }
2254  return 0; // unreachable;
2255 }
2256 
2257 
2260 {
2261  switch ( type_ )
2262  {
2263  case nullValue:
2264  return 0;
2265  case intValue:
2266  JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" );
2267  JSON_ASSERT_MESSAGE( value_.int_ <= maxUInt, "signed integer out of UInt range" );
2268  return UInt(value_.int_);
2269  case uintValue:
2270  JSON_ASSERT_MESSAGE( value_.uint_ <= maxUInt, "unsigned integer out of UInt range" );
2271  return UInt(value_.uint_);
2272  case realValue:
2273  JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" );
2274  return UInt( value_.real_ );
2275  case booleanValue:
2276  return value_.bool_ ? 1 : 0;
2277  case stringValue:
2278  case arrayValue:
2279  case objectValue:
2280  JSON_FAIL_MESSAGE( "Type is not convertible to uint" );
2281  default:
2283  }
2284  return 0; // unreachable;
2285 }
2286 
2287 
2288 # if defined(JSON_HAS_INT64)
2289 
2291 Value::asInt64() const
2292 {
2293  switch ( type_ )
2294  {
2295  case nullValue:
2296  return 0;
2297  case intValue:
2298  return value_.int_;
2299  case uintValue:
2300  JSON_ASSERT_MESSAGE( value_.uint_ <= UInt64(maxInt64), "unsigned integer out of Int64 range" );
2301  return value_.uint_;
2302  case realValue:
2303  JSON_ASSERT_MESSAGE( value_.real_ >= minInt64 && value_.real_ <= maxInt64, "Real out of Int64 range" );
2304  return Int( value_.real_ );
2305  case booleanValue:
2306  return value_.bool_ ? 1 : 0;
2307  case stringValue:
2308  case arrayValue:
2309  case objectValue:
2310  JSON_FAIL_MESSAGE( "Type is not convertible to Int64" );
2311  default:
2313  }
2314  return 0; // unreachable;
2315 }
2316 
2317 
2319 Value::asUInt64() const
2320 {
2321  switch ( type_ )
2322  {
2323  case nullValue:
2324  return 0;
2325  case intValue:
2326  JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to UInt64" );
2327  return value_.int_;
2328  case uintValue:
2329  return value_.uint_;
2330  case realValue:
2331  JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt64, "Real out of UInt64 range" );
2332  return UInt( value_.real_ );
2333  case booleanValue:
2334  return value_.bool_ ? 1 : 0;
2335  case stringValue:
2336  case arrayValue:
2337  case objectValue:
2338  JSON_FAIL_MESSAGE( "Type is not convertible to UInt64" );
2339  default:
2341  }
2342  return 0; // unreachable;
2343 }
2344 # endif // if defined(JSON_HAS_INT64)
2345 
2346 
2347 LargestInt
2349 {
2350 #if defined(JSON_NO_INT64)
2351  return asInt();
2352 #else
2353  return asInt64();
2354 #endif
2355 }
2356 
2357 
2360 {
2361 #if defined(JSON_NO_INT64)
2362  return asUInt();
2363 #else
2364  return asUInt64();
2365 #endif
2366 }
2367 
2368 
2369 double
2371 {
2372  switch ( type_ )
2373  {
2374  case nullValue:
2375  return 0.0;
2376  case intValue:
2377  return static_cast<double>( value_.int_ );
2378  case uintValue:
2379 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
2380  return static_cast<double>( value_.uint_ );
2381 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
2382  return static_cast<double>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1);
2383 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
2384  case realValue:
2385  return value_.real_;
2386  case booleanValue:
2387  return value_.bool_ ? 1.0 : 0.0;
2388  case stringValue:
2389  case arrayValue:
2390  case objectValue:
2391  JSON_FAIL_MESSAGE( "Type is not convertible to double" );
2392  default:
2394  }
2395  return 0; // unreachable;
2396 }
2397 
2398 float
2400 {
2401  switch ( type_ )
2402  {
2403  case nullValue:
2404  return 0.0f;
2405  case intValue:
2406  return static_cast<float>( value_.int_ );
2407  case uintValue:
2408 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
2409  return static_cast<float>( value_.uint_ );
2410 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
2411  return static_cast<float>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1);
2412 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
2413  case realValue:
2414  return static_cast<float>( value_.real_ );
2415  case booleanValue:
2416  return value_.bool_ ? 1.0f : 0.0f;
2417  case stringValue:
2418  case arrayValue:
2419  case objectValue:
2420  JSON_FAIL_MESSAGE( "Type is not convertible to float" );
2421  default:
2423  }
2424  return 0.0f; // unreachable;
2425 }
2426 
2427 bool
2429 {
2430  switch ( type_ )
2431  {
2432  case nullValue:
2433  return false;
2434  case intValue:
2435  case uintValue:
2436  return value_.int_ != 0;
2437  case realValue:
2438  return value_.real_ != 0.0;
2439  case booleanValue:
2440  return value_.bool_;
2441  case stringValue:
2442  return value_.string_ && value_.string_[0] != 0;
2443  case arrayValue:
2444  case objectValue:
2445  return value_.map_->size() != 0;
2446  default:
2448  }
2449  return false; // unreachable;
2450 }
2451 
2452 
2453 bool
2455 {
2456  switch ( type_ )
2457  {
2458  case nullValue:
2459  return true;
2460  case intValue:
2461  return ( other == nullValue && value_.int_ == 0 )
2462  || other == intValue
2463  || ( other == uintValue && value_.int_ >= 0 )
2464  || other == realValue
2465  || other == stringValue
2466  || other == booleanValue;
2467  case uintValue:
2468  return ( other == nullValue && value_.uint_ == 0 )
2469  || ( other == intValue && value_.uint_ <= static_cast<unsigned>(maxInt) )
2470  || other == uintValue
2471  || other == realValue
2472  || other == stringValue
2473  || other == booleanValue;
2474  case realValue:
2475  return ( other == nullValue && value_.real_ == 0.0 )
2476  || ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt )
2477  || ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt )
2478  || other == realValue
2479  || other == stringValue
2480  || other == booleanValue;
2481  case booleanValue:
2482  return ( other == nullValue && value_.bool_ == false )
2483  || other == intValue
2484  || other == uintValue
2485  || other == realValue
2486  || other == stringValue
2487  || other == booleanValue;
2488  case stringValue:
2489  return other == stringValue
2490  || ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) );
2491  case arrayValue:
2492  return other == arrayValue
2493  || ( other == nullValue && value_.map_->size() == 0 );
2494  case objectValue:
2495  return other == objectValue
2496  || ( other == nullValue && value_.map_->size() == 0 );
2497  default:
2499  }
2500  return false; // unreachable;
2501 }
2502 
2503 
2505 ArrayIndex
2507 {
2508  switch ( type_ )
2509  {
2510  case nullValue:
2511  case intValue:
2512  case uintValue:
2513  case realValue:
2514  case booleanValue:
2515  case stringValue:
2516  return 0;
2517 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2518  case arrayValue: // size of the array is highest index + 1
2519  if ( !value_.map_->empty() )
2520  {
2521  ObjectValues::const_iterator itLast = value_.map_->end();
2522  --itLast;
2523  return (*itLast).first.index()+1;
2524  }
2525  return 0;
2526  case objectValue:
2527  return ArrayIndex( value_.map_->size() );
2528 #else
2529  case arrayValue:
2530  return Int( value_.array_->size() );
2531  case objectValue:
2532  return Int( value_.map_->size() );
2533 #endif
2534  default:
2536  }
2537  return 0; // unreachable;
2538 }
2539 
2540 
2541 bool
2543 {
2544  if ( isNull() || isArray() || isObject() )
2545  return size() == 0u;
2546  else
2547  return false;
2548 }
2549 
2550 
2551 bool
2553 {
2554  return isNull();
2555 }
2556 
2557 
2558 void
2560 {
2561  JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue );
2562 
2563  switch ( type_ )
2564  {
2565 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2566  case arrayValue:
2567  case objectValue:
2568  value_.map_->clear();
2569  break;
2570 #else
2571  case arrayValue:
2572  value_.array_->clear();
2573  break;
2574  case objectValue:
2575  value_.map_->clear();
2576  break;
2577 #endif
2578  default:
2579  break;
2580  }
2581 }
2582 
2583 void
2585 {
2586  JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
2587  if ( type_ == nullValue )
2588  *this = Value( arrayValue );
2589 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2590  ArrayIndex oldSize = size();
2591  if ( newSize == 0 )
2592  clear();
2593  else if ( newSize > oldSize )
2594  (*this)[ newSize - 1 ];
2595  else
2596  {
2597  for ( ArrayIndex index = newSize; index < oldSize; ++index )
2598  {
2599  value_.map_->erase( index );
2600  }
2601  assert( size() == newSize );
2602  }
2603 #else
2604  value_.array_->resize( newSize );
2605 #endif
2606 }
2607 
2608 
2609 Value &
2611 {
2612  JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
2613  if ( type_ == nullValue )
2614  *this = Value( arrayValue );
2615 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2616  CZString key( index );
2617  ObjectValues::iterator it = value_.map_->lower_bound( key );
2618  if ( it != value_.map_->end() && (*it).first == key )
2619  return (*it).second;
2620 
2621  ObjectValues::value_type defaultValue( key, null );
2622  it = value_.map_->insert( it, defaultValue );
2623  return (*it).second;
2624 #else
2625  return value_.array_->resolveReference( index );
2626 #endif
2627 }
2628 
2629 
2630 Value &
2631 Value::operator[]( int index )
2632 {
2633  JSON_ASSERT( index >= 0 );
2634  return (*this)[ ArrayIndex(index) ];
2635 }
2636 
2637 
2638 const Value &
2640 {
2641  JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
2642  if ( type_ == nullValue )
2643  return null;
2644 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2645  CZString key( index );
2646  ObjectValues::const_iterator it = value_.map_->find( key );
2647  if ( it == value_.map_->end() )
2648  return null;
2649  return (*it).second;
2650 #else
2651  Value *value = value_.array_->find( index );
2652  return value ? *value : null;
2653 #endif
2654 }
2655 
2656 
2657 const Value &
2658 Value::operator[]( int index ) const
2659 {
2660  JSON_ASSERT( index >= 0 );
2661  return (*this)[ ArrayIndex(index) ];
2662 }
2663 
2664 
2665 Value &
2666 Value::operator[]( const char *key )
2667 {
2668  return resolveReference( key, false );
2669 }
2670 
2671 
2672 Value &
2673 Value::resolveReference( const char *key,
2674  bool isStatic )
2675 {
2676  JSON_ASSERT( type_ == nullValue || type_ == objectValue );
2677  if ( type_ == nullValue )
2678  *this = Value( objectValue );
2679 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2680  CZString actualKey( key, isStatic ? CZString::noDuplication
2681  : CZString::duplicateOnCopy );
2682  ObjectValues::iterator it = value_.map_->lower_bound( actualKey );
2683  if ( it != value_.map_->end() && (*it).first == actualKey )
2684  return (*it).second;
2685 
2686  ObjectValues::value_type defaultValue( actualKey, null );
2687  it = value_.map_->insert( it, defaultValue );
2688  Value &value = (*it).second;
2689  return value;
2690 #else
2691  return value_.map_->resolveReference( key, isStatic );
2692 #endif
2693 }
2694 
2695 
2696 Value
2698  const Value &defaultValue ) const
2699 {
2700  const Value *value = &((*this)[index]);
2701  return value == &null ? defaultValue : *value;
2702 }
2703 
2704 
2705 bool
2707 {
2708  return index < size();
2709 }
2710 
2711 
2712 
2713 const Value &
2714 Value::operator[]( const char *key ) const
2715 {
2716  JSON_ASSERT( type_ == nullValue || type_ == objectValue );
2717  if ( type_ == nullValue )
2718  return null;
2719 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2720  CZString actualKey( key, CZString::noDuplication );
2721  ObjectValues::const_iterator it = value_.map_->find( actualKey );
2722  if ( it == value_.map_->end() )
2723  return null;
2724  return (*it).second;
2725 #else
2726  const Value *value = value_.map_->find( key );
2727  return value ? *value : null;
2728 #endif
2729 }
2730 
2731 
2732 Value &
2733 Value::operator[]( const std::string &key )
2734 {
2735  return (*this)[ key.c_str() ];
2736 }
2737 
2738 
2739 const Value &
2740 Value::operator[]( const std::string &key ) const
2741 {
2742  return (*this)[ key.c_str() ];
2743 }
2744 
2745 Value &
2747 {
2748  return resolveReference( key, true );
2749 }
2750 
2751 
2752 # ifdef JSON_USE_CPPTL
2753 Value &
2754 Value::operator[]( const CppTL::ConstString &key )
2755 {
2756  return (*this)[ key.c_str() ];
2757 }
2758 
2759 
2760 const Value &
2761 Value::operator[]( const CppTL::ConstString &key ) const
2762 {
2763  return (*this)[ key.c_str() ];
2764 }
2765 # endif
2766 
2767 
2768 Value &
2769 Value::append( const Value &value )
2770 {
2771  return (*this)[size()] = value;
2772 }
2773 
2774 
2775 Value
2776 Value::get( const char *key,
2777  const Value &defaultValue ) const
2778 {
2779  const Value *value = &((*this)[key]);
2780  return value == &null ? defaultValue : *value;
2781 }
2782 
2783 
2784 Value
2785 Value::get( const std::string &key,
2786  const Value &defaultValue ) const
2787 {
2788  return get( key.c_str(), defaultValue );
2789 }
2790 
2791 Value
2792 Value::removeMember( const char* key )
2793 {
2794  JSON_ASSERT( type_ == nullValue || type_ == objectValue );
2795  if ( type_ == nullValue )
2796  return null;
2797 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2798  CZString actualKey( key, CZString::noDuplication );
2799  ObjectValues::iterator it = value_.map_->find( actualKey );
2800  if ( it == value_.map_->end() )
2801  return null;
2802  Value old(it->second);
2803  value_.map_->erase(it);
2804  return old;
2805 #else
2806  Value *value = value_.map_->find( key );
2807  if (value){
2808  Value old(*value);
2809  value_.map_.remove( key );
2810  return old;
2811  } else {
2812  return null;
2813  }
2814 #endif
2815 }
2816 
2817 Value
2818 Value::removeMember( const std::string &key )
2819 {
2820  return removeMember( key.c_str() );
2821 }
2822 
2823 # ifdef JSON_USE_CPPTL
2824 Value
2825 Value::get( const CppTL::ConstString &key,
2826  const Value &defaultValue ) const
2827 {
2828  return get( key.c_str(), defaultValue );
2829 }
2830 # endif
2831 
2832 bool
2833 Value::isMember( const char *key ) const
2834 {
2835  const Value *value = &((*this)[key]);
2836  return value != &null;
2837 }
2838 
2839 
2840 bool
2841 Value::isMember( const std::string &key ) const
2842 {
2843  return isMember( key.c_str() );
2844 }
2845 
2846 
2847 # ifdef JSON_USE_CPPTL
2848 bool
2849 Value::isMember( const CppTL::ConstString &key ) const
2850 {
2851  return isMember( key.c_str() );
2852 }
2853 #endif
2854 
2857 {
2858  JSON_ASSERT( type_ == nullValue || type_ == objectValue );
2859  if ( type_ == nullValue )
2860  return Value::Members();
2861  Members members;
2862  members.reserve( value_.map_->size() );
2863 #ifndef JSON_VALUE_USE_INTERNAL_MAP
2864  ObjectValues::const_iterator it = value_.map_->begin();
2865  ObjectValues::const_iterator itEnd = value_.map_->end();
2866  for ( ; it != itEnd; ++it )
2867  members.push_back( std::string( (*it).first.c_str() ) );
2868 #else
2869  ValueInternalMap::IteratorState it;
2870  ValueInternalMap::IteratorState itEnd;
2871  value_.map_->makeBeginIterator( it );
2872  value_.map_->makeEndIterator( itEnd );
2873  for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) )
2874  members.push_back( std::string( ValueInternalMap::key( it ) ) );
2875 #endif
2876  return members;
2877 }
2878 //
2879 //# ifdef JSON_USE_CPPTL
2880 //EnumMemberNames
2881 //Value::enumMemberNames() const
2882 //{
2883 // if ( type_ == objectValue )
2884 // {
2885 // return CppTL::Enum::any( CppTL::Enum::transform(
2886 // CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
2887 // MemberNamesTransform() ) );
2888 // }
2889 // return EnumMemberNames();
2890 //}
2891 //
2892 //
2893 //EnumValues
2894 //Value::enumValues() const
2895 //{
2896 // if ( type_ == objectValue || type_ == arrayValue )
2897 // return CppTL::Enum::anyValues( *(value_.map_),
2898 // CppTL::Type<const Value &>() );
2899 // return EnumValues();
2900 //}
2901 //
2902 //# endif
2903 
2904 
2905 bool
2907 {
2908  return type_ == nullValue;
2909 }
2910 
2911 
2912 bool
2914 {
2915  return type_ == booleanValue;
2916 }
2917 
2918 
2919 bool
2921 {
2922  return type_ == intValue;
2923 }
2924 
2925 
2926 bool
2928 {
2929  return type_ == uintValue;
2930 }
2931 
2932 
2933 bool
2935 {
2936  return type_ == intValue
2937  || type_ == uintValue
2938  || type_ == booleanValue;
2939 }
2940 
2941 
2942 bool
2944 {
2945  return type_ == realValue;
2946 }
2947 
2948 
2949 bool
2951 {
2952  return isIntegral() || isDouble();
2953 }
2954 
2955 
2956 bool
2958 {
2959  return type_ == stringValue;
2960 }
2961 
2962 
2963 bool
2965 {
2966  return type_ == nullValue || type_ == arrayValue;
2967 }
2968 
2969 
2970 bool
2972 {
2973  return type_ == nullValue || type_ == objectValue;
2974 }
2975 
2976 
2977 void
2978 Value::setComment( const char *comment,
2979  CommentPlacement placement )
2980 {
2981  if ( !comments_ )
2982  comments_ = new CommentInfo[numberOfCommentPlacement];
2983  comments_[placement].setComment( comment );
2984 }
2985 
2986 
2987 void
2988 Value::setComment( const std::string &comment,
2989  CommentPlacement placement )
2990 {
2991  setComment( comment.c_str(), placement );
2992 }
2993 
2994 
2995 bool
2997 {
2998  return comments_ != nullptr && comments_[placement].comment_ != nullptr;
2999 }
3000 
3001 std::string
3003 {
3004  if ( hasComment(placement) )
3005  return comments_[placement].comment_;
3006  return "";
3007 }
3008 
3009 
3010 std::string
3012 {
3013  StyledWriter writer;
3014  return writer.write( *this );
3015 }
3016 
3017 
3020 {
3021  switch ( type_ )
3022  {
3023 #ifdef JSON_VALUE_USE_INTERNAL_MAP
3024  case arrayValue:
3025  if ( value_.array_ )
3026  {
3027  ValueInternalArray::IteratorState it;
3028  value_.array_->makeBeginIterator( it );
3029  return const_iterator( it );
3030  }
3031  break;
3032  case objectValue:
3033  if ( value_.map_ )
3034  {
3035  ValueInternalMap::IteratorState it;
3036  value_.map_->makeBeginIterator( it );
3037  return const_iterator( it );
3038  }
3039  break;
3040 #else
3041  case arrayValue:
3042  case objectValue:
3043  if ( value_.map_ )
3044  return const_iterator( value_.map_->begin() );
3045  break;
3046 #endif
3047  default:
3048  break;
3049  }
3050  return const_iterator();
3051 }
3052 
3054 Value::end() const
3055 {
3056  switch ( type_ )
3057  {
3058 #ifdef JSON_VALUE_USE_INTERNAL_MAP
3059  case arrayValue:
3060  if ( value_.array_ )
3061  {
3062  ValueInternalArray::IteratorState it;
3063  value_.array_->makeEndIterator( it );
3064  return const_iterator( it );
3065  }
3066  break;
3067  case objectValue:
3068  if ( value_.map_ )
3069  {
3070  ValueInternalMap::IteratorState it;
3071  value_.map_->makeEndIterator( it );
3072  return const_iterator( it );
3073  }
3074  break;
3075 #else
3076  case arrayValue:
3077  case objectValue:
3078  if ( value_.map_ )
3079  return const_iterator( value_.map_->end() );
3080  break;
3081 #endif
3082  default:
3083  break;
3084  }
3085  return const_iterator();
3086 }
3087 
3088 
3091 {
3092  switch ( type_ )
3093  {
3094 #ifdef JSON_VALUE_USE_INTERNAL_MAP
3095  case arrayValue:
3096  if ( value_.array_ )
3097  {
3098  ValueInternalArray::IteratorState it;
3099  value_.array_->makeBeginIterator( it );
3100  return iterator( it );
3101  }
3102  break;
3103  case objectValue:
3104  if ( value_.map_ )
3105  {
3106  ValueInternalMap::IteratorState it;
3107  value_.map_->makeBeginIterator( it );
3108  return iterator( it );
3109  }
3110  break;
3111 #else
3112  case arrayValue:
3113  case objectValue:
3114  if ( value_.map_ )
3115  return iterator( value_.map_->begin() );
3116  break;
3117 #endif
3118  default:
3119  break;
3120  }
3121  return iterator();
3122 }
3123 
3126 {
3127  switch ( type_ )
3128  {
3129 #ifdef JSON_VALUE_USE_INTERNAL_MAP
3130  case arrayValue:
3131  if ( value_.array_ )
3132  {
3133  ValueInternalArray::IteratorState it;
3134  value_.array_->makeEndIterator( it );
3135  return iterator( it );
3136  }
3137  break;
3138  case objectValue:
3139  if ( value_.map_ )
3140  {
3141  ValueInternalMap::IteratorState it;
3142  value_.map_->makeEndIterator( it );
3143  return iterator( it );
3144  }
3145  break;
3146 #else
3147  case arrayValue:
3148  case objectValue:
3149  if ( value_.map_ )
3150  return iterator( value_.map_->end() );
3151  break;
3152 #endif
3153  default:
3154  break;
3155  }
3156  return iterator();
3157 }
3158 
3159 
3160 // class PathArgument
3161 // //////////////////////////////////////////////////////////////////
3162 
3164  : kind_( kindNone )
3165 {
3166 }
3167 
3168 
3170  : index_( index )
3171  , kind_( kindIndex )
3172 {
3173 }
3174 
3175 
3176 PathArgument::PathArgument( const char *key )
3177  : key_( key )
3178  , kind_( kindKey )
3179 {
3180 }
3181 
3182 
3183 PathArgument::PathArgument( const std::string &key )
3184  : key_( key.c_str() )
3185  , kind_( kindKey )
3186 {
3187 }
3188 
3189 // class Path
3190 // //////////////////////////////////////////////////////////////////
3191 
3192 Path::Path( const std::string &path,
3193  const PathArgument &a1,
3194  const PathArgument &a2,
3195  const PathArgument &a3,
3196  const PathArgument &a4,
3197  const PathArgument &a5 )
3198 {
3199  InArgs in;
3200  in.push_back( &a1 );
3201  in.push_back( &a2 );
3202  in.push_back( &a3 );
3203  in.push_back( &a4 );
3204  in.push_back( &a5 );
3205  makePath( path, in );
3206 }
3207 
3208 
3209 void
3210 Path::makePath( const std::string &path,
3211  const InArgs &in )
3212 {
3213  const char *current = path.c_str();
3214  const char *end = current + path.length();
3215  InArgs::const_iterator itInArg = in.begin();
3216  while ( current != end )
3217  {
3218  if ( *current == '[' )
3219  {
3220  ++current;
3221  if ( *current == '%' )
3222  addPathInArg( path, in, itInArg, PathArgument::kindIndex );
3223  else
3224  {
3225  ArrayIndex index = 0;
3226  for ( ; current != end && *current >= '0' && *current <= '9'; ++current )
3227  index = index * 10 + ArrayIndex(*current - '0');
3228  args_.push_back( index );
3229  }
3230  if ( current == end || *current++ != ']' )
3231  invalidPath( path, int(current - path.c_str()) );
3232  }
3233  else if ( *current == '%' )
3234  {
3235  addPathInArg( path, in, itInArg, PathArgument::kindKey );
3236  ++current;
3237  }
3238  else if ( *current == '.' )
3239  {
3240  ++current;
3241  }
3242  else
3243  {
3244  const char *beginName = current;
3245  while ( current != end && !strchr( "[.", *current ) )
3246  ++current;
3247  args_.push_back( std::string( beginName, current ) );
3248  }
3249  }
3250 }
3251 
3252 
3253 void
3254 Path::addPathInArg( const std::string &/*path*/,
3255  const InArgs &in,
3256  InArgs::const_iterator &itInArg,
3257  PathArgument::Kind kind )
3258 {
3259  if ( itInArg == in.end() )
3260  {
3261  // Error: missing argument %d
3262  }
3263  else if ( (*itInArg)->kind_ != kind )
3264  {
3265  // Error: bad argument type
3266  }
3267  else
3268  {
3269  args_.push_back( **itInArg );
3270  }
3271 }
3272 
3273 
3274 void
3275 Path::invalidPath( const std::string &/*path*/,
3276  int /*location*/ )
3277 {
3278  // Error: invalid path.
3279 }
3280 
3281 
3282 const Value &
3283 Path::resolve( const Value &root ) const
3284 {
3285  const Value *node = &root;
3286  for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
3287  {
3288  const PathArgument &arg = *it;
3289  if ( arg.kind_ == PathArgument::kindIndex )
3290  {
3291  if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
3292  {
3293  // Error: unable to resolve path (array value expected at position...
3294  }
3295  node = &((*node)[arg.index_]);
3296  }
3297  else if ( arg.kind_ == PathArgument::kindKey )
3298  {
3299  if ( !node->isObject() )
3300  {
3301  // Error: unable to resolve path (object value expected at position...)
3302  }
3303  node = &((*node)[arg.key_]);
3304  if ( node == &Value::null )
3305  {
3306  // Error: unable to resolve path (object has no member named '' at position...)
3307  }
3308  }
3309  }
3310  return *node;
3311 }
3312 
3313 
3314 Value
3315 Path::resolve( const Value &root,
3316  const Value &defaultValue ) const
3317 {
3318  const Value *node = &root;
3319  for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
3320  {
3321  const PathArgument &arg = *it;
3322  if ( arg.kind_ == PathArgument::kindIndex )
3323  {
3324  if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
3325  return defaultValue;
3326  node = &((*node)[arg.index_]);
3327  }
3328  else if ( arg.kind_ == PathArgument::kindKey )
3329  {
3330  if ( !node->isObject() )
3331  return defaultValue;
3332  node = &((*node)[arg.key_]);
3333  if ( node == &Value::null )
3334  return defaultValue;
3335  }
3336  }
3337  return *node;
3338 }
3339 
3340 
3341 Value &
3342 Path::make( Value &root ) const
3343 {
3344  Value *node = &root;
3345  for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
3346  {
3347  const PathArgument &arg = *it;
3348  if ( arg.kind_ == PathArgument::kindIndex )
3349  {
3350  if ( !node->isArray() )
3351  {
3352  // Error: node is not an array at position ...
3353  }
3354  node = &((*node)[arg.index_]);
3355  }
3356  else if ( arg.kind_ == PathArgument::kindKey )
3357  {
3358  if ( !node->isObject() )
3359  {
3360  // Error: node is not an object at position...
3361  }
3362  node = &((*node)[arg.key_]);
3363  }
3364  }
3365  return *node;
3366 }
3367 
3368 
3369 } // namespace Json
3370 
3371 // //////////////////////////////////////////////////////////////////////
3372 // End of content of file: src/lib_json/json_value.cpp
3373 // //////////////////////////////////////////////////////////////////////
3374 
3375 
3376 
3377 
3378 
3379 
3380 // //////////////////////////////////////////////////////////////////////
3381 // Beginning of content of file: src/lib_json/json_writer.cpp
3382 // //////////////////////////////////////////////////////////////////////
3383 
3384 // Copyright 2007-2010 Baptiste Lepilleur
3385 // Distributed under MIT license, or public domain if desired and
3386 // recognized in your jurisdiction.
3387 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
3388 
3389 #if !defined(JSON_IS_AMALGAMATION)
3390 # include <json/writer.h>
3391 # include "json_tool.h"
3392 #endif // if !defined(JSON_IS_AMALGAMATION)
3393 #include <utility>
3394 #include <assert.h>
3395 #include <stdio.h>
3396 #include <string.h>
3397 #include <iostream>
3398 #include <sstream>
3399 #include <iomanip>
3400 
3401 #if _MSC_VER >= 1400 // VC++ 8.0
3402 #pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
3403 #endif
3404 
3405 namespace Json {
3406 
3407 static bool containsControlCharacter( const char* str )
3408 {
3409  while ( *str )
3410  {
3411  if ( isControlCharacter( *(str++) ) )
3412  return true;
3413  }
3414  return false;
3415 }
3416 
3417 
3418 std::string valueToString( LargestInt value )
3419 {
3420  UIntToStringBuffer buffer;
3421  char *current = buffer + sizeof(buffer);
3422  bool isNegative = value < 0;
3423  if ( isNegative )
3424  value = -value;
3425  uintToString( LargestUInt(value), current );
3426  if ( isNegative )
3427  *--current = '-';
3428  assert( current >= buffer );
3429  return current;
3430 }
3431 
3432 
3433 std::string valueToString( LargestUInt value )
3434 {
3435  UIntToStringBuffer buffer;
3436  char *current = buffer + sizeof(buffer);
3437  uintToString( value, current );
3438  assert( current >= buffer );
3439  return current;
3440 }
3441 
3442 #if defined(JSON_HAS_INT64)
3443 
3444 std::string valueToString( Int value )
3445 {
3446  return valueToString( LargestInt(value) );
3447 }
3448 
3449 
3450 std::string valueToString( UInt value )
3451 {
3452  return valueToString( LargestUInt(value) );
3453 }
3454 
3455 #endif // # if defined(JSON_HAS_INT64)
3456 
3457 
3458 std::string valueToString( double value )
3459 {
3460  char buffer[32];
3461 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning.
3462  sprintf_s(buffer, sizeof(buffer), "%#.16g", value);
3463 #else
3464  sprintf(buffer, "%#.16g", value);
3465 #endif
3466  char* ch = buffer + strlen(buffer) - 1;
3467  if (*ch != '0') return buffer; // nothing to truncate, so save time
3468  while(ch > buffer && *ch == '0'){
3469  --ch;
3470  }
3471  char* last_nonzero = ch;
3472  while(ch >= buffer){
3473  switch(*ch){
3474  case '0':
3475  case '1':
3476  case '2':
3477  case '3':
3478  case '4':
3479  case '5':
3480  case '6':
3481  case '7':
3482  case '8':
3483  case '9':
3484  --ch;
3485  continue;
3486  case '.':
3487  // Truncate zeroes to save bytes in output, but keep one.
3488  *(last_nonzero+2) = '\0';
3489  return buffer;
3490  default:
3491  return buffer;
3492  }
3493  }
3494  return buffer;
3495 }
3496 
3497 
3498 std::string valueToString( bool value )
3499 {
3500  return value ? "true" : "false";
3501 }
3502 
3503 std::string valueToQuotedString( const char *value )
3504 {
3505  // Not sure how to handle unicode...
3506  if (strpbrk(value, "\"\\\b\f\n\r\t") == nullptr && !containsControlCharacter( value ))
3507  return std::string("\"") + value + "\"";
3508  // We have to walk value and escape any special characters.
3509  // Appending to std::string is not efficient, but this should be rare.
3510  // (Note: forward slashes are *not* rare, but I am not escaping them.)
3511  std::string::size_type maxsize = strlen(value)*2 + 3; // allescaped+quotes+nullptr
3512  std::string result;
3513  result.reserve(maxsize); // to avoid lots of mallocs
3514  result += "\"";
3515  for (const char* c=value; *c != 0; ++c)
3516  {
3517  switch(*c)
3518  {
3519  case '\"':
3520  result += "\\\"";
3521  break;
3522  case '\\':
3523  result += "\\\\";
3524  break;
3525  case '\b':
3526  result += "\\b";
3527  break;
3528  case '\f':
3529  result += "\\f";
3530  break;
3531  case '\n':
3532  result += "\\n";
3533  break;
3534  case '\r':
3535  result += "\\r";
3536  break;
3537  case '\t':
3538  result += "\\t";
3539  break;
3540  //case '/':
3541  // Even though \/ is considered a legal escape in JSON, a bare
3542  // slash is also legal, so I see no reason to escape it.
3543  // (I hope I am not misunderstanding something.
3544  // blep notes: actually escaping \/ may be useful in javascript to avoid </
3545  // sequence.
3546  // Should add a flag to allow this compatibility mode and prevent this
3547  // sequence from occurring.
3548  default:
3549  if ( isControlCharacter( *c ) )
3550  {
3551  std::ostringstream oss;
3552  oss << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*c);
3553  result += oss.str();
3554  }
3555  else
3556  {
3557  result += *c;
3558  }
3559  break;
3560  }
3561  }
3562  result += "\"";
3563  return result;
3564 }
3565 
3566 // Class Writer
3567 // //////////////////////////////////////////////////////////////////
3569 {
3570 }
3571 
3572 
3573 // Class FastWriter
3574 // //////////////////////////////////////////////////////////////////
3575 
3577  : yamlCompatiblityEnabled_( false )
3578 {
3579 }
3580 
3581 
3582 void
3584 {
3585  yamlCompatiblityEnabled_ = true;
3586 }
3587 
3588 
3589 std::string
3590 FastWriter::write( const Value &root )
3591 {
3592  document_ = "";
3593  writeValue( root );
3594  document_ += "\n";
3595  return document_;
3596 }
3597 
3598 
3599 void
3600 FastWriter::writeValue( const Value &value )
3601 {
3602  switch ( value.type() )
3603  {
3604  case nullValue:
3605  document_ += "null";
3606  break;
3607  case intValue:
3608  document_ += valueToString( value.asLargestInt() );
3609  break;
3610  case uintValue:
3611  document_ += valueToString( value.asLargestUInt() );
3612  break;
3613  case realValue:
3614  document_ += valueToString( value.asDouble() );
3615  break;
3616  case stringValue:
3617  document_ += valueToQuotedString( value.asCString() );
3618  break;
3619  case booleanValue:
3620  document_ += valueToString( value.asBool() );
3621  break;
3622  case arrayValue:
3623  {
3624  document_ += "[";
3625  int size = value.size();
3626  for ( int index =0; index < size; ++index )
3627  {
3628  if ( index > 0 )
3629  document_ += ",";
3630  writeValue( value[index] );
3631  }
3632  document_ += "]";
3633  }
3634  break;
3635  case objectValue:
3636  {
3637  Value::Members members( value.getMemberNames() );
3638  document_ += "{";
3639  for ( Value::Members::iterator it = members.begin();
3640  it != members.end();
3641  ++it )
3642  {
3643  const std::string &name = *it;
3644  if ( it != members.begin() )
3645  document_ += ",";
3646  document_ += valueToQuotedString( name.c_str() );
3647  document_ += yamlCompatiblityEnabled_ ? ": "
3648  : ":";
3649  writeValue( value[name] );
3650  }
3651  document_ += "}";
3652  }
3653  break;
3654  }
3655 }
3656 
3657 
3658 // Class StyledWriter
3659 // //////////////////////////////////////////////////////////////////
3660 
3662  : rightMargin_( 74 )
3663  , indentSize_( 3 )
3664 {
3665 }
3666 
3667 
3668 std::string
3670 {
3671  document_ = "";
3672  addChildValues_ = false;
3673  indentString_ = "";
3674  writeCommentBeforeValue( root );
3675  writeValue( root );
3676  writeCommentAfterValueOnSameLine( root );
3677  document_ += "\n";
3678  return document_;
3679 }
3680 
3681 
3682 void
3683 StyledWriter::writeValue( const Value &value )
3684 {
3685  switch ( value.type() )
3686  {
3687  case nullValue:
3688  pushValue( "null" );
3689  break;
3690  case intValue:
3691  pushValue( valueToString( value.asLargestInt() ) );
3692  break;
3693  case uintValue:
3694  pushValue( valueToString( value.asLargestUInt() ) );
3695  break;
3696  case realValue:
3697  pushValue( valueToString( value.asDouble() ) );
3698  break;
3699  case stringValue:
3700  pushValue( valueToQuotedString( value.asCString() ) );
3701  break;
3702  case booleanValue:
3703  pushValue( valueToString( value.asBool() ) );
3704  break;
3705  case arrayValue:
3706  writeArrayValue( value);
3707  break;
3708  case objectValue:
3709  {
3710  Value::Members members( value.getMemberNames() );
3711  if ( members.empty() )
3712  pushValue( "{}" );
3713  else
3714  {
3715  writeWithIndent( "{" );
3716  indent();
3717  Value::Members::iterator it = members.begin();
3718  for (;;)
3719  {
3720  const std::string &name = *it;
3721  const Value &childValue = value[name];
3722  writeCommentBeforeValue( childValue );
3723  writeWithIndent( valueToQuotedString( name.c_str() ) );
3724  document_ += " : ";
3725  writeValue( childValue );
3726  if ( ++it == members.end() )
3727  {
3728  writeCommentAfterValueOnSameLine( childValue );
3729  break;
3730  }
3731  document_ += ",";
3732  writeCommentAfterValueOnSameLine( childValue );
3733  }
3734  unindent();
3735  writeWithIndent( "}" );
3736  }
3737  }
3738  break;
3739  }
3740 }
3741 
3742 
3743 void
3744 StyledWriter::writeArrayValue( const Value &value )
3745 {
3746  unsigned size = value.size();
3747  if ( size == 0 )
3748  pushValue( "[]" );
3749  else
3750  {
3751  bool isArrayMultiLine = isMultineArray( value );
3752  if ( isArrayMultiLine )
3753  {
3754  writeWithIndent( "[" );
3755  indent();
3756  bool hasChildValue = !childValues_.empty();
3757  unsigned index =0;
3758  for (;;)
3759  {
3760  const Value &childValue = value[index];
3761  writeCommentBeforeValue( childValue );
3762  if ( hasChildValue )
3763  writeWithIndent( childValues_[index] );
3764  else
3765  {
3766  writeIndent();
3767  writeValue( childValue );
3768  }
3769  if ( ++index == size )
3770  {
3771  writeCommentAfterValueOnSameLine( childValue );
3772  break;
3773  }
3774  document_ += ",";
3775  writeCommentAfterValueOnSameLine( childValue );
3776  }
3777  unindent();
3778  writeWithIndent( "]" );
3779  }
3780  else // output on a single line
3781  {
3782  assert( childValues_.size() == size );
3783  document_ += "[ ";
3784  for ( unsigned index =0; index < size; ++index )
3785  {
3786  if ( index > 0 )
3787  document_ += ", ";
3788  document_ += childValues_[index];
3789  }
3790  document_ += " ]";
3791  }
3792  }
3793 }
3794 
3795 
3796 bool
3797 StyledWriter::isMultineArray( const Value &value )
3798 {
3799  int size = value.size();
3800  bool isMultiLine = size*3 >= rightMargin_ ;
3801  childValues_.clear();
3802  for ( int index =0; index < size && !isMultiLine; ++index )
3803  {
3804  const Value &childValue = value[index];
3805  isMultiLine = isMultiLine ||
3806  ( (childValue.isArray() || childValue.isObject()) &&
3807  childValue.size() > 0 );
3808  }
3809  if ( !isMultiLine ) // check if line length > max line length
3810  {
3811  childValues_.reserve( size );
3812  addChildValues_ = true;
3813  int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
3814  for ( int index =0; index < size && !isMultiLine; ++index )
3815  {
3816  writeValue( value[index] );
3817  lineLength += int( childValues_[index].length() );
3818  isMultiLine = isMultiLine && hasCommentForValue( value[index] );
3819  }
3820  addChildValues_ = false;
3821  isMultiLine = isMultiLine || lineLength >= rightMargin_;
3822  }
3823  return isMultiLine;
3824 }
3825 
3826 
3827 void
3828 StyledWriter::pushValue( const std::string &value )
3829 {
3830  if ( addChildValues_ )
3831  childValues_.push_back( value );
3832  else
3833  document_ += value;
3834 }
3835 
3836 
3837 void
3838 StyledWriter::writeIndent()
3839 {
3840  if ( !document_.empty() )
3841  {
3842  char last = document_[document_.length()-1];
3843  if ( last == ' ' ) // already indented
3844  return;
3845  if ( last != '\n' ) // Comments may add new-line
3846  document_ += '\n';
3847  }
3848  document_ += indentString_;
3849 }
3850 
3851 
3852 void
3853 StyledWriter::writeWithIndent( const std::string &value )
3854 {
3855  writeIndent();
3856  document_ += value;
3857 }
3858 
3859 
3860 void
3861 StyledWriter::indent()
3862 {
3863  indentString_ += std::string( indentSize_, ' ' );
3864 }
3865 
3866 
3867 void
3868 StyledWriter::unindent()
3869 {
3870  assert( int(indentString_.size()) >= indentSize_ );
3871  indentString_.resize( indentString_.size() - indentSize_ );
3872 }
3873 
3874 
3875 void
3876 StyledWriter::writeCommentBeforeValue( const Value &root )
3877 {
3878  if ( !root.hasComment( commentBefore ) )
3879  return;
3880  document_ += normalizeEOL( root.getComment( commentBefore ) );
3881  document_ += "\n";
3882 }
3883 
3884 
3885 void
3886 StyledWriter::writeCommentAfterValueOnSameLine( const Value &root )
3887 {
3888  if ( root.hasComment( commentAfterOnSameLine ) )
3889  document_ += " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
3890 
3891  if ( root.hasComment( commentAfter ) )
3892  {
3893  document_ += "\n";
3894  document_ += normalizeEOL( root.getComment( commentAfter ) );
3895  document_ += "\n";
3896  }
3897 }
3898 
3899 
3900 bool
3901 StyledWriter::hasCommentForValue( const Value &value )
3902 {
3903  return value.hasComment( commentBefore )
3905  || value.hasComment( commentAfter );
3906 }
3907 
3908 
3909 std::string
3910 StyledWriter::normalizeEOL( const std::string &text )
3911 {
3912  std::string normalized;
3913  normalized.reserve( text.length() );
3914  const char *begin = text.c_str();
3915  const char *end = begin + text.length();
3916  const char *current = begin;
3917  while ( current != end )
3918  {
3919  char c = *current++;
3920  if ( c == '\r' ) // mac or dos EOL
3921  {
3922  if ( *current == '\n' ) // convert dos EOL
3923  ++current;
3924  normalized += '\n';
3925  }
3926  else // handle unix EOL & other char
3927  normalized += c;
3928  }
3929  return normalized;
3930 }
3931 
3932 
3933 // Class StyledStreamWriter
3934 // //////////////////////////////////////////////////////////////////
3935 
3936 StyledStreamWriter::StyledStreamWriter( std::string indentation )
3937  : document_(nullptr)
3938  , rightMargin_( 74 )
3939  , indentation_( indentation )
3940 {
3941 }
3942 
3943 
3944 void
3945 StyledStreamWriter::write( std::ostream &out, const Value &root )
3946 {
3947  document_ = &out;
3948  addChildValues_ = false;
3949  indentString_ = "";
3950  writeCommentBeforeValue( root );
3951  writeValue( root );
3952  writeCommentAfterValueOnSameLine( root );
3953  *document_ << "\n";
3954  document_ = nullptr; // Forget the stream, for safety.
3955 }
3956 
3957 
3958 void
3959 StyledStreamWriter::writeValue( const Value &value )
3960 {
3961  switch ( value.type() )
3962  {
3963  case nullValue:
3964  pushValue( "null" );
3965  break;
3966  case intValue:
3967  pushValue( valueToString( value.asLargestInt() ) );
3968  break;
3969  case uintValue:
3970  pushValue( valueToString( value.asLargestUInt() ) );
3971  break;
3972  case realValue:
3973  pushValue( valueToString( value.asDouble() ) );
3974  break;
3975  case stringValue:
3976  pushValue( valueToQuotedString( value.asCString() ) );
3977  break;
3978  case booleanValue:
3979  pushValue( valueToString( value.asBool() ) );
3980  break;
3981  case arrayValue:
3982  writeArrayValue( value);
3983  break;
3984  case objectValue:
3985  {
3986  Value::Members members( value.getMemberNames() );
3987  if ( members.empty() )
3988  pushValue( "{}" );
3989  else
3990  {
3991  writeWithIndent( "{" );
3992  indent();
3993  Value::Members::iterator it = members.begin();
3994  for (;;)
3995  {
3996  const std::string &name = *it;
3997  const Value &childValue = value[name];
3998  writeCommentBeforeValue( childValue );
3999  writeWithIndent( valueToQuotedString( name.c_str() ) );
4000  *document_ << " : ";
4001  writeValue( childValue );
4002  if ( ++it == members.end() )
4003  {
4004  writeCommentAfterValueOnSameLine( childValue );
4005  break;
4006  }
4007  *document_ << ",";
4008  writeCommentAfterValueOnSameLine( childValue );
4009  }
4010  unindent();
4011  writeWithIndent( "}" );
4012  }
4013  }
4014  break;
4015  }
4016 }
4017 
4018 
4019 void
4020 StyledStreamWriter::writeArrayValue( const Value &value )
4021 {
4022  unsigned size = value.size();
4023  if ( size == 0 )
4024  pushValue( "[]" );
4025  else
4026  {
4027  bool isArrayMultiLine = isMultineArray( value );
4028  if ( isArrayMultiLine )
4029  {
4030  writeWithIndent( "[" );
4031  indent();
4032  bool hasChildValue = !childValues_.empty();
4033  unsigned index =0;
4034  for (;;)
4035  {
4036  const Value &childValue = value[index];
4037  writeCommentBeforeValue( childValue );
4038  if ( hasChildValue )
4039  writeWithIndent( childValues_[index] );
4040  else
4041  {
4042  writeIndent();
4043  writeValue( childValue );
4044  }
4045  if ( ++index == size )
4046  {
4047  writeCommentAfterValueOnSameLine( childValue );
4048  break;
4049  }
4050  *document_ << ",";
4051  writeCommentAfterValueOnSameLine( childValue );
4052  }
4053  unindent();
4054  writeWithIndent( "]" );
4055  }
4056  else // output on a single line
4057  {
4058  assert( childValues_.size() == size );
4059  *document_ << "[ ";
4060  for ( unsigned index =0; index < size; ++index )
4061  {
4062  if ( index > 0 )
4063  *document_ << ", ";
4064  *document_ << childValues_[index];
4065  }
4066  *document_ << " ]";
4067  }
4068  }
4069 }
4070 
4071 
4072 bool
4073 StyledStreamWriter::isMultineArray( const Value &value )
4074 {
4075  int size = value.size();
4076  bool isMultiLine = size*3 >= rightMargin_ ;
4077  childValues_.clear();
4078  for ( int index =0; index < size && !isMultiLine; ++index )
4079  {
4080  const Value &childValue = value[index];
4081  isMultiLine = isMultiLine ||
4082  ( (childValue.isArray() || childValue.isObject()) &&
4083  childValue.size() > 0 );
4084  }
4085  if ( !isMultiLine ) // check if line length > max line length
4086  {
4087  childValues_.reserve( size );
4088  addChildValues_ = true;
4089  int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
4090  for ( int index =0; index < size && !isMultiLine; ++index )
4091  {
4092  writeValue( value[index] );
4093  lineLength += int( childValues_[index].length() );
4094  isMultiLine = isMultiLine && hasCommentForValue( value[index] );
4095  }
4096  addChildValues_ = false;
4097  isMultiLine = isMultiLine || lineLength >= rightMargin_;
4098  }
4099  return isMultiLine;
4100 }
4101 
4102 
4103 void
4104 StyledStreamWriter::pushValue( const std::string &value )
4105 {
4106  if ( addChildValues_ )
4107  childValues_.push_back( value );
4108  else
4109  *document_ << value;
4110 }
4111 
4112 
4113 void
4114 StyledStreamWriter::writeIndent()
4115 {
4116  /*
4117  Some comments in this method would have been nice. ;-)
4118 
4119  if ( !document_.empty() )
4120  {
4121  char last = document_[document_.length()-1];
4122  if ( last == ' ' ) // already indented
4123  return;
4124  if ( last != '\n' ) // Comments may add new-line
4125  *document_ << '\n';
4126  }
4127  */
4128  *document_ << '\n' << indentString_;
4129 }
4130 
4131 
4132 void
4133 StyledStreamWriter::writeWithIndent( const std::string &value )
4134 {
4135  writeIndent();
4136  *document_ << value;
4137 }
4138 
4139 
4140 void
4141 StyledStreamWriter::indent()
4142 {
4143  indentString_ += indentation_;
4144 }
4145 
4146 
4147 void
4148 StyledStreamWriter::unindent()
4149 {
4150  assert( indentString_.size() >= indentation_.size() );
4151  indentString_.resize( indentString_.size() - indentation_.size() );
4152 }
4153 
4154 
4155 void
4156 StyledStreamWriter::writeCommentBeforeValue( const Value &root )
4157 {
4158  if ( !root.hasComment( commentBefore ) )
4159  return;
4160  *document_ << normalizeEOL( root.getComment( commentBefore ) );
4161  *document_ << "\n";
4162 }
4163 
4164 
4165 void
4166 StyledStreamWriter::writeCommentAfterValueOnSameLine( const Value &root )
4167 {
4168  if ( root.hasComment( commentAfterOnSameLine ) )
4169  *document_ << " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
4170 
4171  if ( root.hasComment( commentAfter ) )
4172  {
4173  *document_ << "\n";
4174  *document_ << normalizeEOL( root.getComment( commentAfter ) );
4175  *document_ << "\n";
4176  }
4177 }
4178 
4179 
4180 bool
4181 StyledStreamWriter::hasCommentForValue( const Value &value )
4182 {
4183  return value.hasComment( commentBefore )
4185  || value.hasComment( commentAfter );
4186 }
4187 
4188 
4189 std::string
4190 StyledStreamWriter::normalizeEOL( const std::string &text )
4191 {
4192  std::string normalized;
4193  normalized.reserve( text.length() );
4194  const char *begin = text.c_str();
4195  const char *end = begin + text.length();
4196  const char *current = begin;
4197  while ( current != end )
4198  {
4199  char c = *current++;
4200  if ( c == '\r' ) // mac or dos EOL
4201  {
4202  if ( *current == '\n' ) // convert dos EOL
4203  ++current;
4204  normalized += '\n';
4205  }
4206  else // handle unix EOL & other char
4207  normalized += c;
4208  }
4209  return normalized;
4210 }
4211 
4212 
4213 std::ostream& operator<<( std::ostream &sout, const Value &root )
4214 {
4215  Json::StyledStreamWriter writer;
4216  writer.write(sout, root);
4217  return sout;
4218 }
4219 
4220 
4221 } // namespace Json
4222 
4223 // //////////////////////////////////////////////////////////////////////
4224 // End of content of file: src/lib_json/json_writer.cpp
4225 // //////////////////////////////////////////////////////////////////////
#define JSON_FAIL_MESSAGE(message)
Definition: jsoncpp.cpp:1565
Value & operator[](ArrayIndex index)
Definition: jsoncpp.cpp:2610
unsigned int UInt
Definition: jsoncpp.h:159
unsigned integer value
Definition: jsoncpp.h:349
bool operator>(const Value &other) const
Definition: jsoncpp.cpp:2134
std::vector< std::string > Members
Definition: jsoncpp.h:441
static char * line
Definition: svm.cpp:2870
double value
Definition: jsoncpp.h:350
Value get(ArrayIndex index, const Value &defaultValue) const
Definition: jsoncpp.cpp:2697
Value(ValueType type=nullValue)
Create a default Value of the given type.
Definition: jsoncpp.cpp:1776
std::string valueToQuotedString(const char *value)
Definition: jsoncpp.cpp:3503
void clear()
Definition: jsoncpp.cpp:2559
ValueIterator iterator
Definition: jsoncpp.h:442
std::ostream & operator<<(std::ostream &sout, const Value &root)
Output using the StyledStreamWriter.
Definition: jsoncpp.cpp:4213
bool allowComments_
true if comments are allowed. Default: true.
Definition: jsoncpp.h:293
bool isConvertibleTo(ValueType other) const
Definition: jsoncpp.cpp:2454
const_iterator end() const
Definition: jsoncpp.cpp:3054
Writes a Value in JSON format in a human friendly way, to a stream rather than to a string...
Definition: jsoncpp.h:1789
Features()
Initialize the configuration like JsonConfig::allFeatures;.
Definition: jsoncpp.cpp:216
bool isEqual(const SelfType &other) const
Definition: jsoncpp.cpp:1358
Json::LargestInt LargestInt
Definition: jsoncpp.h:450
Value removeMember(const char *key)
Remove and return the named member.
Definition: jsoncpp.cpp:2792
signed integer value
Definition: jsoncpp.h:348
static const LargestUInt maxLargestUInt
Maximum unsigned integer value that can be stored in a Json::Value.
Definition: jsoncpp.h:460
const char * c_str() const
Definition: jsoncpp.h:397
std::string getComment(CommentPlacement placement) const
Include delimiters and embedded newlines.
Definition: jsoncpp.cpp:3002
bool operator!=(const Value &other) const
Definition: jsoncpp.cpp:2184
UInt64 LargestUInt
Definition: jsoncpp.h:174
static const LargestInt minLargestInt
Minimum signed integer value that can be stored in a Json::Value.
Definition: jsoncpp.h:456
double asDouble() const
Definition: jsoncpp.cpp:2370
Json::Int Int
Definition: jsoncpp.h:445
std::string getFormatedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
Definition: jsoncpp.cpp:1035
Value key() const
Return either the index or the member name of the referenced value as a Value.
Definition: jsoncpp.cpp:1388
std::string write(const Value &root) override
Definition: jsoncpp.cpp:3590
Experimental and untested: represents an element of the "path" to access a node.
Definition: jsoncpp.h:819
Json::ArrayIndex ArrayIndex
Definition: jsoncpp.h:452
Int64 asInt64() const
Lightweight wrapper to tag static string.
Definition: jsoncpp.h:384
static const unsigned int unknown
Unknown size marker.
Definition: jsoncpp.cpp:1583
ValueConstIterator const_iterator
Definition: jsoncpp.h:443
friend class Value
Definition: jsoncpp.h:1358
bool operator<(const StaticParameterMap::ValueType &a, const StaticParameterMap::ValueType &b)
Compares two var lists and returns true if the first list&#39;s first item is lower than the second one&#39;s...
bool isNull() const
Definition: jsoncpp.cpp:2906
bool operator!() const
Return isNull()
Definition: jsoncpp.cpp:2552
unsigned int ArrayIndex
Definition: jsoncpp.h:217
bool isValidIndex(ArrayIndex index) const
Return true if index < size().
Definition: jsoncpp.cpp:2706
bool parse(const std::string &document, Value &root, bool collectComments=true)
Read a Value from a JSON document.
Definition: jsoncpp.cpp:283
std::string asString() const
Definition: jsoncpp.cpp:2198
static const UInt maxUInt
Maximum unsigned int value that can be stored in a Json::Value.
Definition: jsoncpp.h:467
Represents a JSON value.
Definition: jsoncpp.h:433
Json::Int64 Int64
Definition: jsoncpp.h:448
void setComment(const char *comment, CommentPlacement placement)
Comments must be //... or /* ... */.
Definition: jsoncpp.cpp:2978
UInt64 asUInt64() const
Configuration passed to reader and writer. This configuration object can be used to force the Reader ...
Definition: jsoncpp.h:271
const Value & resolve(const Value &root) const
Definition: jsoncpp.cpp:3283
a comment placed on the line before a value
Definition: jsoncpp.h:359
static const UInt64 maxUInt64
Maximum unsigned 64 bits int value that can be stored in a Json::Value.
Definition: jsoncpp.h:474
bool asBool() const
Definition: jsoncpp.cpp:2428
static const Int64 maxInt64
Maximum signed 64 bits int value that can be stored in a Json::Value.
Definition: jsoncpp.h:472
MITKCORE_EXPORT bool operator==(const InteractionEvent &a, const InteractionEvent &b)
SelfType & operator=(const ValueIteratorBase &other)
Definition: jsoncpp.cpp:1472
long long int Int64
Definition: jsoncpp.h:170
bool isIntegral() const
Definition: jsoncpp.cpp:2934
static void info(const char *fmt,...)
Definition: svm.cpp:86
void enableYAMLCompatibility()
Definition: jsoncpp.cpp:3583
Value & make(Value &root) const
Creates the "path" to access the specified node and returns a reference on the node.
Definition: jsoncpp.cpp:3342
bool operator>=(const Value &other) const
Definition: jsoncpp.cpp:2128
#define JSON_ASSERT_MESSAGE(condition, message)
Definition: jsoncpp.cpp:1566
static std::string codePointToUTF8(unsigned int cp)
Converts a unicode code-point to UTF-8.
Definition: jsoncpp.cpp:101
static const Int minInt
Minimum signed int value that can be stored in a Json::Value.
Definition: jsoncpp.h:463
void resize(ArrayIndex size)
Definition: jsoncpp.cpp:2584
Value & operator=(const Value &other)
Definition: jsoncpp.cpp:2040
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: jsoncpp.cpp:2833
Int64 LargestInt
Definition: jsoncpp.h:173
static const Value null
Definition: jsoncpp.h:454
static bool isControlCharacter(char ch)
Returns true if ch is a control character (in range [0,32[).
Definition: jsoncpp.cpp:140
std::map< CZString, Value > ObjectValues
Definition: jsoncpp.h:506
static const Int64 minInt64
Minimum signed 64 bits int value that can be stored in a Json::Value.
Definition: jsoncpp.h:470
Reader()
Constructs a Reader allowing all features for parsing.
Definition: jsoncpp.cpp:270
bool hasComment(CommentPlacement placement) const
Definition: jsoncpp.cpp:2996
bool isDouble() const
Definition: jsoncpp.cpp:2943
Json::UInt UInt
Definition: jsoncpp.h:444
bool isInt() const
Definition: jsoncpp.cpp:2920
static void uintToString(LargestUInt value, char *&current)
Definition: jsoncpp.cpp:161
object value (collection of name/value pairs).
Definition: jsoncpp.h:354
static Features all()
A configuration that allows all features and assumes all strings are UTF-8.
Definition: jsoncpp.cpp:224
bool value
Definition: jsoncpp.h:352
Constant that specify the size of the buffer that must be passed to uintToString. ...
Definition: jsoncpp.cpp:148
Json::LargestUInt LargestUInt
Definition: jsoncpp.h:451
bool isNumeric() const
Definition: jsoncpp.cpp:2950
UInt asUInt() const
Definition: jsoncpp.cpp:2259
void swap(Value &other)
Definition: jsoncpp.cpp:2048
char UIntToStringBuffer[uintToStringBufferSize]
Definition: jsoncpp.cpp:152
ValueType
Type of the value held by a Value object.
Definition: jsoncpp.h:345
std::string toStyledString() const
Definition: jsoncpp.cpp:3011
#define JSON_ASSERT(condition)
Definition: jsoncpp.cpp:1564
JSON (JavaScript Object Notation).
Definition: jsoncpp.cpp:97
a comment just after a value on the same line
Definition: jsoncpp.h:360
static void releaseStringValue(char *value)
Definition: jsoncpp.cpp:1610
Value & deref() const
Definition: jsoncpp.cpp:1282
static bool containsControlCharacter(const char *str)
Definition: jsoncpp.cpp:3407
std::istream & operator>>(std::istream &sin, Value &root)
Read from &#39;sin&#39; into &#39;root&#39;.
Definition: jsoncpp.cpp:1059
Json::UInt64 UInt64
Definition: jsoncpp.h:447
base class for Value iterators.
Definition: jsoncpp.h:1228
#define JSON_ASSERT_UNREACHABLE
Definition: jsoncpp.cpp:1563
CommentPlacement
Definition: jsoncpp.h:357
virtual ~Writer()
Definition: jsoncpp.cpp:3568
bool isString() const
Definition: jsoncpp.cpp:2957
std::string valueToString(LargestInt value)
Definition: jsoncpp.cpp:3418
UInt index() const
Return the index of the referenced Value. -1 if it is not an arrayValue.
Definition: jsoncpp.cpp:1412
int Int
Definition: jsoncpp.h:158
Path(const std::string &path, const PathArgument &a1=PathArgument(), const PathArgument &a2=PathArgument(), const PathArgument &a3=PathArgument(), const PathArgument &a4=PathArgument(), const PathArgument &a5=PathArgument())
Definition: jsoncpp.cpp:3192
ArrayIndex size() const
Number of values in array or object.
Definition: jsoncpp.cpp:2506
a comment on the line after a value (only make sense for root value)
Definition: jsoncpp.h:361
void copy(const SelfType &other)
Definition: jsoncpp.cpp:1375
&#39;null&#39; value
Definition: jsoncpp.h:347
float asFloat() const
Definition: jsoncpp.cpp:2399
bool equals(const mitk::ScalarType &val1, const mitk::ScalarType &val2, mitk::ScalarType epsilon=mitk::eps)
LargestInt asLargestInt() const
Definition: jsoncpp.cpp:2348
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
Definition: jsoncpp.cpp:244
Int asInt() const
Definition: jsoncpp.cpp:2230
SelfType & operator=(const SelfType &other)
Definition: jsoncpp.cpp:1520
UTF-8 string value.
Definition: jsoncpp.h:351
std::string write(const Value &root) override
Serialize a Value in JSON format.
Definition: jsoncpp.cpp:3669
static const Int maxInt
Maximum signed int value that can be stored in a Json::Value.
Definition: jsoncpp.h:465
bool operator<=(const Value &other) const
Definition: jsoncpp.cpp:2122
bool empty() const
Return true if empty array, empty object, or null; otherwise, false.
Definition: jsoncpp.cpp:2542
void write(std::ostream &out, const Value &root)
Serialize a Value in JSON format.
Definition: jsoncpp.cpp:3945
static void swap(T &x, T &y)
Definition: svm.cpp:58
static Features strictMode()
A configuration that is strictly compatible with the JSON specification.
Definition: jsoncpp.cpp:231
difference_type computeDistance(const SelfType &other) const
Definition: jsoncpp.cpp:1321
LargestUInt asLargestUInt() const
Definition: jsoncpp.cpp:2359
Unserialize a JSON document into a Value.
Definition: jsoncpp.h:1455
unsigned long long int UInt64
Definition: jsoncpp.h:171
ValueType type() const
Definition: jsoncpp.cpp:2060
static const LargestInt maxLargestInt
Maximum signed integer value that can be stored in a Json::Value.
Definition: jsoncpp.h:458
bool isBool() const
Definition: jsoncpp.cpp:2913
static bool containsNewLine(Reader::Location begin, Reader::Location end)
Definition: jsoncpp.cpp:257
static char * duplicateStringValue(const char *value, unsigned int length=unknown)
Definition: jsoncpp.cpp:1594
Iterator for object and array value.
Definition: jsoncpp.h:1356
int compare(const Value &other) const
Definition: jsoncpp.cpp:2067
Members getMemberNames() const
Return a list of the member names.
Definition: jsoncpp.cpp:2856
bool operator<(const Value &other) const
Definition: jsoncpp.cpp:2078
const Char * Location
Definition: jsoncpp.h:1459
bool isUInt() const
Definition: jsoncpp.cpp:2927
bool isArray() const
Definition: jsoncpp.cpp:2964
Writes a Value in JSON format in a human friendly way.
Definition: jsoncpp.h:1732
bool isObject() const
Definition: jsoncpp.cpp:2971
const char * memberName() const
Return the member name of the referenced Value. "" if it is not an objectValue.
Definition: jsoncpp.cpp:1428
const char * asCString() const
Definition: jsoncpp.cpp:2190
StyledStreamWriter(std::string indentation="\)
Definition: jsoncpp.cpp:3936
bool strictRoot_
true if root must be either an array or an object value. Default: false.
Definition: jsoncpp.h:296
Value & append(const Value &value)
Append value to array at the end.
Definition: jsoncpp.cpp:2769
std::string getFormattedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
Definition: jsoncpp.cpp:1042
bool operator==(const Value &other) const
Definition: jsoncpp.cpp:2140
const iterator for object and array value.
Definition: jsoncpp.h:1298
array value (ordered list)
Definition: jsoncpp.h:353
const_iterator begin() const
Definition: jsoncpp.cpp:3019