88 #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED 89 # define LIB_JSONCPP_JSON_TOOL_H_INCLUDED 100 static inline std::string
110 result[0] =
static_cast<char>(cp);
112 else if (cp <= 0x7FF)
115 result[1] =
static_cast<char>(0x80 | (0x3f & cp));
116 result[0] =
static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
118 else if (cp <= 0xFFFF)
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)));
125 else if (cp <= 0x10FFFF)
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)));
142 return ch > 0 && ch <= 0x1F;
167 *--current = char(value % 10) +
'0';
170 while ( value != 0 );
175 #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED 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) 207 #if _MSC_VER >= 1400 // VC++ 8.0 208 #pragma warning( disable : 4996 ) // disable warning about strdup being deprecated. 217 : allowComments_( true )
218 , strictRoot_( false )
246 return c == c1 || c == c2 || c == c3 || c == c4;
252 return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
260 for ( ;begin < end; ++begin )
261 if ( *begin ==
'\n' || *begin ==
'\r' )
277 : features_( features )
285 bool collectComments )
287 document_ = document;
288 const char *begin = document_.c_str();
289 const char *end = begin + document_.length();
290 return parse( begin, end, root, collectComments );
297 bool collectComments )
307 std::getline(sin, doc, static_cast<char>(EOF));
308 return parse( doc, root, collectComments );
314 bool collectComments )
318 collectComments =
false;
323 collectComments_ = collectComments;
325 lastValueEnd_ =
nullptr;
326 lastValue_ =
nullptr;
327 commentsBefore_ =
"";
329 while ( !nodes_.empty() )
331 nodes_.push( &root );
333 bool successful = readValue();
335 skipCommentTokens( token );
336 if ( collectComments_ && !commentsBefore_.empty() )
343 token.type_ = tokenError;
344 token.start_ = beginDoc;
346 addError(
"A valid JSON document must be either an array or an object value.",
359 skipCommentTokens( token );
360 bool successful =
true;
362 if ( collectComments_ && !commentsBefore_.empty() )
365 commentsBefore_ =
"";
369 switch ( token.type_ )
371 case tokenObjectBegin:
372 successful = readObject( token );
374 case tokenArrayBegin:
375 successful = readArray( token );
378 successful = decodeNumber( token );
381 successful = decodeString( token );
384 currentValue() =
true;
387 currentValue() =
false;
390 currentValue() =
Value();
393 return addError(
"Syntax error: value, object or array expected.", token );
396 if ( collectComments_ )
398 lastValueEnd_ = current_;
399 lastValue_ = ¤tValue();
407 Reader::skipCommentTokens( Token &token )
415 while ( token.type_ == tokenComment );
425 Reader::expectToken( TokenType type, Token &token,
const char *message )
428 if ( token.type_ != type )
429 return addError( message, token );
435 Reader::readToken( Token &token )
438 token.start_ = current_;
439 Char c = getNextChar();
444 token.type_ = tokenObjectBegin;
447 token.type_ = tokenObjectEnd;
450 token.type_ = tokenArrayBegin;
453 token.type_ = tokenArrayEnd;
456 token.type_ = tokenString;
460 token.type_ = tokenComment;
474 token.type_ = tokenNumber;
478 token.type_ = tokenTrue;
479 ok = match(
"rue", 3 );
482 token.type_ = tokenFalse;
483 ok = match(
"alse", 4 );
486 token.type_ = tokenNull;
487 ok = match(
"ull", 3 );
490 token.type_ = tokenArraySeparator;
493 token.type_ = tokenMemberSeparator;
496 token.type_ = tokenEndOfStream;
503 token.type_ = tokenError;
504 token.end_ = current_;
512 while ( current_ != end_ )
515 if ( c ==
' ' || c ==
'\t' || c ==
'\r' || c ==
'\n' )
527 if ( end_ - current_ < patternLength )
529 int index = patternLength;
531 if ( current_[index] != pattern[index] )
533 current_ += patternLength;
539 Reader::readComment()
541 Location commentBegin = current_ - 1;
542 Char c = getNextChar();
543 bool successful =
false;
545 successful = readCStyleComment();
547 successful = readCppStyleComment();
551 if ( collectComments_ )
554 if ( lastValueEnd_ && !
containsNewLine( lastValueEnd_, commentBegin ) )
560 addComment( commentBegin, current_, placement );
571 assert( collectComments_ );
574 assert( lastValue_ !=
nullptr );
575 lastValue_->
setComment( std::string( begin, end ), placement );
579 if ( !commentsBefore_.empty() )
580 commentsBefore_ +=
"\n";
581 commentsBefore_ += std::string( begin, end );
587 Reader::readCStyleComment()
589 while ( current_ != end_ )
591 Char c = getNextChar();
592 if ( c ==
'*' && *current_ ==
'/' )
595 return getNextChar() ==
'/';
600 Reader::readCppStyleComment()
602 while ( current_ != end_ )
604 Char c = getNextChar();
605 if ( c ==
'\r' || c ==
'\n' )
615 while ( current_ != end_ )
617 if ( !(*current_ >=
'0' && *current_ <=
'9') &&
618 !
in( *current_,
'.',
'e',
'E',
'+',
'-' ) )
628 while ( current_ != end_ )
641 Reader::readObject( Token & )
646 while ( readToken( tokenName ) )
648 bool initialTokenOk =
true;
649 while ( tokenName.type_ == tokenComment && initialTokenOk )
650 initialTokenOk = readToken( tokenName );
651 if ( !initialTokenOk )
653 if ( tokenName.type_ == tokenObjectEnd && name.empty() )
655 if ( tokenName.type_ != tokenString )
659 if ( !decodeString( tokenName, name ) )
660 return recoverFromError( tokenObjectEnd );
663 if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator )
665 return addErrorAndRecover(
"Missing ':' after object member name",
669 Value &value = currentValue()[ name ];
670 nodes_.push( &value );
671 bool ok = readValue();
674 return recoverFromError( tokenObjectEnd );
677 if ( !readToken( comma )
678 || ( comma.type_ != tokenObjectEnd &&
679 comma.type_ != tokenArraySeparator &&
680 comma.type_ != tokenComment ) )
682 return addErrorAndRecover(
"Missing ',' or '}' in object declaration",
686 bool finalizeTokenOk =
true;
687 while ( comma.type_ == tokenComment &&
689 finalizeTokenOk = readToken( comma );
690 if ( comma.type_ == tokenObjectEnd )
693 return addErrorAndRecover(
"Missing '}' or object member name",
700 Reader::readArray( Token & )
704 if ( *current_ ==
']' )
707 readToken( endArray );
713 Value &value = currentValue()[ index++ ];
714 nodes_.push( &value );
715 bool ok = readValue();
718 return recoverFromError( tokenArrayEnd );
722 ok = readToken( token );
723 while ( token.type_ == tokenComment && ok )
725 ok = readToken( token );
727 bool badTokenType = ( token.type_ != tokenArraySeparator &&
728 token.type_ != tokenArrayEnd );
729 if ( !ok || badTokenType )
731 return addErrorAndRecover(
"Missing ',' or ']' in array declaration",
735 if ( token.type_ == tokenArrayEnd )
743 Reader::decodeNumber( Token &token )
745 bool isDouble =
false;
746 for (
Location inspect = token.start_; inspect != token.end_; ++inspect )
749 ||
in( *inspect,
'.',
'e',
'E',
'+' )
750 || ( *inspect ==
'-' && inspect != token.start_ );
753 return decodeDouble( token );
758 bool isNegative = *current ==
'-';
763 Value::LargestUInt threshold = maxIntegerValue / 10;
765 assert( lastDigitThreshold <= 9 );
766 Value::LargestUInt value = 0;
767 while ( current < token.end_ )
770 if ( c < '0' || c >
'9' )
771 return addError(
"'" + std::string( token.start_, token.end_ ) +
"' is not a number.", token );
773 if ( value >= threshold )
778 if ( current != token.end_ || digit > lastDigitThreshold )
780 return decodeDouble( token );
783 value = value * 10 + digit;
790 currentValue() = value;
796 Reader::decodeDouble( Token &token )
799 const int bufferSize = 32;
801 int length = int(token.end_ - token.start_);
802 if ( length <= bufferSize )
804 Char buffer[bufferSize+1];
805 memcpy( buffer, token.start_, length );
807 count = sscanf( buffer,
"%lf", &value );
811 std::string buffer( token.start_, token.end_ );
812 count = sscanf( buffer.c_str(),
"%lf", &value );
816 return addError(
"'" + std::string( token.start_, token.end_ ) +
"' is not a number.", token );
817 currentValue() = value;
823 Reader::decodeString( Token &token )
826 if ( !decodeString( token, decoded ) )
828 currentValue() = decoded;
834 Reader::decodeString( Token &token, std::string &decoded )
836 decoded.reserve( token.end_ - token.start_ - 2 );
837 Location current = token.start_ + 1;
839 while ( current != end )
844 else if ( c ==
'\\' )
846 if ( current == end )
847 return addError(
"Empty escape sequence in string", token, current );
848 Char escape = *current++;
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;
861 unsigned int unicode;
862 if ( !decodeUnicodeCodePoint( token, current, end, unicode ) )
868 return addError(
"Bad escape sequence in string", token, current );
880 Reader::decodeUnicodeCodePoint( Token &token,
883 unsigned int &unicode )
886 if ( !decodeUnicodeEscapeSequence( token, current, end, unicode ) )
888 if (unicode >= 0xD800 && unicode <= 0xDBFF)
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')
896 if (decodeUnicodeEscapeSequence( token, current, end, surrogatePair ))
898 unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
904 return addError(
"expecting another \\u token to begin the second half of a unicode surrogate pair", token, current );
910 Reader::decodeUnicodeEscapeSequence( Token &token,
913 unsigned int &unicode )
915 if ( end - current < 4 )
916 return addError(
"Bad unicode escape sequence in string: four digits expected.", token, current );
918 for (
int index =0; index < 4; ++index )
922 if ( c >=
'0' && c <=
'9' )
924 else if ( c >=
'a' && c <=
'f' )
925 unicode += c -
'a' + 10;
926 else if ( c >=
'A' && c <=
'F' )
927 unicode += c -
'A' + 10;
929 return addError(
"Bad unicode escape sequence in string: hexadecimal digit expected.", token, current );
936 Reader::addError(
const std::string &message,
942 info.message_ = message;
944 errors_.push_back( info );
950 Reader::recoverFromError( TokenType skipUntilToken )
952 int errorCount = int(errors_.size());
956 if ( !readToken(skip) )
957 errors_.resize( errorCount );
958 if ( skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream )
961 errors_.resize( errorCount );
967 Reader::addErrorAndRecover(
const std::string &message,
969 TokenType skipUntilToken )
971 addError( message, token );
972 return recoverFromError( skipUntilToken );
977 Reader::currentValue()
979 return *(nodes_.top());
984 Reader::getNextChar()
986 if ( current_ == end_ )
993 Reader::getLocationLineAndColumn(
Location location,
1000 while ( current < location && current != end_ )
1002 Char c = *current++;
1005 if ( *current ==
'\n' )
1007 lastLineStart = current;
1010 else if ( c ==
'\n' )
1012 lastLineStart = current;
1017 column = int(location - lastLineStart) + 1;
1023 Reader::getLocationLineAndColumn(
Location location )
const 1026 getLocationLineAndColumn( location, line, column );
1027 char buffer[18+16+16+1];
1028 sprintf( buffer,
"Line %d, Column %d", line, column );
1044 std::string formattedMessage;
1045 for ( Errors::const_iterator itError = errors_.begin();
1046 itError != errors_.end();
1049 const ErrorInfo &error = *itError;
1050 formattedMessage +=
"* " + getLocationLineAndColumn( error.token_.start_ ) +
"\n";
1051 formattedMessage +=
" " + error.message_ +
"\n";
1053 formattedMessage +=
"See " + getLocationLineAndColumn( error.extra_ ) +
" for detail.\n";
1055 return formattedMessage;
1062 bool ok = reader.
parse(sin, root,
true);
1089 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED 1090 # define JSONCPP_BATCHALLOCATOR_H_INCLUDED 1092 # include <stdlib.h> 1093 # include <assert.h> 1095 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION 1111 template<
typename AllocatedType
1112 ,
const unsigned int objectPerAllocation>
1113 class BatchAllocator
1116 typedef AllocatedType Type;
1118 BatchAllocator(
unsigned int objectsPerPage = 255 )
1120 , objectsPerPage_( objectsPerPage )
1123 assert(
sizeof(AllocatedType) * objectPerAllocation >=
sizeof(AllocatedType *) );
1124 assert( objectsPerPage >= 16 );
1125 batches_ = allocateBatch( 0 );
1126 currentBatch_ = batches_;
1131 for ( BatchInfo *batch = batches_; batch; )
1133 BatchInfo *nextBatch = batch->next_;
1141 AllocatedType *allocate()
1145 AllocatedType *
object = freeHead_;
1146 freeHead_ = *
static_cast<AllocatedType **
>(object);
1149 if ( currentBatch_->used_ == currentBatch_->end_ )
1151 currentBatch_ = currentBatch_->next_;
1152 while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
1153 currentBatch_ = currentBatch_->next_;
1155 if ( !currentBatch_ )
1157 currentBatch_ = allocateBatch( objectsPerPage_ );
1158 currentBatch_->next_ = batches_;
1159 batches_ = currentBatch_;
1162 AllocatedType *allocated = currentBatch_->used_;
1163 currentBatch_->used_ += objectPerAllocation;
1169 void release( AllocatedType *
object )
1171 assert(
object != 0 );
1172 *
static_cast<AllocatedType **
>(object) = freeHead_;
1180 AllocatedType *used_;
1181 AllocatedType *end_;
1182 AllocatedType buffer_[objectPerAllocation];
1186 BatchAllocator(
const BatchAllocator & );
1187 void operator =(
const BatchAllocator &);
1189 static BatchInfo *allocateBatch(
unsigned int objectsPerPage )
1191 const unsigned int mallocSize =
sizeof(BatchInfo) -
sizeof(AllocatedType)* objectPerAllocation
1192 +
sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
1193 BatchInfo *batch =
static_cast<BatchInfo*
>( malloc( mallocSize ) );
1195 batch->used_ = batch->buffer_;
1196 batch->end_ = batch->buffer_ + objectsPerPage;
1200 BatchInfo *batches_;
1201 BatchInfo *currentBatch_;
1203 AllocatedType *freeHead_;
1204 unsigned int objectsPerPage_;
1210 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION 1212 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED 1246 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1255 iterator_.array_ = ValueInternalArray::IteratorState();
1260 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1262 : current_( current )
1270 iterator_.array_ = state;
1277 iterator_.map_ = state;
1284 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1285 return current_->second;
1288 return ValueInternalArray::dereference( iterator_.array_ );
1289 return ValueInternalMap::value( iterator_.map_ );
1297 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1301 ValueInternalArray::increment( iterator_.array_ );
1302 ValueInternalMap::increment( iterator_.map_ );
1310 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1314 ValueInternalArray::decrement( iterator_.array_ );
1315 ValueInternalMap::decrement( iterator_.map_ );
1323 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1324 # ifdef JSON_USE_CPPTL_SMALLMAP 1325 return current_ - other.current_;
1332 if ( isNull_ && other.isNull_ )
1343 for ( Value::ObjectValues::iterator it = current_; it != other.current_; ++it )
1351 return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ );
1352 return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ );
1360 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1363 return other.isNull_;
1365 return current_ == other.current_;
1377 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1378 current_ = other.current_;
1381 iterator_.array_ = other.iterator_.array_;
1382 iterator_.map_ = other.iterator_.map_;
1390 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1391 const Value::CZString czstring = (*current_).first;
1392 if ( czstring.c_str() )
1394 if ( czstring.isStaticString() )
1396 return Value( czstring.c_str() );
1398 return Value( czstring.index() );
1401 return Value( ValueInternalArray::indexOf( iterator_.array_ ) );
1403 const char *
memberName = ValueInternalMap::key( iterator_.map_, isStatic );
1406 return Value( memberName );
1414 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1415 const Value::CZString czstring = (*current_).first;
1416 if ( !czstring.c_str() )
1417 return czstring.index();
1421 return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) );
1430 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1431 const char *name = (*current_).first.c_str();
1432 return name ? name :
"";
1435 return ValueInternalMap::key( iterator_.map_ );
1454 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1492 #ifndef JSON_VALUE_USE_INTERNAL_MAP 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) 1555 #include <stdexcept> 1558 #ifdef JSON_USE_CPPTL 1559 # include <cpptl/conststring.h> 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 ) 1593 static inline char *
1595 unsigned int length = unknown )
1597 if ( length == unknown )
1598 length =
static_cast<unsigned int>(strlen(value));
1599 char *newString =
static_cast<char *
>( malloc( length + 1 ) );
1601 memcpy( newString, value, length );
1602 newString[length] = 0;
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 1632 # include "json_valueiterator.inl" 1633 #endif // if !defined(JSON_IS_AMALGAMATION) 1646 Value::CommentInfo::CommentInfo()
1647 : comment_(
nullptr )
1651 Value::CommentInfo::~CommentInfo()
1659 Value::CommentInfo::setComment(
const char *text )
1677 # ifndef JSON_VALUE_USE_INTERNAL_MAP 1688 Value::CZString::CZString(
const char *cstr, DuplicationPolicy allocate )
1691 , index_( allocate )
1695 Value::CZString::CZString(
const CZString &other )
1696 : cstr_( other.index_ != noDuplication && other.cstr_ !=
nullptr 1699 , index_( other.cstr_ ? (other.index_ == noDuplication ? static_cast<ArrayIndex>(noDuplication) : static_cast<ArrayIndex>(duplicate))
1704 Value::CZString::~CZString()
1706 if ( cstr_ && index_ == duplicate )
1718 Value::CZString::operator =(
const CZString &other )
1720 CZString temp( other );
1729 return strcmp( cstr_, other.cstr_ ) < 0;
1730 return index_ < other.index_;
1737 return strcmp( cstr_, other.cstr_ ) == 0;
1738 return index_ == other.index_;
1743 Value::CZString::index()
const 1750 Value::CZString::c_str()
const 1756 Value::CZString::isStaticString()
const 1758 return index_ == noDuplication;
1761 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP 1779 , comments_( nullptr )
1780 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1796 value_.string_ =
nullptr;
1798 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1805 value_.array_ = arrayAllocator()->newArray();
1808 value_.map_ = mapAllocator()->newMap();
1812 value_.bool_ =
false;
1820 #if defined(JSON_HAS_INT64) 1823 , comments_(
nullptr )
1824 # ifdef JSON_VALUE_USE_INTERNAL_MAP 1828 value_.uint_ = value;
1833 , comments_(
nullptr )
1834 # ifdef JSON_VALUE_USE_INTERNAL_MAP 1838 value_.int_ = value;
1841 #endif // if defined(JSON_HAS_INT64) 1846 , comments_( nullptr )
1847 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1851 value_.int_ = value;
1857 , comments_( nullptr )
1858 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1862 value_.uint_ = value;
1867 , comments_( nullptr )
1868 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1872 value_.real_ = value;
1877 , allocated_( true )
1878 , comments_( nullptr )
1879 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1888 const char *endValue )
1890 , allocated_( true )
1891 , comments_( nullptr )
1892 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1897 static_cast<unsigned int>(endValue - beginValue) );
1903 , allocated_( true )
1904 , comments_( nullptr )
1905 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1910 static_cast<unsigned int>(value.length()) );
1916 , allocated_( false )
1917 , comments_( nullptr )
1918 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1922 value_.string_ =
const_cast<char *
>( value.
c_str() );
1926 # ifdef JSON_USE_CPPTL 1929 , allocated_(
true )
1931 # ifdef JSON_VALUE_USE_INTERNAL_MAP 1941 , comments_( nullptr )
1942 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1946 value_.bool_ = value;
1951 : type_( other.type_ )
1952 , comments_( nullptr )
1953 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1964 value_ = other.value_;
1967 if ( other.value_.string_ )
1973 value_.string_ =
nullptr;
1975 #ifndef JSON_VALUE_USE_INTERNAL_MAP 1982 value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ );
1985 value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ );
1991 if ( other.comments_ )
1996 const CommentInfo &otherComment = other.comments_[comment];
1997 if ( otherComment.comment_ )
1998 comments_[comment].setComment( otherComment.comment_ );
2018 #ifndef JSON_VALUE_USE_INTERNAL_MAP 2025 arrayAllocator()->destructArray( value_.array_ );
2028 mapAllocator()->destructMap( value_.map_ );
2042 Value temp( other );
2051 type_ = other.type_;
2054 int temp2 = allocated_;
2055 allocated_ = other.allocated_;
2056 other.allocated_ = temp2;
2069 if ( *
this < other )
2071 if ( *
this > other )
2080 int typeDelta = type_ - other.type_;
2082 return typeDelta < 0 ? true :
false;
2088 return value_.int_ < other.value_.int_;
2090 return value_.uint_ < other.value_.uint_;
2092 return value_.real_ < other.value_.real_;
2094 return value_.bool_ < other.value_.bool_;
2096 return ( value_.string_ ==
nullptr && other.value_.string_ )
2097 || ( other.value_.string_
2099 && strcmp( value_.string_, other.value_.string_ ) < 0 );
2100 #ifndef JSON_VALUE_USE_INTERNAL_MAP 2104 int delta = int( value_.map_->size() - other.value_.map_->size() );
2107 return (*value_.map_) < (*other.value_.map_);
2111 return value_.array_->compare( *(other.value_.array_) ) < 0;
2113 return value_.map_->compare( *(other.value_.map_) ) < 0;
2124 return !(other < *
this);
2130 return !(*
this < other);
2136 return other < *
this;
2146 int temp = other.type_;
2147 if ( type_ != temp )
2154 return value_.int_ == other.value_.int_;
2156 return value_.uint_ == other.value_.uint_;
2158 return value_.real_ == other.value_.real_;
2160 return value_.bool_ == other.value_.bool_;
2162 return ( value_.string_ == other.value_.string_ )
2163 || ( other.value_.string_
2165 && strcmp( value_.string_, other.value_.string_ ) == 0 );
2166 #ifndef JSON_VALUE_USE_INTERNAL_MAP 2169 return value_.map_->size() == other.value_.map_->size()
2170 && (*value_.map_) == (*other.value_.map_);
2173 return value_.array_->compare( *(other.value_.array_) ) == 0;
2175 return value_.map_->compare( *(other.value_.map_) ) == 0;
2186 return !( *
this == other );
2193 return value_.string_;
2205 return value_.string_ ? value_.string_ :
"";
2207 return value_.bool_ ?
"true" :
"false";
2220 # ifdef JSON_USE_CPPTL 2222 Value::asConstString()
const 2224 return CppTL::ConstString(
asString().c_str() );
2238 return Int(value_.int_);
2241 return Int(value_.uint_);
2244 return Int( value_.real_ );
2246 return value_.bool_ ? 1 : 0;
2266 JSON_ASSERT_MESSAGE( value_.int_ >= 0,
"Negative integer can not be converted to unsigned integer" );
2268 return UInt(value_.int_);
2271 return UInt(value_.uint_);
2274 return UInt( value_.real_ );
2276 return value_.bool_ ? 1 : 0;
2288 # if defined(JSON_HAS_INT64) 2301 return value_.uint_;
2304 return Int( value_.real_ );
2306 return value_.bool_ ? 1 : 0;
2326 JSON_ASSERT_MESSAGE( value_.int_ >= 0,
"Negative integer can not be converted to UInt64" );
2329 return value_.uint_;
2332 return UInt( value_.real_ );
2334 return value_.bool_ ? 1 : 0;
2344 # endif // if defined(JSON_HAS_INT64) 2350 #if defined(JSON_NO_INT64) 2361 #if defined(JSON_NO_INT64) 2377 return static_cast<double>( value_.int_ );
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) 2385 return value_.real_;
2387 return value_.bool_ ? 1.0 : 0.0;
2406 return static_cast<float>( value_.int_ );
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) 2414 return static_cast<float>( value_.real_ );
2416 return value_.bool_ ? 1.0f : 0.0f;
2436 return value_.int_ != 0;
2438 return value_.real_ != 0.0;
2440 return value_.bool_;
2442 return value_.string_ && value_.string_[0] != 0;
2445 return value_.map_->size() != 0;
2461 return ( other ==
nullValue && value_.int_ == 0 )
2463 || ( other ==
uintValue && value_.int_ >= 0 )
2468 return ( other ==
nullValue && value_.uint_ == 0 )
2469 || ( other ==
intValue && value_.uint_ <=
static_cast<unsigned>(
maxInt) )
2475 return ( other ==
nullValue && value_.real_ == 0.0 )
2482 return ( other ==
nullValue && value_.bool_ ==
false )
2490 || ( other ==
nullValue && (!value_.string_ || value_.string_[0] == 0) );
2493 || ( other ==
nullValue && value_.map_->size() == 0 );
2496 || ( other ==
nullValue && value_.map_->size() == 0 );
2517 #ifndef JSON_VALUE_USE_INTERNAL_MAP 2519 if ( !value_.map_->empty() )
2521 ObjectValues::const_iterator itLast = value_.map_->end();
2523 return (*itLast).first.index()+1;
2530 return Int( value_.array_->size() );
2532 return Int( value_.map_->size() );
2545 return size() == 0u;
2565 #ifndef JSON_VALUE_USE_INTERNAL_MAP 2568 value_.map_->clear();
2572 value_.array_->clear();
2575 value_.map_->clear();
2589 #ifndef JSON_VALUE_USE_INTERNAL_MAP 2593 else if ( newSize > oldSize )
2594 (*this)[ newSize - 1 ];
2597 for (
ArrayIndex index = newSize; index < oldSize; ++index )
2599 value_.map_->erase( index );
2601 assert(
size() == newSize );
2604 value_.array_->resize( newSize );
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;
2621 ObjectValues::value_type defaultValue( key,
null );
2622 it = value_.map_->insert( it, defaultValue );
2623 return (*it).second;
2625 return value_.array_->resolveReference( index );
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() )
2649 return (*it).second;
2651 Value *value = value_.array_->find( index );
2652 return value ? *value :
null;
2668 return resolveReference( key,
false );
2673 Value::resolveReference(
const char *key,
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;
2686 ObjectValues::value_type defaultValue( actualKey,
null );
2687 it = value_.map_->insert( it, defaultValue );
2688 Value &value = (*it).second;
2691 return value_.map_->resolveReference( key, isStatic );
2698 const Value &defaultValue )
const 2700 const Value *value = &((*this)[index]);
2701 return value == &
null ? defaultValue : *value;
2708 return index <
size();
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() )
2724 return (*it).second;
2726 const Value *value = value_.map_->find( key );
2727 return value ? *value :
null;
2735 return (*
this)[ key.c_str() ];
2742 return (*
this)[ key.c_str() ];
2748 return resolveReference( key,
true );
2752 # ifdef JSON_USE_CPPTL 2756 return (*
this)[ key.c_str() ];
2763 return (*
this)[ key.c_str() ];
2771 return (*
this)[
size()] = value;
2777 const Value &defaultValue )
const 2779 const Value *value = &((*this)[key]);
2780 return value == &
null ? defaultValue : *value;
2786 const Value &defaultValue )
const 2788 return get( key.c_str(), defaultValue );
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() )
2802 Value old(it->second);
2803 value_.map_->erase(it);
2806 Value *value = value_.map_->find( key );
2809 value_.map_.remove( key );
2823 # ifdef JSON_USE_CPPTL 2826 const Value &defaultValue )
const 2828 return get( key.c_str(), defaultValue );
2835 const Value *value = &((*this)[key]);
2836 return value != &
null;
2847 # ifdef JSON_USE_CPPTL 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() ) );
2869 ValueInternalMap::IteratorState it;
2870 ValueInternalMap::IteratorState itEnd;
2871 value_.map_->makeBeginIterator( it );
2872 value_.map_->makeEndIterator( itEnd );
2874 members.push_back( std::string( ValueInternalMap::key( it ) ) );
2983 comments_[placement].setComment( comment );
2998 return comments_ !=
nullptr && comments_[placement].comment_ !=
nullptr;
3005 return comments_[placement].comment_;
3014 return writer.
write( *
this );
3023 #ifdef JSON_VALUE_USE_INTERNAL_MAP 3025 if ( value_.array_ )
3027 ValueInternalArray::IteratorState it;
3028 value_.array_->makeBeginIterator( it );
3035 ValueInternalMap::IteratorState it;
3036 value_.map_->makeBeginIterator( it );
3058 #ifdef JSON_VALUE_USE_INTERNAL_MAP 3060 if ( value_.array_ )
3062 ValueInternalArray::IteratorState it;
3063 value_.array_->makeEndIterator( it );
3070 ValueInternalMap::IteratorState it;
3071 value_.map_->makeEndIterator( it );
3094 #ifdef JSON_VALUE_USE_INTERNAL_MAP 3096 if ( value_.array_ )
3098 ValueInternalArray::IteratorState it;
3099 value_.array_->makeBeginIterator( it );
3106 ValueInternalMap::IteratorState it;
3107 value_.map_->makeBeginIterator( it );
3115 return iterator( value_.map_->begin() );
3129 #ifdef JSON_VALUE_USE_INTERNAL_MAP 3131 if ( value_.array_ )
3133 ValueInternalArray::IteratorState it;
3134 value_.array_->makeEndIterator( it );
3141 ValueInternalMap::IteratorState it;
3142 value_.map_->makeEndIterator( it );
3150 return iterator( value_.map_->end() );
3171 , kind_( kindIndex )
3184 : key_( key.c_str() )
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 );
3210 Path::makePath(
const std::string &path,
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 )
3218 if ( *current ==
'[' )
3221 if ( *current ==
'%' )
3222 addPathInArg( path, in, itInArg, PathArgument::kindIndex );
3226 for ( ; current != end && *current >=
'0' && *current <=
'9'; ++current )
3227 index = index * 10 +
ArrayIndex(*current -
'0');
3228 args_.push_back( index );
3230 if ( current == end || *current++ !=
']' )
3231 invalidPath( path,
int(current - path.c_str()) );
3233 else if ( *current ==
'%' )
3235 addPathInArg( path, in, itInArg, PathArgument::kindKey );
3238 else if ( *current ==
'.' )
3244 const char *beginName = current;
3245 while ( current != end && !strchr(
"[.", *current ) )
3247 args_.push_back( std::string( beginName, current ) );
3254 Path::addPathInArg(
const std::string &,
3256 InArgs::const_iterator &itInArg,
3257 PathArgument::Kind kind )
3259 if ( itInArg == in.end() )
3263 else if ( (*itInArg)->kind_ != kind )
3269 args_.push_back( **itInArg );
3275 Path::invalidPath(
const std::string &,
3285 const Value *node = &root;
3286 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
3289 if ( arg.kind_ == PathArgument::kindIndex )
3295 node = &((*node)[arg.index_]);
3297 else if ( arg.kind_ == PathArgument::kindKey )
3303 node = &((*node)[arg.key_]);
3316 const Value &defaultValue )
const 3318 const Value *node = &root;
3319 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
3322 if ( arg.kind_ == PathArgument::kindIndex )
3325 return defaultValue;
3326 node = &((*node)[arg.index_]);
3328 else if ( arg.kind_ == PathArgument::kindKey )
3331 return defaultValue;
3332 node = &((*node)[arg.key_]);
3334 return defaultValue;
3344 Value *node = &root;
3345 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
3348 if ( arg.kind_ == PathArgument::kindIndex )
3354 node = &((*node)[arg.index_]);
3356 else if ( arg.kind_ == PathArgument::kindKey )
3362 node = &((*node)[arg.key_]);
3389 #if !defined(JSON_IS_AMALGAMATION) 3390 # include <json/writer.h> 3391 # include "json_tool.h" 3392 #endif // if !defined(JSON_IS_AMALGAMATION) 3401 #if _MSC_VER >= 1400 // VC++ 8.0 3402 #pragma warning( disable : 4996 ) // disable warning about strdup being deprecated. 3421 char *current = buffer +
sizeof(buffer);
3422 bool isNegative = value < 0;
3428 assert( current >= buffer );
3436 char *current = buffer +
sizeof(buffer);
3438 assert( current >= buffer );
3442 #if defined(JSON_HAS_INT64) 3455 #endif // # if defined(JSON_HAS_INT64) 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);
3464 sprintf(buffer,
"%#.16g", value);
3466 char* ch = buffer + strlen(buffer) - 1;
3467 if (*ch !=
'0')
return buffer;
3468 while(ch > buffer && *ch ==
'0'){
3471 char* last_nonzero = ch;
3472 while(ch >= buffer){
3488 *(last_nonzero+2) =
'\0';
3500 return value ?
"true" :
"false";
3507 return std::string(
"\"") + value +
"\"";
3511 std::string::size_type maxsize = strlen(value)*2 + 3;
3513 result.reserve(maxsize);
3515 for (
const char* c=value; *c != 0; ++c)
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();
3577 : yamlCompatiblityEnabled_( false )
3585 yamlCompatiblityEnabled_ =
true;
3600 FastWriter::writeValue(
const Value &value )
3602 switch ( value.
type() )
3605 document_ +=
"null";
3625 int size = value.
size();
3626 for (
int index =0; index < size; ++index )
3630 writeValue( value[index] );
3639 for ( Value::Members::iterator it = members.begin();
3640 it != members.end();
3643 const std::string &name = *it;
3644 if ( it != members.begin() )
3647 document_ += yamlCompatiblityEnabled_ ?
": " 3649 writeValue( value[name] );
3662 : rightMargin_( 74 )
3672 addChildValues_ =
false;
3674 writeCommentBeforeValue( root );
3676 writeCommentAfterValueOnSameLine( root );
3683 StyledWriter::writeValue(
const Value &value )
3685 switch ( value.
type() )
3688 pushValue(
"null" );
3706 writeArrayValue( value);
3711 if ( members.empty() )
3715 writeWithIndent(
"{" );
3717 Value::Members::iterator it = members.begin();
3720 const std::string &name = *it;
3721 const Value &childValue = value[name];
3722 writeCommentBeforeValue( childValue );
3725 writeValue( childValue );
3726 if ( ++it == members.end() )
3728 writeCommentAfterValueOnSameLine( childValue );
3732 writeCommentAfterValueOnSameLine( childValue );
3735 writeWithIndent(
"}" );
3744 StyledWriter::writeArrayValue(
const Value &value )
3746 unsigned size = value.
size();
3751 bool isArrayMultiLine = isMultineArray( value );
3752 if ( isArrayMultiLine )
3754 writeWithIndent(
"[" );
3756 bool hasChildValue = !childValues_.empty();
3760 const Value &childValue = value[index];
3761 writeCommentBeforeValue( childValue );
3762 if ( hasChildValue )
3763 writeWithIndent( childValues_[index] );
3767 writeValue( childValue );
3769 if ( ++index == size )
3771 writeCommentAfterValueOnSameLine( childValue );
3775 writeCommentAfterValueOnSameLine( childValue );
3778 writeWithIndent(
"]" );
3782 assert( childValues_.size() == size );
3784 for (
unsigned index =0; index < size; ++index )
3788 document_ += childValues_[index];
3797 StyledWriter::isMultineArray(
const Value &value )
3799 int size = value.
size();
3800 bool isMultiLine = size*3 >= rightMargin_ ;
3801 childValues_.clear();
3802 for (
int index =0; index < size && !isMultiLine; ++index )
3804 const Value &childValue = value[index];
3805 isMultiLine = isMultiLine ||
3807 childValue.
size() > 0 );
3811 childValues_.reserve( size );
3812 addChildValues_ =
true;
3813 int lineLength = 4 + (size-1)*2;
3814 for (
int index =0; index < size && !isMultiLine; ++index )
3816 writeValue( value[index] );
3817 lineLength += int( childValues_[index].length() );
3818 isMultiLine = isMultiLine && hasCommentForValue( value[index] );
3820 addChildValues_ =
false;
3821 isMultiLine = isMultiLine || lineLength >= rightMargin_;
3828 StyledWriter::pushValue(
const std::string &value )
3830 if ( addChildValues_ )
3831 childValues_.push_back( value );
3838 StyledWriter::writeIndent()
3840 if ( !document_.empty() )
3842 char last = document_[document_.length()-1];
3848 document_ += indentString_;
3853 StyledWriter::writeWithIndent(
const std::string &value )
3861 StyledWriter::indent()
3863 indentString_ += std::string( indentSize_,
' ' );
3868 StyledWriter::unindent()
3870 assert(
int(indentString_.size()) >= indentSize_ );
3871 indentString_.resize( indentString_.size() - indentSize_ );
3876 StyledWriter::writeCommentBeforeValue(
const Value &root )
3886 StyledWriter::writeCommentAfterValueOnSameLine(
const Value &root )
3901 StyledWriter::hasCommentForValue(
const Value &value )
3910 StyledWriter::normalizeEOL(
const std::string &text )
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 )
3919 char c = *current++;
3922 if ( *current ==
'\n' )
3937 : document_(nullptr)
3938 , rightMargin_( 74 )
3939 , indentation_( indentation )
3948 addChildValues_ =
false;
3950 writeCommentBeforeValue( root );
3952 writeCommentAfterValueOnSameLine( root );
3954 document_ =
nullptr;
3959 StyledStreamWriter::writeValue(
const Value &value )
3961 switch ( value.
type() )
3964 pushValue(
"null" );
3982 writeArrayValue( value);
3987 if ( members.empty() )
3991 writeWithIndent(
"{" );
3993 Value::Members::iterator it = members.begin();
3996 const std::string &name = *it;
3997 const Value &childValue = value[name];
3998 writeCommentBeforeValue( childValue );
4000 *document_ <<
" : ";
4001 writeValue( childValue );
4002 if ( ++it == members.end() )
4004 writeCommentAfterValueOnSameLine( childValue );
4008 writeCommentAfterValueOnSameLine( childValue );
4011 writeWithIndent(
"}" );
4020 StyledStreamWriter::writeArrayValue(
const Value &value )
4022 unsigned size = value.
size();
4027 bool isArrayMultiLine = isMultineArray( value );
4028 if ( isArrayMultiLine )
4030 writeWithIndent(
"[" );
4032 bool hasChildValue = !childValues_.empty();
4036 const Value &childValue = value[index];
4037 writeCommentBeforeValue( childValue );
4038 if ( hasChildValue )
4039 writeWithIndent( childValues_[index] );
4043 writeValue( childValue );
4045 if ( ++index == size )
4047 writeCommentAfterValueOnSameLine( childValue );
4051 writeCommentAfterValueOnSameLine( childValue );
4054 writeWithIndent(
"]" );
4058 assert( childValues_.size() == size );
4060 for (
unsigned index =0; index < size; ++index )
4064 *document_ << childValues_[index];
4073 StyledStreamWriter::isMultineArray(
const Value &value )
4075 int size = value.
size();
4076 bool isMultiLine = size*3 >= rightMargin_ ;
4077 childValues_.clear();
4078 for (
int index =0; index < size && !isMultiLine; ++index )
4080 const Value &childValue = value[index];
4081 isMultiLine = isMultiLine ||
4083 childValue.
size() > 0 );
4087 childValues_.reserve( size );
4088 addChildValues_ =
true;
4089 int lineLength = 4 + (size-1)*2;
4090 for (
int index =0; index < size && !isMultiLine; ++index )
4092 writeValue( value[index] );
4093 lineLength += int( childValues_[index].length() );
4094 isMultiLine = isMultiLine && hasCommentForValue( value[index] );
4096 addChildValues_ =
false;
4097 isMultiLine = isMultiLine || lineLength >= rightMargin_;
4104 StyledStreamWriter::pushValue(
const std::string &value )
4106 if ( addChildValues_ )
4107 childValues_.push_back( value );
4109 *document_ << value;
4114 StyledStreamWriter::writeIndent()
4128 *document_ <<
'\n' << indentString_;
4133 StyledStreamWriter::writeWithIndent(
const std::string &value )
4136 *document_ << value;
4141 StyledStreamWriter::indent()
4143 indentString_ += indentation_;
4148 StyledStreamWriter::unindent()
4150 assert( indentString_.size() >= indentation_.size() );
4151 indentString_.resize( indentString_.size() - indentation_.size() );
4156 StyledStreamWriter::writeCommentBeforeValue(
const Value &root )
4166 StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value &root )
4181 StyledStreamWriter::hasCommentForValue(
const Value &value )
4190 StyledStreamWriter::normalizeEOL(
const std::string &text )
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 )
4199 char c = *current++;
4202 if ( *current ==
'\n' )
4216 writer.
write(sout, root);
#define JSON_FAIL_MESSAGE(message)
Value & operator[](ArrayIndex index)
bool operator>(const Value &other) const
std::vector< std::string > Members
Value get(ArrayIndex index, const Value &defaultValue) const
Value(ValueType type=nullValue)
Create a default Value of the given type.
std::string valueToQuotedString(const char *value)
std::ostream & operator<<(std::ostream &sout, const Value &root)
Output using the StyledStreamWriter.
bool allowComments_
true if comments are allowed. Default: true.
bool isConvertibleTo(ValueType other) const
const_iterator end() const
Writes a Value in JSON format in a human friendly way, to a stream rather than to a string...
Features()
Initialize the configuration like JsonConfig::allFeatures;.
bool isEqual(const SelfType &other) const
Json::LargestInt LargestInt
Value removeMember(const char *key)
Remove and return the named member.
static const LargestUInt maxLargestUInt
Maximum unsigned integer value that can be stored in a Json::Value.
const char * c_str() const
std::string getComment(CommentPlacement placement) const
Include delimiters and embedded newlines.
bool operator!=(const Value &other) const
static const LargestInt minLargestInt
Minimum signed integer value that can be stored in a Json::Value.
std::string getFormatedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
Value key() const
Return either the index or the member name of the referenced value as a Value.
std::string write(const Value &root) override
Experimental and untested: represents an element of the "path" to access a node.
Json::ArrayIndex ArrayIndex
Lightweight wrapper to tag static string.
static const unsigned int unknown
Unknown size marker.
ValueConstIterator const_iterator
bool operator<(const StaticParameterMap::ValueType &a, const StaticParameterMap::ValueType &b)
Compares two var lists and returns true if the first list's first item is lower than the second one's...
bool operator!() const
Return isNull()
bool isValidIndex(ArrayIndex index) const
Return true if index < size().
bool parse(const std::string &document, Value &root, bool collectComments=true)
Read a Value from a JSON document.
std::string asString() const
static const UInt maxUInt
Maximum unsigned int value that can be stored in a Json::Value.
void setComment(const char *comment, CommentPlacement placement)
Comments must be //... or /* ... */.
Configuration passed to reader and writer. This configuration object can be used to force the Reader ...
const Value & resolve(const Value &root) const
a comment placed on the line before a value
static const UInt64 maxUInt64
Maximum unsigned 64 bits int value that can be stored in a Json::Value.
static const Int64 maxInt64
Maximum signed 64 bits int value that can be stored in a Json::Value.
MITKCORE_EXPORT bool operator==(const InteractionEvent &a, const InteractionEvent &b)
SelfType & operator=(const ValueIteratorBase &other)
static void info(const char *fmt,...)
void enableYAMLCompatibility()
Value & make(Value &root) const
Creates the "path" to access the specified node and returns a reference on the node.
bool operator>=(const Value &other) const
#define JSON_ASSERT_MESSAGE(condition, message)
static std::string codePointToUTF8(unsigned int cp)
Converts a unicode code-point to UTF-8.
static const Int minInt
Minimum signed int value that can be stored in a Json::Value.
void resize(ArrayIndex size)
Value & operator=(const Value &other)
bool isMember(const char *key) const
Return true if the object has a member named key.
static bool isControlCharacter(char ch)
Returns true if ch is a control character (in range [0,32[).
std::map< CZString, Value > ObjectValues
static const Int64 minInt64
Minimum signed 64 bits int value that can be stored in a Json::Value.
Reader()
Constructs a Reader allowing all features for parsing.
bool hasComment(CommentPlacement placement) const
static void uintToString(LargestUInt value, char *¤t)
object value (collection of name/value pairs).
static Features all()
A configuration that allows all features and assumes all strings are UTF-8.
Constant that specify the size of the buffer that must be passed to uintToString. ...
Json::LargestUInt LargestUInt
char UIntToStringBuffer[uintToStringBufferSize]
ValueType
Type of the value held by a Value object.
std::string toStyledString() const
#define JSON_ASSERT(condition)
JSON (JavaScript Object Notation).
a comment just after a value on the same line
static void releaseStringValue(char *value)
static bool containsControlCharacter(const char *str)
std::istream & operator>>(std::istream &sin, Value &root)
Read from 'sin' into 'root'.
base class for Value iterators.
#define JSON_ASSERT_UNREACHABLE
std::string valueToString(LargestInt value)
UInt index() const
Return the index of the referenced Value. -1 if it is not an arrayValue.
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())
ArrayIndex size() const
Number of values in array or object.
a comment on the line after a value (only make sense for root value)
void copy(const SelfType &other)
bool equals(const mitk::ScalarType &val1, const mitk::ScalarType &val2, mitk::ScalarType epsilon=mitk::eps)
LargestInt asLargestInt() const
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
SelfType & operator=(const SelfType &other)
std::string write(const Value &root) override
Serialize a Value in JSON format.
static const Int maxInt
Maximum signed int value that can be stored in a Json::Value.
bool operator<=(const Value &other) const
bool empty() const
Return true if empty array, empty object, or null; otherwise, false.
void write(std::ostream &out, const Value &root)
Serialize a Value in JSON format.
static void swap(T &x, T &y)
static Features strictMode()
A configuration that is strictly compatible with the JSON specification.
difference_type computeDistance(const SelfType &other) const
LargestUInt asLargestUInt() const
Unserialize a JSON document into a Value.
unsigned long long int UInt64
static const LargestInt maxLargestInt
Maximum signed integer value that can be stored in a Json::Value.
static bool containsNewLine(Reader::Location begin, Reader::Location end)
static char * duplicateStringValue(const char *value, unsigned int length=unknown)
Iterator for object and array value.
int compare(const Value &other) const
Members getMemberNames() const
Return a list of the member names.
bool operator<(const Value &other) const
Writes a Value in JSON format in a human friendly way.
const char * memberName() const
Return the member name of the referenced Value. "" if it is not an objectValue.
const char * asCString() const
StyledStreamWriter(std::string indentation="\)
bool strictRoot_
true if root must be either an array or an object value. Default: false.
Value & append(const Value &value)
Append value to array at the end.
std::string getFormattedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
bool operator==(const Value &other) const
const iterator for object and array value.
array value (ordered list)
const_iterator begin() const