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;
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' )
524 Reader::match( Location pattern,
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 );
567 Reader::addComment( Location begin,
571 assert( collectComments_ );
574 assert( lastValue_ != 0 );
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 ==
'-';
762 : Value::maxLargestUInt;
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
1461 : ValueIteratorBase( state )
1466 : ValueIteratorBase( state )
1471 ValueConstIterator &
1492 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1499 : ValueIteratorBase( state )
1504 : ValueIteratorBase( state )
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()
1651 Value::CommentInfo::~CommentInfo()
1659 Value::CommentInfo::setComment(
const char *text )
1677 # ifndef JSON_VALUE_USE_INTERNAL_MAP
1682 Value::CZString::CZString(
ArrayIndex index )
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_ != 0
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 );
1726 Value::CZString::operator<(
const CZString &other )
const
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
1780 # ifdef JSON_VALUE_USE_INTERNAL_MAP
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)
1824 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1828 value_.uint_ = value;
1834 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1838 value_.int_ = value;
1841 #endif // if defined(JSON_HAS_INT64)
1847 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1851 value_.int_ = value;
1858 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1862 value_.uint_ = value;
1868 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1872 value_.real_ = value;
1877 , allocated_( true )
1879 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1888 const char *endValue )
1890 , allocated_( true )
1892 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1897 static_cast<unsigned int>(endValue - beginValue) );
1903 , allocated_( true )
1905 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1910 static_cast<unsigned int>(value.length()) );
1916 , allocated_( false )
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
1942 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1946 value_.bool_ = value;
1951 : type_( other.type_ )
1953 # ifdef JSON_VALUE_USE_INTERNAL_MAP
1964 value_ = other.value_;
1967 if ( other.value_.string_ )
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_ == 0 && 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_ != 0 && comments_[placement].comment_ != 0;
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 ||
3806 ( (childValue.isArray() || childValue.isObject()) &&
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 )
3880 document_ += normalizeEOL( root.getComment(
commentBefore ) );
3886 StyledWriter::writeCommentAfterValueOnSameLine(
const Value &root )
3894 document_ += normalizeEOL( root.getComment(
commentAfter ) );
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' )
3938 , rightMargin_( 74 )
3939 , indentation_( indentation )
3948 addChildValues_ =
false;
3950 writeCommentBeforeValue( root );
3952 writeCommentAfterValueOnSameLine( root );
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 ||
4082 ( (childValue.isArray() || childValue.isObject()) &&
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 )
4160 *document_ << normalizeEOL( root.getComment(
commentBefore ) );
4166 StyledStreamWriter::writeCommentAfterValueOnSameLine(
const Value &root )
4174 *document_ << normalizeEOL( root.getComment(
commentAfter ) );
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)
bool operator<=(const Value &other) const
Value & operator[](ArrayIndex index)
std::vector< std::string > Members
const_iterator begin() const
Value(ValueType type=nullValue)
Create a default Value of the given type.
bool operator>(const Value &other) const
std::string valueToQuotedString(const char *value)
std::ostream & operator<<(std::ostream &sout, const Value &root)
Output using the StyledStreamWriter.
const_iterator end() const
bool allowComments_
true if comments are allowed. Default: true.
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;.
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.
bool isEqual(const SelfType &other) const
Value get(ArrayIndex index, const Value &defaultValue) const
static const LargestInt minLargestInt
Minimum signed integer value that can be stored in a Json::Value.
virtual 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 parse(const std::string &document, Value &root, bool collectComments=true)
Read a Value from a JSON document.
static const UInt maxUInt
Maximum unsigned int value that can be stored in a Json::Value.
bool operator<(const Value &other) const
void setComment(const char *comment, CommentPlacement placement)
Comments must be //... or /* ... */.
const Value & resolve(const Value &root) const
const char * c_str() const
Configuration passed to reader and writer. This configuration object can be used to force the Reader ...
a comment placed on the line before a value
bool operator!=(const Value &other) const
bool isValidIndex(ArrayIndex index) const
Return true if index < size().
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()
bool isConvertibleTo(ValueType other) const
#define JSON_ASSERT_MESSAGE(condition, message)
bool isMember(const char *key) const
Return true if the object has a member named key.
const char * memberName() const
Return the member name of the referenced Value. "" if it is not an objectValue.
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)
difference_type computeDistance(const SelfType &other) const
static bool isControlCharacter(char ch)
Returns true if ch is a control character (in range [0,32[).
bool operator>=(const Value &other) const
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 operator==(const Value &other) 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]
UInt index() const
Return the index of the referenced Value. -1 if it is not an arrayValue.
ValueType
Type of the value held by a Value object.
#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.
bool hasComment(CommentPlacement placement) const
#define JSON_ASSERT_UNREACHABLE
std::string getFormattedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
bool empty() const
Return true if empty array, empty object, or null; otherwise, false.
std::string valueToString(LargestInt value)
Value key() const
Return either the index or the member name of the referenced value as a Value.
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())
a comment on the line after a value (only make sense for root value)
bool operator!() const
Return isNull()
void copy(const SelfType &other)
std::string asString() const
std::string toStyledString() const
std::string getComment(CommentPlacement placement) const
Include delimiters and embedded newlines.
bool equals(const mitk::ScalarType &val1, const mitk::ScalarType &val2, mitk::ScalarType epsilon=mitk::eps)
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
Value & make(Value &root) const
Creates the "path" to access the specified node and returns a reference on the node.
SelfType & operator=(const SelfType &other)
virtual 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.
LargestUInt asLargestUInt() const
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.
Unserialize a JSON document into a Value.
const char * asCString() const
StyledStreamWriter(std::string indentation="\t")
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.
Members getMemberNames() const
Return a list of the member names.
LargestInt asLargestInt() const
int compare(const Value &other) const
Writes a Value in JSON format in a human friendly way.
ArrayIndex size() const
Number of values in array or object.
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.
const iterator for object and array value.
std::string getFormatedErrorMessages() const
Returns a user friendly string that list errors in the parsed document.
array value (ordered list)