00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #include <json/json.h>
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
00089 # define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
00090
00091
00092
00093
00094
00095
00096
00097 namespace Json {
00098
00100 static inline std::string
00101 codePointToUTF8(unsigned int cp)
00102 {
00103 std::string result;
00104
00105
00106
00107 if (cp <= 0x7f)
00108 {
00109 result.resize(1);
00110 result[0] = static_cast<char>(cp);
00111 }
00112 else if (cp <= 0x7FF)
00113 {
00114 result.resize(2);
00115 result[1] = static_cast<char>(0x80 | (0x3f & cp));
00116 result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
00117 }
00118 else if (cp <= 0xFFFF)
00119 {
00120 result.resize(3);
00121 result[2] = static_cast<char>(0x80 | (0x3f & cp));
00122 result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6)));
00123 result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12)));
00124 }
00125 else if (cp <= 0x10FFFF)
00126 {
00127 result.resize(4);
00128 result[3] = static_cast<char>(0x80 | (0x3f & cp));
00129 result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
00130 result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
00131 result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
00132 }
00133
00134 return result;
00135 }
00136
00137
00139 static inline bool
00140 isControlCharacter(char ch)
00141 {
00142 return ch > 0 && ch <= 0x1F;
00143 }
00144
00145
00146 enum {
00148 uintToStringBufferSize = 3*sizeof(LargestUInt)+1
00149 };
00150
00151
00152 typedef char UIntToStringBuffer[uintToStringBufferSize];
00153
00154
00160 static inline void
00161 uintToString( LargestUInt value,
00162 char *¤t )
00163 {
00164 *--current = 0;
00165 do
00166 {
00167 *--current = char(value % 10) + '0';
00168 value /= 10;
00169 }
00170 while ( value != 0 );
00171 }
00172
00173 }
00174
00175 #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 #if !defined(JSON_IS_AMALGAMATION)
00196 # include <json/reader.h>
00197 # include <json/value.h>
00198 # include "json_tool.h"
00199 #endif // if !defined(JSON_IS_AMALGAMATION)
00200 #include <utility>
00201 #include <cstdio>
00202 #include <cassert>
00203 #include <cstring>
00204 #include <iostream>
00205 #include <stdexcept>
00206
00207 #if _MSC_VER >= 1400 // VC++ 8.0
00208 #pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
00209 #endif
00210
00211 namespace Json {
00212
00213
00214
00215
00216 Features::Features()
00217 : allowComments_( true )
00218 , strictRoot_( false )
00219 {
00220 }
00221
00222
00223 Features
00224 Features::all()
00225 {
00226 return Features();
00227 }
00228
00229
00230 Features
00231 Features::strictMode()
00232 {
00233 Features features;
00234 features.allowComments_ = false;
00235 features.strictRoot_ = true;
00236 return features;
00237 }
00238
00239
00240
00241
00242
00243 static inline bool
00244 in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4 )
00245 {
00246 return c == c1 || c == c2 || c == c3 || c == c4;
00247 }
00248
00249 static inline bool
00250 in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4, Reader::Char c5 )
00251 {
00252 return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
00253 }
00254
00255
00256 static bool
00257 containsNewLine( Reader::Location begin,
00258 Reader::Location end )
00259 {
00260 for ( ;begin < end; ++begin )
00261 if ( *begin == '\n' || *begin == '\r' )
00262 return true;
00263 return false;
00264 }
00265
00266
00267
00268
00269
00270 Reader::Reader()
00271 : features_( Features::all() )
00272 {
00273 }
00274
00275
00276 Reader::Reader( const Features &features )
00277 : features_( features )
00278 {
00279 }
00280
00281
00282 bool
00283 Reader::parse( const std::string &document,
00284 Value &root,
00285 bool collectComments )
00286 {
00287 document_ = document;
00288 const char *begin = document_.c_str();
00289 const char *end = begin + document_.length();
00290 return parse( begin, end, root, collectComments );
00291 }
00292
00293
00294 bool
00295 Reader::parse( std::istream& sin,
00296 Value &root,
00297 bool collectComments )
00298 {
00299
00300
00301
00302
00303
00304
00305
00306 std::string doc;
00307 std::getline(sin, doc, (char)EOF);
00308 return parse( doc, root, collectComments );
00309 }
00310
00311 bool
00312 Reader::parse( const char *beginDoc, const char *endDoc,
00313 Value &root,
00314 bool collectComments )
00315 {
00316 if ( !features_.allowComments_ )
00317 {
00318 collectComments = false;
00319 }
00320
00321 begin_ = beginDoc;
00322 end_ = endDoc;
00323 collectComments_ = collectComments;
00324 current_ = begin_;
00325 lastValueEnd_ = 0;
00326 lastValue_ = 0;
00327 commentsBefore_ = "";
00328 errors_.clear();
00329 while ( !nodes_.empty() )
00330 nodes_.pop();
00331 nodes_.push( &root );
00332
00333 bool successful = readValue();
00334 Token token;
00335 skipCommentTokens( token );
00336 if ( collectComments_ && !commentsBefore_.empty() )
00337 root.setComment( commentsBefore_, commentAfter );
00338 if ( features_.strictRoot_ )
00339 {
00340 if ( !root.isArray() && !root.isObject() )
00341 {
00342
00343 token.type_ = tokenError;
00344 token.start_ = beginDoc;
00345 token.end_ = endDoc;
00346 addError( "A valid JSON document must be either an array or an object value.",
00347 token );
00348 return false;
00349 }
00350 }
00351 return successful;
00352 }
00353
00354
00355 bool
00356 Reader::readValue()
00357 {
00358 Token token;
00359 skipCommentTokens( token );
00360 bool successful = true;
00361
00362 if ( collectComments_ && !commentsBefore_.empty() )
00363 {
00364 currentValue().setComment( commentsBefore_, commentBefore );
00365 commentsBefore_ = "";
00366 }
00367
00368
00369 switch ( token.type_ )
00370 {
00371 case tokenObjectBegin:
00372 successful = readObject( token );
00373 break;
00374 case tokenArrayBegin:
00375 successful = readArray( token );
00376 break;
00377 case tokenNumber:
00378 successful = decodeNumber( token );
00379 break;
00380 case tokenString:
00381 successful = decodeString( token );
00382 break;
00383 case tokenTrue:
00384 currentValue() = true;
00385 break;
00386 case tokenFalse:
00387 currentValue() = false;
00388 break;
00389 case tokenNull:
00390 currentValue() = Value();
00391 break;
00392 default:
00393 return addError( "Syntax error: value, object or array expected.", token );
00394 }
00395
00396 if ( collectComments_ )
00397 {
00398 lastValueEnd_ = current_;
00399 lastValue_ = ¤tValue();
00400 }
00401
00402 return successful;
00403 }
00404
00405
00406 void
00407 Reader::skipCommentTokens( Token &token )
00408 {
00409 if ( features_.allowComments_ )
00410 {
00411 do
00412 {
00413 readToken( token );
00414 }
00415 while ( token.type_ == tokenComment );
00416 }
00417 else
00418 {
00419 readToken( token );
00420 }
00421 }
00422
00423
00424 bool
00425 Reader::expectToken( TokenType type, Token &token, const char *message )
00426 {
00427 readToken( token );
00428 if ( token.type_ != type )
00429 return addError( message, token );
00430 return true;
00431 }
00432
00433
00434 bool
00435 Reader::readToken( Token &token )
00436 {
00437 skipSpaces();
00438 token.start_ = current_;
00439 Char c = getNextChar();
00440 bool ok = true;
00441 switch ( c )
00442 {
00443 case '{':
00444 token.type_ = tokenObjectBegin;
00445 break;
00446 case '}':
00447 token.type_ = tokenObjectEnd;
00448 break;
00449 case '[':
00450 token.type_ = tokenArrayBegin;
00451 break;
00452 case ']':
00453 token.type_ = tokenArrayEnd;
00454 break;
00455 case '"':
00456 token.type_ = tokenString;
00457 ok = readString();
00458 break;
00459 case '/':
00460 token.type_ = tokenComment;
00461 ok = readComment();
00462 break;
00463 case '0':
00464 case '1':
00465 case '2':
00466 case '3':
00467 case '4':
00468 case '5':
00469 case '6':
00470 case '7':
00471 case '8':
00472 case '9':
00473 case '-':
00474 token.type_ = tokenNumber;
00475 readNumber();
00476 break;
00477 case 't':
00478 token.type_ = tokenTrue;
00479 ok = match( "rue", 3 );
00480 break;
00481 case 'f':
00482 token.type_ = tokenFalse;
00483 ok = match( "alse", 4 );
00484 break;
00485 case 'n':
00486 token.type_ = tokenNull;
00487 ok = match( "ull", 3 );
00488 break;
00489 case ',':
00490 token.type_ = tokenArraySeparator;
00491 break;
00492 case ':':
00493 token.type_ = tokenMemberSeparator;
00494 break;
00495 case 0:
00496 token.type_ = tokenEndOfStream;
00497 break;
00498 default:
00499 ok = false;
00500 break;
00501 }
00502 if ( !ok )
00503 token.type_ = tokenError;
00504 token.end_ = current_;
00505 return true;
00506 }
00507
00508
00509 void
00510 Reader::skipSpaces()
00511 {
00512 while ( current_ != end_ )
00513 {
00514 Char c = *current_;
00515 if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' )
00516 ++current_;
00517 else
00518 break;
00519 }
00520 }
00521
00522
00523 bool
00524 Reader::match( Location pattern,
00525 int patternLength )
00526 {
00527 if ( end_ - current_ < patternLength )
00528 return false;
00529 int index = patternLength;
00530 while ( index-- )
00531 if ( current_[index] != pattern[index] )
00532 return false;
00533 current_ += patternLength;
00534 return true;
00535 }
00536
00537
00538 bool
00539 Reader::readComment()
00540 {
00541 Location commentBegin = current_ - 1;
00542 Char c = getNextChar();
00543 bool successful = false;
00544 if ( c == '*' )
00545 successful = readCStyleComment();
00546 else if ( c == '/' )
00547 successful = readCppStyleComment();
00548 if ( !successful )
00549 return false;
00550
00551 if ( collectComments_ )
00552 {
00553 CommentPlacement placement = commentBefore;
00554 if ( lastValueEnd_ && !containsNewLine( lastValueEnd_, commentBegin ) )
00555 {
00556 if ( c != '*' || !containsNewLine( commentBegin, current_ ) )
00557 placement = commentAfterOnSameLine;
00558 }
00559
00560 addComment( commentBegin, current_, placement );
00561 }
00562 return true;
00563 }
00564
00565
00566 void
00567 Reader::addComment( Location begin,
00568 Location end,
00569 CommentPlacement placement )
00570 {
00571 assert( collectComments_ );
00572 if ( placement == commentAfterOnSameLine )
00573 {
00574 assert( lastValue_ != 0 );
00575 lastValue_->setComment( std::string( begin, end ), placement );
00576 }
00577 else
00578 {
00579 if ( !commentsBefore_.empty() )
00580 commentsBefore_ += "\n";
00581 commentsBefore_ += std::string( begin, end );
00582 }
00583 }
00584
00585
00586 bool
00587 Reader::readCStyleComment()
00588 {
00589 while ( current_ != end_ )
00590 {
00591 Char c = getNextChar();
00592 if ( c == '*' && *current_ == '/' )
00593 break;
00594 }
00595 return getNextChar() == '/';
00596 }
00597
00598
00599 bool
00600 Reader::readCppStyleComment()
00601 {
00602 while ( current_ != end_ )
00603 {
00604 Char c = getNextChar();
00605 if ( c == '\r' || c == '\n' )
00606 break;
00607 }
00608 return true;
00609 }
00610
00611
00612 void
00613 Reader::readNumber()
00614 {
00615 while ( current_ != end_ )
00616 {
00617 if ( !(*current_ >= '0' && *current_ <= '9') &&
00618 !in( *current_, '.', 'e', 'E', '+', '-' ) )
00619 break;
00620 ++current_;
00621 }
00622 }
00623
00624 bool
00625 Reader::readString()
00626 {
00627 Char c = 0;
00628 while ( current_ != end_ )
00629 {
00630 c = getNextChar();
00631 if ( c == '\\' )
00632 getNextChar();
00633 else if ( c == '"' )
00634 break;
00635 }
00636 return c == '"';
00637 }
00638
00639
00640 bool
00641 Reader::readObject( Token & )
00642 {
00643 Token tokenName;
00644 std::string name;
00645 currentValue() = Value( objectValue );
00646 while ( readToken( tokenName ) )
00647 {
00648 bool initialTokenOk = true;
00649 while ( tokenName.type_ == tokenComment && initialTokenOk )
00650 initialTokenOk = readToken( tokenName );
00651 if ( !initialTokenOk )
00652 break;
00653 if ( tokenName.type_ == tokenObjectEnd && name.empty() )
00654 return true;
00655 if ( tokenName.type_ != tokenString )
00656 break;
00657
00658 name = "";
00659 if ( !decodeString( tokenName, name ) )
00660 return recoverFromError( tokenObjectEnd );
00661
00662 Token colon;
00663 if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator )
00664 {
00665 return addErrorAndRecover( "Missing ':' after object member name",
00666 colon,
00667 tokenObjectEnd );
00668 }
00669 Value &value = currentValue()[ name ];
00670 nodes_.push( &value );
00671 bool ok = readValue();
00672 nodes_.pop();
00673 if ( !ok )
00674 return recoverFromError( tokenObjectEnd );
00675
00676 Token comma;
00677 if ( !readToken( comma )
00678 || ( comma.type_ != tokenObjectEnd &&
00679 comma.type_ != tokenArraySeparator &&
00680 comma.type_ != tokenComment ) )
00681 {
00682 return addErrorAndRecover( "Missing ',' or '}' in object declaration",
00683 comma,
00684 tokenObjectEnd );
00685 }
00686 bool finalizeTokenOk = true;
00687 while ( comma.type_ == tokenComment &&
00688 finalizeTokenOk )
00689 finalizeTokenOk = readToken( comma );
00690 if ( comma.type_ == tokenObjectEnd )
00691 return true;
00692 }
00693 return addErrorAndRecover( "Missing '}' or object member name",
00694 tokenName,
00695 tokenObjectEnd );
00696 }
00697
00698
00699 bool
00700 Reader::readArray( Token & )
00701 {
00702 currentValue() = Value( arrayValue );
00703 skipSpaces();
00704 if ( *current_ == ']' )
00705 {
00706 Token endArray;
00707 readToken( endArray );
00708 return true;
00709 }
00710 int index = 0;
00711 for (;;)
00712 {
00713 Value &value = currentValue()[ index++ ];
00714 nodes_.push( &value );
00715 bool ok = readValue();
00716 nodes_.pop();
00717 if ( !ok )
00718 return recoverFromError( tokenArrayEnd );
00719
00720 Token token;
00721
00722 ok = readToken( token );
00723 while ( token.type_ == tokenComment && ok )
00724 {
00725 ok = readToken( token );
00726 }
00727 bool badTokenType = ( token.type_ != tokenArraySeparator &&
00728 token.type_ != tokenArrayEnd );
00729 if ( !ok || badTokenType )
00730 {
00731 return addErrorAndRecover( "Missing ',' or ']' in array declaration",
00732 token,
00733 tokenArrayEnd );
00734 }
00735 if ( token.type_ == tokenArrayEnd )
00736 break;
00737 }
00738 return true;
00739 }
00740
00741
00742 bool
00743 Reader::decodeNumber( Token &token )
00744 {
00745 bool isDouble = false;
00746 for ( Location inspect = token.start_; inspect != token.end_; ++inspect )
00747 {
00748 isDouble = isDouble
00749 || in( *inspect, '.', 'e', 'E', '+' )
00750 || ( *inspect == '-' && inspect != token.start_ );
00751 }
00752 if ( isDouble )
00753 return decodeDouble( token );
00754
00755
00756
00757 Location current = token.start_;
00758 bool isNegative = *current == '-';
00759 if ( isNegative )
00760 ++current;
00761 Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(-Value::minLargestInt)
00762 : Value::maxLargestUInt;
00763 Value::LargestUInt threshold = maxIntegerValue / 10;
00764 Value::UInt lastDigitThreshold = Value::UInt( maxIntegerValue % 10 );
00765 assert( lastDigitThreshold >=0 && lastDigitThreshold <= 9 );
00766 Value::LargestUInt value = 0;
00767 while ( current < token.end_ )
00768 {
00769 Char c = *current++;
00770 if ( c < '0' || c > '9' )
00771 return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
00772 Value::UInt digit(c - '0');
00773 if ( value >= threshold )
00774 {
00775
00776
00777
00778 if ( current != token.end_ || digit > lastDigitThreshold )
00779 {
00780 return decodeDouble( token );
00781 }
00782 }
00783 value = value * 10 + digit;
00784 }
00785 if ( isNegative )
00786 currentValue() = -Value::LargestInt( value );
00787 else if ( value <= Value::LargestUInt(Value::maxInt) )
00788 currentValue() = Value::LargestInt( value );
00789 else
00790 currentValue() = value;
00791 return true;
00792 }
00793
00794
00795 bool
00796 Reader::decodeDouble( Token &token )
00797 {
00798 double value = 0;
00799 const int bufferSize = 32;
00800 int count;
00801 int length = int(token.end_ - token.start_);
00802 if ( length <= bufferSize )
00803 {
00804 Char buffer[bufferSize+1];
00805 memcpy( buffer, token.start_, length );
00806 buffer[length] = 0;
00807 count = sscanf( buffer, "%lf", &value );
00808 }
00809 else
00810 {
00811 std::string buffer( token.start_, token.end_ );
00812 count = sscanf( buffer.c_str(), "%lf", &value );
00813 }
00814
00815 if ( count != 1 )
00816 return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
00817 currentValue() = value;
00818 return true;
00819 }
00820
00821
00822 bool
00823 Reader::decodeString( Token &token )
00824 {
00825 std::string decoded;
00826 if ( !decodeString( token, decoded ) )
00827 return false;
00828 currentValue() = decoded;
00829 return true;
00830 }
00831
00832
00833 bool
00834 Reader::decodeString( Token &token, std::string &decoded )
00835 {
00836 decoded.reserve( token.end_ - token.start_ - 2 );
00837 Location current = token.start_ + 1;
00838 Location end = token.end_ - 1;
00839 while ( current != end )
00840 {
00841 Char c = *current++;
00842 if ( c == '"' )
00843 break;
00844 else if ( c == '\\' )
00845 {
00846 if ( current == end )
00847 return addError( "Empty escape sequence in string", token, current );
00848 Char escape = *current++;
00849 switch ( escape )
00850 {
00851 case '"': decoded += '"'; break;
00852 case '/': decoded += '/'; break;
00853 case '\\': decoded += '\\'; break;
00854 case 'b': decoded += '\b'; break;
00855 case 'f': decoded += '\f'; break;
00856 case 'n': decoded += '\n'; break;
00857 case 'r': decoded += '\r'; break;
00858 case 't': decoded += '\t'; break;
00859 case 'u':
00860 {
00861 unsigned int unicode;
00862 if ( !decodeUnicodeCodePoint( token, current, end, unicode ) )
00863 return false;
00864 decoded += codePointToUTF8(unicode);
00865 }
00866 break;
00867 default:
00868 return addError( "Bad escape sequence in string", token, current );
00869 }
00870 }
00871 else
00872 {
00873 decoded += c;
00874 }
00875 }
00876 return true;
00877 }
00878
00879 bool
00880 Reader::decodeUnicodeCodePoint( Token &token,
00881 Location ¤t,
00882 Location end,
00883 unsigned int &unicode )
00884 {
00885
00886 if ( !decodeUnicodeEscapeSequence( token, current, end, unicode ) )
00887 return false;
00888 if (unicode >= 0xD800 && unicode <= 0xDBFF)
00889 {
00890
00891 if (end - current < 6)
00892 return addError( "additional six characters expected to parse unicode surrogate pair.", token, current );
00893 unsigned int surrogatePair;
00894 if (*(current++) == '\\' && *(current++)== 'u')
00895 {
00896 if (decodeUnicodeEscapeSequence( token, current, end, surrogatePair ))
00897 {
00898 unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
00899 }
00900 else
00901 return false;
00902 }
00903 else
00904 return addError( "expecting another \\u token to begin the second half of a unicode surrogate pair", token, current );
00905 }
00906 return true;
00907 }
00908
00909 bool
00910 Reader::decodeUnicodeEscapeSequence( Token &token,
00911 Location ¤t,
00912 Location end,
00913 unsigned int &unicode )
00914 {
00915 if ( end - current < 4 )
00916 return addError( "Bad unicode escape sequence in string: four digits expected.", token, current );
00917 unicode = 0;
00918 for ( int index =0; index < 4; ++index )
00919 {
00920 Char c = *current++;
00921 unicode *= 16;
00922 if ( c >= '0' && c <= '9' )
00923 unicode += c - '0';
00924 else if ( c >= 'a' && c <= 'f' )
00925 unicode += c - 'a' + 10;
00926 else if ( c >= 'A' && c <= 'F' )
00927 unicode += c - 'A' + 10;
00928 else
00929 return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", token, current );
00930 }
00931 return true;
00932 }
00933
00934
00935 bool
00936 Reader::addError( const std::string &message,
00937 Token &token,
00938 Location extra )
00939 {
00940 ErrorInfo info;
00941 info.token_ = token;
00942 info.message_ = message;
00943 info.extra_ = extra;
00944 errors_.push_back( info );
00945 return false;
00946 }
00947
00948
00949 bool
00950 Reader::recoverFromError( TokenType skipUntilToken )
00951 {
00952 int errorCount = int(errors_.size());
00953 Token skip;
00954 for (;;)
00955 {
00956 if ( !readToken(skip) )
00957 errors_.resize( errorCount );
00958 if ( skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream )
00959 break;
00960 }
00961 errors_.resize( errorCount );
00962 return false;
00963 }
00964
00965
00966 bool
00967 Reader::addErrorAndRecover( const std::string &message,
00968 Token &token,
00969 TokenType skipUntilToken )
00970 {
00971 addError( message, token );
00972 return recoverFromError( skipUntilToken );
00973 }
00974
00975
00976 Value &
00977 Reader::currentValue()
00978 {
00979 return *(nodes_.top());
00980 }
00981
00982
00983 Reader::Char
00984 Reader::getNextChar()
00985 {
00986 if ( current_ == end_ )
00987 return 0;
00988 return *current_++;
00989 }
00990
00991
00992 void
00993 Reader::getLocationLineAndColumn( Location location,
00994 int &line,
00995 int &column ) const
00996 {
00997 Location current = begin_;
00998 Location lastLineStart = current;
00999 line = 0;
01000 while ( current < location && current != end_ )
01001 {
01002 Char c = *current++;
01003 if ( c == '\r' )
01004 {
01005 if ( *current == '\n' )
01006 ++current;
01007 lastLineStart = current;
01008 ++line;
01009 }
01010 else if ( c == '\n' )
01011 {
01012 lastLineStart = current;
01013 ++line;
01014 }
01015 }
01016
01017 column = int(location - lastLineStart) + 1;
01018 ++line;
01019 }
01020
01021
01022 std::string
01023 Reader::getLocationLineAndColumn( Location location ) const
01024 {
01025 int line, column;
01026 getLocationLineAndColumn( location, line, column );
01027 char buffer[18+16+16+1];
01028 sprintf( buffer, "Line %d, Column %d", line, column );
01029 return buffer;
01030 }
01031
01032
01033
01034 std::string
01035 Reader::getFormatedErrorMessages() const
01036 {
01037 return getFormattedErrorMessages();
01038 }
01039
01040
01041 std::string
01042 Reader::getFormattedErrorMessages() const
01043 {
01044 std::string formattedMessage;
01045 for ( Errors::const_iterator itError = errors_.begin();
01046 itError != errors_.end();
01047 ++itError )
01048 {
01049 const ErrorInfo &error = *itError;
01050 formattedMessage += "* " + getLocationLineAndColumn( error.token_.start_ ) + "\n";
01051 formattedMessage += " " + error.message_ + "\n";
01052 if ( error.extra_ )
01053 formattedMessage += "See " + getLocationLineAndColumn( error.extra_ ) + " for detail.\n";
01054 }
01055 return formattedMessage;
01056 }
01057
01058
01059 std::istream& operator>>( std::istream &sin, Value &root )
01060 {
01061 Json::Reader reader;
01062 bool ok = reader.parse(sin, root, true);
01063
01064 if (!ok) throw std::runtime_error(reader.getFormattedErrorMessages());
01065 return sin;
01066 }
01067
01068
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
01090 # define JSONCPP_BATCHALLOCATOR_H_INCLUDED
01091
01092 # include <stdlib.h>
01093 # include <assert.h>
01094
01095 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
01096
01097 namespace Json {
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111 template<typename AllocatedType
01112 ,const unsigned int objectPerAllocation>
01113 class BatchAllocator
01114 {
01115 public:
01116 typedef AllocatedType Type;
01117
01118 BatchAllocator( unsigned int objectsPerPage = 255 )
01119 : freeHead_( 0 )
01120 , objectsPerPage_( objectsPerPage )
01121 {
01122
01123 assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) );
01124 assert( objectsPerPage >= 16 );
01125 batches_ = allocateBatch( 0 );
01126 currentBatch_ = batches_;
01127 }
01128
01129 ~BatchAllocator()
01130 {
01131 for ( BatchInfo *batch = batches_; batch; )
01132 {
01133 BatchInfo *nextBatch = batch->next_;
01134 free( batch );
01135 batch = nextBatch;
01136 }
01137 }
01138
01141 AllocatedType *allocate()
01142 {
01143 if ( freeHead_ )
01144 {
01145 AllocatedType *object = freeHead_;
01146 freeHead_ = *(AllocatedType **)object;
01147 return object;
01148 }
01149 if ( currentBatch_->used_ == currentBatch_->end_ )
01150 {
01151 currentBatch_ = currentBatch_->next_;
01152 while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
01153 currentBatch_ = currentBatch_->next_;
01154
01155 if ( !currentBatch_ )
01156 {
01157 currentBatch_ = allocateBatch( objectsPerPage_ );
01158 currentBatch_->next_ = batches_;
01159 batches_ = currentBatch_;
01160 }
01161 }
01162 AllocatedType *allocated = currentBatch_->used_;
01163 currentBatch_->used_ += objectPerAllocation;
01164 return allocated;
01165 }
01166
01169 void release( AllocatedType *object )
01170 {
01171 assert( object != 0 );
01172 *(AllocatedType **)object = freeHead_;
01173 freeHead_ = object;
01174 }
01175
01176 private:
01177 struct BatchInfo
01178 {
01179 BatchInfo *next_;
01180 AllocatedType *used_;
01181 AllocatedType *end_;
01182 AllocatedType buffer_[objectPerAllocation];
01183 };
01184
01185
01186 BatchAllocator( const BatchAllocator & );
01187 void operator =( const BatchAllocator &);
01188
01189 static BatchInfo *allocateBatch( unsigned int objectsPerPage )
01190 {
01191 const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
01192 + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
01193 BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
01194 batch->next_ = 0;
01195 batch->used_ = batch->buffer_;
01196 batch->end_ = batch->buffer_ + objectsPerPage;
01197 return batch;
01198 }
01199
01200 BatchInfo *batches_;
01201 BatchInfo *currentBatch_;
01203 AllocatedType *freeHead_;
01204 unsigned int objectsPerPage_;
01205 };
01206
01207
01208 }
01209
01210 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
01211
01212 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235 namespace Json {
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 ValueIteratorBase::ValueIteratorBase()
01246 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01247 : current_()
01248 , isNull_( true )
01249 {
01250 }
01251 #else
01252 : isArray_( true )
01253 , isNull_( true )
01254 {
01255 iterator_.array_ = ValueInternalArray::IteratorState();
01256 }
01257 #endif
01258
01259
01260 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01261 ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator ¤t )
01262 : current_( current )
01263 , isNull_( false )
01264 {
01265 }
01266 #else
01267 ValueIteratorBase::ValueIteratorBase( const ValueInternalArray::IteratorState &state )
01268 : isArray_( true )
01269 {
01270 iterator_.array_ = state;
01271 }
01272
01273
01274 ValueIteratorBase::ValueIteratorBase( const ValueInternalMap::IteratorState &state )
01275 : isArray_( false )
01276 {
01277 iterator_.map_ = state;
01278 }
01279 #endif
01280
01281 Value &
01282 ValueIteratorBase::deref() const
01283 {
01284 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01285 return current_->second;
01286 #else
01287 if ( isArray_ )
01288 return ValueInternalArray::dereference( iterator_.array_ );
01289 return ValueInternalMap::value( iterator_.map_ );
01290 #endif
01291 }
01292
01293
01294 void
01295 ValueIteratorBase::increment()
01296 {
01297 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01298 ++current_;
01299 #else
01300 if ( isArray_ )
01301 ValueInternalArray::increment( iterator_.array_ );
01302 ValueInternalMap::increment( iterator_.map_ );
01303 #endif
01304 }
01305
01306
01307 void
01308 ValueIteratorBase::decrement()
01309 {
01310 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01311 --current_;
01312 #else
01313 if ( isArray_ )
01314 ValueInternalArray::decrement( iterator_.array_ );
01315 ValueInternalMap::decrement( iterator_.map_ );
01316 #endif
01317 }
01318
01319
01320 ValueIteratorBase::difference_type
01321 ValueIteratorBase::computeDistance( const SelfType &other ) const
01322 {
01323 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01324 # ifdef JSON_USE_CPPTL_SMALLMAP
01325 return current_ - other.current_;
01326 # else
01327
01328
01329
01330
01331
01332 if ( isNull_ && other.isNull_ )
01333 {
01334 return 0;
01335 }
01336
01337
01338
01339
01340
01341
01342 difference_type myDistance = 0;
01343 for ( Value::ObjectValues::iterator it = current_; it != other.current_; ++it )
01344 {
01345 ++myDistance;
01346 }
01347 return myDistance;
01348 # endif
01349 #else
01350 if ( isArray_ )
01351 return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ );
01352 return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ );
01353 #endif
01354 }
01355
01356
01357 bool
01358 ValueIteratorBase::isEqual( const SelfType &other ) const
01359 {
01360 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01361 if ( isNull_ )
01362 {
01363 return other.isNull_;
01364 }
01365 return current_ == other.current_;
01366 #else
01367 if ( isArray_ )
01368 return ValueInternalArray::equals( iterator_.array_, other.iterator_.array_ );
01369 return ValueInternalMap::equals( iterator_.map_, other.iterator_.map_ );
01370 #endif
01371 }
01372
01373
01374 void
01375 ValueIteratorBase::copy( const SelfType &other )
01376 {
01377 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01378 current_ = other.current_;
01379 #else
01380 if ( isArray_ )
01381 iterator_.array_ = other.iterator_.array_;
01382 iterator_.map_ = other.iterator_.map_;
01383 #endif
01384 }
01385
01386
01387 Value
01388 ValueIteratorBase::key() const
01389 {
01390 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01391 const Value::CZString czstring = (*current_).first;
01392 if ( czstring.c_str() )
01393 {
01394 if ( czstring.isStaticString() )
01395 return Value( StaticString( czstring.c_str() ) );
01396 return Value( czstring.c_str() );
01397 }
01398 return Value( czstring.index() );
01399 #else
01400 if ( isArray_ )
01401 return Value( ValueInternalArray::indexOf( iterator_.array_ ) );
01402 bool isStatic;
01403 const char *memberName = ValueInternalMap::key( iterator_.map_, isStatic );
01404 if ( isStatic )
01405 return Value( StaticString( memberName ) );
01406 return Value( memberName );
01407 #endif
01408 }
01409
01410
01411 UInt
01412 ValueIteratorBase::index() const
01413 {
01414 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01415 const Value::CZString czstring = (*current_).first;
01416 if ( !czstring.c_str() )
01417 return czstring.index();
01418 return Value::UInt( -1 );
01419 #else
01420 if ( isArray_ )
01421 return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) );
01422 return Value::UInt( -1 );
01423 #endif
01424 }
01425
01426
01427 const char *
01428 ValueIteratorBase::memberName() const
01429 {
01430 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01431 const char *name = (*current_).first.c_str();
01432 return name ? name : "";
01433 #else
01434 if ( !isArray_ )
01435 return ValueInternalMap::key( iterator_.map_ );
01436 return "";
01437 #endif
01438 }
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449 ValueConstIterator::ValueConstIterator()
01450 {
01451 }
01452
01453
01454 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01455 ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator ¤t )
01456 : ValueIteratorBase( current )
01457 {
01458 }
01459 #else
01460 ValueConstIterator::ValueConstIterator( const ValueInternalArray::IteratorState &state )
01461 : ValueIteratorBase( state )
01462 {
01463 }
01464
01465 ValueConstIterator::ValueConstIterator( const ValueInternalMap::IteratorState &state )
01466 : ValueIteratorBase( state )
01467 {
01468 }
01469 #endif
01470
01471 ValueConstIterator &
01472 ValueConstIterator::operator =( const ValueIteratorBase &other )
01473 {
01474 copy( other );
01475 return *this;
01476 }
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487 ValueIterator::ValueIterator()
01488 {
01489 }
01490
01491
01492 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01493 ValueIterator::ValueIterator( const Value::ObjectValues::iterator ¤t )
01494 : ValueIteratorBase( current )
01495 {
01496 }
01497 #else
01498 ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state )
01499 : ValueIteratorBase( state )
01500 {
01501 }
01502
01503 ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state )
01504 : ValueIteratorBase( state )
01505 {
01506 }
01507 #endif
01508
01509 ValueIterator::ValueIterator( const ValueConstIterator &other )
01510 : ValueIteratorBase( other )
01511 {
01512 }
01513
01514 ValueIterator::ValueIterator( const ValueIterator &other )
01515 : ValueIteratorBase( other )
01516 {
01517 }
01518
01519 ValueIterator &
01520 ValueIterator::operator =( const SelfType &other )
01521 {
01522 copy( other );
01523 return *this;
01524 }
01525
01526 }
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546 #if !defined(JSON_IS_AMALGAMATION)
01547 # include <json/value.h>
01548 # include <json/writer.h>
01549 # ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
01550 # include "json_batchallocator.h"
01551 # endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
01552 #endif // if !defined(JSON_IS_AMALGAMATION)
01553 #include <iostream>
01554 #include <utility>
01555 #include <stdexcept>
01556 #include <cstring>
01557 #include <cassert>
01558 #ifdef JSON_USE_CPPTL
01559 # include <cpptl/conststring.h>
01560 #endif
01561 #include <cstddef>
01562
01563 #define JSON_ASSERT_UNREACHABLE assert( false )
01564 #define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw
01565 #define JSON_FAIL_MESSAGE( message ) throw std::runtime_error( message );
01566 #define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) JSON_FAIL_MESSAGE( message )
01567
01568 namespace Json {
01569
01570 const Value Value::null;
01571 const Int Value::minInt = Int( ~(UInt(-1)/2) );
01572 const Int Value::maxInt = Int( UInt(-1)/2 );
01573 const UInt Value::maxUInt = UInt(-1);
01574 const Int64 Value::minInt64 = Int64( ~(UInt64(-1)/2) );
01575 const Int64 Value::maxInt64 = Int64( UInt64(-1)/2 );
01576 const UInt64 Value::maxUInt64 = UInt64(-1);
01577 const LargestInt Value::minLargestInt = LargestInt( ~(LargestUInt(-1)/2) );
01578 const LargestInt Value::maxLargestInt = LargestInt( LargestUInt(-1)/2 );
01579 const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
01580
01581
01583 static const unsigned int unknown = (unsigned)-1;
01584
01585
01593 static inline char *
01594 duplicateStringValue( const char *value,
01595 unsigned int length = unknown )
01596 {
01597 if ( length == unknown )
01598 length = (unsigned int)strlen(value);
01599 char *newString = static_cast<char *>( malloc( length + 1 ) );
01600 JSON_ASSERT_MESSAGE( newString != 0, "Failed to allocate string value buffer" );
01601 memcpy( newString, value, length );
01602 newString[length] = 0;
01603 return newString;
01604 }
01605
01606
01609 static inline void
01610 releaseStringValue( char *value )
01611 {
01612 if ( value )
01613 free( value );
01614 }
01615
01616 }
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626 #if !defined(JSON_IS_AMALGAMATION)
01627 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01628 # include "json_internalarray.inl"
01629 # include "json_internalmap.inl"
01630 # endif // JSON_VALUE_USE_INTERNAL_MAP
01631
01632 # include "json_valueiterator.inl"
01633 #endif // if !defined(JSON_IS_AMALGAMATION)
01634
01635 namespace Json {
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646 Value::CommentInfo::CommentInfo()
01647 : comment_( 0 )
01648 {
01649 }
01650
01651 Value::CommentInfo::~CommentInfo()
01652 {
01653 if ( comment_ )
01654 releaseStringValue( comment_ );
01655 }
01656
01657
01658 void
01659 Value::CommentInfo::setComment( const char *text )
01660 {
01661 if ( comment_ )
01662 releaseStringValue( comment_ );
01663 JSON_ASSERT( text != 0 );
01664 JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
01665
01666 comment_ = duplicateStringValue( text );
01667 }
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677 # ifndef JSON_VALUE_USE_INTERNAL_MAP
01678
01679
01680
01681
01682 Value::CZString::CZString( ArrayIndex index )
01683 : cstr_( 0 )
01684 , index_( index )
01685 {
01686 }
01687
01688 Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
01689 : cstr_( allocate == duplicate ? duplicateStringValue(cstr)
01690 : cstr )
01691 , index_( allocate )
01692 {
01693 }
01694
01695 Value::CZString::CZString( const CZString &other )
01696 : cstr_( other.index_ != noDuplication && other.cstr_ != 0
01697 ? duplicateStringValue( other.cstr_ )
01698 : other.cstr_ )
01699 , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
01700 : other.index_ )
01701 {
01702 }
01703
01704 Value::CZString::~CZString()
01705 {
01706 if ( cstr_ && index_ == duplicate )
01707 releaseStringValue( const_cast<char *>( cstr_ ) );
01708 }
01709
01710 void
01711 Value::CZString::swap( CZString &other )
01712 {
01713 std::swap( cstr_, other.cstr_ );
01714 std::swap( index_, other.index_ );
01715 }
01716
01717 Value::CZString &
01718 Value::CZString::operator =( const CZString &other )
01719 {
01720 CZString temp( other );
01721 swap( temp );
01722 return *this;
01723 }
01724
01725 bool
01726 Value::CZString::operator<( const CZString &other ) const
01727 {
01728 if ( cstr_ )
01729 return strcmp( cstr_, other.cstr_ ) < 0;
01730 return index_ < other.index_;
01731 }
01732
01733 bool
01734 Value::CZString::operator==( const CZString &other ) const
01735 {
01736 if ( cstr_ )
01737 return strcmp( cstr_, other.cstr_ ) == 0;
01738 return index_ == other.index_;
01739 }
01740
01741
01742 ArrayIndex
01743 Value::CZString::index() const
01744 {
01745 return index_;
01746 }
01747
01748
01749 const char *
01750 Value::CZString::c_str() const
01751 {
01752 return cstr_;
01753 }
01754
01755 bool
01756 Value::CZString::isStaticString() const
01757 {
01758 return index_ == noDuplication;
01759 }
01760
01761 #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01776 Value::Value( ValueType type )
01777 : type_( type )
01778 , allocated_( 0 )
01779 , comments_( 0 )
01780 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01781 , itemIsUsed_( 0 )
01782 #endif
01783 {
01784 switch ( type )
01785 {
01786 case nullValue:
01787 break;
01788 case intValue:
01789 case uintValue:
01790 value_.int_ = 0;
01791 break;
01792 case realValue:
01793 value_.real_ = 0.0;
01794 break;
01795 case stringValue:
01796 value_.string_ = 0;
01797 break;
01798 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01799 case arrayValue:
01800 case objectValue:
01801 value_.map_ = new ObjectValues();
01802 break;
01803 #else
01804 case arrayValue:
01805 value_.array_ = arrayAllocator()->newArray();
01806 break;
01807 case objectValue:
01808 value_.map_ = mapAllocator()->newMap();
01809 break;
01810 #endif
01811 case booleanValue:
01812 value_.bool_ = false;
01813 break;
01814 default:
01815 JSON_ASSERT_UNREACHABLE;
01816 }
01817 }
01818
01819
01820 #if defined(JSON_HAS_INT64)
01821 Value::Value( UInt value )
01822 : type_( uintValue )
01823 , comments_( 0 )
01824 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01825 , itemIsUsed_( 0 )
01826 #endif
01827 {
01828 value_.uint_ = value;
01829 }
01830
01831 Value::Value( Int value )
01832 : type_( intValue )
01833 , comments_( 0 )
01834 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01835 , itemIsUsed_( 0 )
01836 #endif
01837 {
01838 value_.int_ = value;
01839 }
01840
01841 #endif // if defined(JSON_HAS_INT64)
01842
01843
01844 Value::Value( Int64 value )
01845 : type_( intValue )
01846 , comments_( 0 )
01847 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01848 , itemIsUsed_( 0 )
01849 #endif
01850 {
01851 value_.int_ = value;
01852 }
01853
01854
01855 Value::Value( UInt64 value )
01856 : type_( uintValue )
01857 , comments_( 0 )
01858 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01859 , itemIsUsed_( 0 )
01860 #endif
01861 {
01862 value_.uint_ = value;
01863 }
01864
01865 Value::Value( double value )
01866 : type_( realValue )
01867 , comments_( 0 )
01868 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01869 , itemIsUsed_( 0 )
01870 #endif
01871 {
01872 value_.real_ = value;
01873 }
01874
01875 Value::Value( const char *value )
01876 : type_( stringValue )
01877 , allocated_( true )
01878 , comments_( 0 )
01879 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01880 , itemIsUsed_( 0 )
01881 #endif
01882 {
01883 value_.string_ = duplicateStringValue( value );
01884 }
01885
01886
01887 Value::Value( const char *beginValue,
01888 const char *endValue )
01889 : type_( stringValue )
01890 , allocated_( true )
01891 , comments_( 0 )
01892 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01893 , itemIsUsed_( 0 )
01894 #endif
01895 {
01896 value_.string_ = duplicateStringValue( beginValue,
01897 (unsigned int)(endValue - beginValue) );
01898 }
01899
01900
01901 Value::Value( const std::string &value )
01902 : type_( stringValue )
01903 , allocated_( true )
01904 , comments_( 0 )
01905 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01906 , itemIsUsed_( 0 )
01907 #endif
01908 {
01909 value_.string_ = duplicateStringValue( value.c_str(),
01910 (unsigned int)value.length() );
01911
01912 }
01913
01914 Value::Value( const StaticString &value )
01915 : type_( stringValue )
01916 , allocated_( false )
01917 , comments_( 0 )
01918 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01919 , itemIsUsed_( 0 )
01920 #endif
01921 {
01922 value_.string_ = const_cast<char *>( value.c_str() );
01923 }
01924
01925
01926 # ifdef JSON_USE_CPPTL
01927 Value::Value( const CppTL::ConstString &value )
01928 : type_( stringValue )
01929 , allocated_( true )
01930 , comments_( 0 )
01931 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01932 , itemIsUsed_( 0 )
01933 #endif
01934 {
01935 value_.string_ = duplicateStringValue( value, value.length() );
01936 }
01937 # endif
01938
01939 Value::Value( bool value )
01940 : type_( booleanValue )
01941 , comments_( 0 )
01942 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01943 , itemIsUsed_( 0 )
01944 #endif
01945 {
01946 value_.bool_ = value;
01947 }
01948
01949
01950 Value::Value( const Value &other )
01951 : type_( other.type_ )
01952 , comments_( 0 )
01953 # ifdef JSON_VALUE_USE_INTERNAL_MAP
01954 , itemIsUsed_( 0 )
01955 #endif
01956 {
01957 switch ( type_ )
01958 {
01959 case nullValue:
01960 case intValue:
01961 case uintValue:
01962 case realValue:
01963 case booleanValue:
01964 value_ = other.value_;
01965 break;
01966 case stringValue:
01967 if ( other.value_.string_ )
01968 {
01969 value_.string_ = duplicateStringValue( other.value_.string_ );
01970 allocated_ = true;
01971 }
01972 else
01973 value_.string_ = 0;
01974 break;
01975 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01976 case arrayValue:
01977 case objectValue:
01978 value_.map_ = new ObjectValues( *other.value_.map_ );
01979 break;
01980 #else
01981 case arrayValue:
01982 value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ );
01983 break;
01984 case objectValue:
01985 value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ );
01986 break;
01987 #endif
01988 default:
01989 JSON_ASSERT_UNREACHABLE;
01990 }
01991 if ( other.comments_ )
01992 {
01993 comments_ = new CommentInfo[numberOfCommentPlacement];
01994 for ( int comment =0; comment < numberOfCommentPlacement; ++comment )
01995 {
01996 const CommentInfo &otherComment = other.comments_[comment];
01997 if ( otherComment.comment_ )
01998 comments_[comment].setComment( otherComment.comment_ );
01999 }
02000 }
02001 }
02002
02003
02004 Value::~Value()
02005 {
02006 switch ( type_ )
02007 {
02008 case nullValue:
02009 case intValue:
02010 case uintValue:
02011 case realValue:
02012 case booleanValue:
02013 break;
02014 case stringValue:
02015 if ( allocated_ )
02016 releaseStringValue( value_.string_ );
02017 break;
02018 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02019 case arrayValue:
02020 case objectValue:
02021 delete value_.map_;
02022 break;
02023 #else
02024 case arrayValue:
02025 arrayAllocator()->destructArray( value_.array_ );
02026 break;
02027 case objectValue:
02028 mapAllocator()->destructMap( value_.map_ );
02029 break;
02030 #endif
02031 default:
02032 JSON_ASSERT_UNREACHABLE;
02033 }
02034
02035 if ( comments_ )
02036 delete[] comments_;
02037 }
02038
02039 Value &
02040 Value::operator=( const Value &other )
02041 {
02042 Value temp( other );
02043 swap( temp );
02044 return *this;
02045 }
02046
02047 void
02048 Value::swap( Value &other )
02049 {
02050 ValueType temp = type_;
02051 type_ = other.type_;
02052 other.type_ = temp;
02053 std::swap( value_, other.value_ );
02054 int temp2 = allocated_;
02055 allocated_ = other.allocated_;
02056 other.allocated_ = temp2;
02057 }
02058
02059 ValueType
02060 Value::type() const
02061 {
02062 return type_;
02063 }
02064
02065
02066 int
02067 Value::compare( const Value &other ) const
02068 {
02069 if ( *this < other )
02070 return -1;
02071 if ( *this > other )
02072 return 1;
02073 return 0;
02074 }
02075
02076
02077 bool
02078 Value::operator <( const Value &other ) const
02079 {
02080 int typeDelta = type_ - other.type_;
02081 if ( typeDelta )
02082 return typeDelta < 0 ? true : false;
02083 switch ( type_ )
02084 {
02085 case nullValue:
02086 return false;
02087 case intValue:
02088 return value_.int_ < other.value_.int_;
02089 case uintValue:
02090 return value_.uint_ < other.value_.uint_;
02091 case realValue:
02092 return value_.real_ < other.value_.real_;
02093 case booleanValue:
02094 return value_.bool_ < other.value_.bool_;
02095 case stringValue:
02096 return ( value_.string_ == 0 && other.value_.string_ )
02097 || ( other.value_.string_
02098 && value_.string_
02099 && strcmp( value_.string_, other.value_.string_ ) < 0 );
02100 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02101 case arrayValue:
02102 case objectValue:
02103 {
02104 int delta = int( value_.map_->size() - other.value_.map_->size() );
02105 if ( delta )
02106 return delta < 0;
02107 return (*value_.map_) < (*other.value_.map_);
02108 }
02109 #else
02110 case arrayValue:
02111 return value_.array_->compare( *(other.value_.array_) ) < 0;
02112 case objectValue:
02113 return value_.map_->compare( *(other.value_.map_) ) < 0;
02114 #endif
02115 default:
02116 JSON_ASSERT_UNREACHABLE;
02117 }
02118 return false;
02119 }
02120
02121 bool
02122 Value::operator <=( const Value &other ) const
02123 {
02124 return !(other < *this);
02125 }
02126
02127 bool
02128 Value::operator >=( const Value &other ) const
02129 {
02130 return !(*this < other);
02131 }
02132
02133 bool
02134 Value::operator >( const Value &other ) const
02135 {
02136 return other < *this;
02137 }
02138
02139 bool
02140 Value::operator ==( const Value &other ) const
02141 {
02142
02143
02144
02145
02146 int temp = other.type_;
02147 if ( type_ != temp )
02148 return false;
02149 switch ( type_ )
02150 {
02151 case nullValue:
02152 return true;
02153 case intValue:
02154 return value_.int_ == other.value_.int_;
02155 case uintValue:
02156 return value_.uint_ == other.value_.uint_;
02157 case realValue:
02158 return value_.real_ == other.value_.real_;
02159 case booleanValue:
02160 return value_.bool_ == other.value_.bool_;
02161 case stringValue:
02162 return ( value_.string_ == other.value_.string_ )
02163 || ( other.value_.string_
02164 && value_.string_
02165 && strcmp( value_.string_, other.value_.string_ ) == 0 );
02166 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02167 case arrayValue:
02168 case objectValue:
02169 return value_.map_->size() == other.value_.map_->size()
02170 && (*value_.map_) == (*other.value_.map_);
02171 #else
02172 case arrayValue:
02173 return value_.array_->compare( *(other.value_.array_) ) == 0;
02174 case objectValue:
02175 return value_.map_->compare( *(other.value_.map_) ) == 0;
02176 #endif
02177 default:
02178 JSON_ASSERT_UNREACHABLE;
02179 }
02180 return false;
02181 }
02182
02183 bool
02184 Value::operator !=( const Value &other ) const
02185 {
02186 return !( *this == other );
02187 }
02188
02189 const char *
02190 Value::asCString() const
02191 {
02192 JSON_ASSERT( type_ == stringValue );
02193 return value_.string_;
02194 }
02195
02196
02197 std::string
02198 Value::asString() const
02199 {
02200 switch ( type_ )
02201 {
02202 case nullValue:
02203 return "";
02204 case stringValue:
02205 return value_.string_ ? value_.string_ : "";
02206 case booleanValue:
02207 return value_.bool_ ? "true" : "false";
02208 case intValue:
02209 case uintValue:
02210 case realValue:
02211 case arrayValue:
02212 case objectValue:
02213 JSON_FAIL_MESSAGE( "Type is not convertible to string" );
02214 default:
02215 JSON_ASSERT_UNREACHABLE;
02216 }
02217 return "";
02218 }
02219
02220 # ifdef JSON_USE_CPPTL
02221 CppTL::ConstString
02222 Value::asConstString() const
02223 {
02224 return CppTL::ConstString( asString().c_str() );
02225 }
02226 # endif
02227
02228
02229 Value::Int
02230 Value::asInt() const
02231 {
02232 switch ( type_ )
02233 {
02234 case nullValue:
02235 return 0;
02236 case intValue:
02237 JSON_ASSERT_MESSAGE( value_.int_ >= minInt && value_.int_ <= maxInt, "unsigned integer out of signed int range" );
02238 return Int(value_.int_);
02239 case uintValue:
02240 JSON_ASSERT_MESSAGE( value_.uint_ <= UInt(maxInt), "unsigned integer out of signed int range" );
02241 return Int(value_.uint_);
02242 case realValue:
02243 JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
02244 return Int( value_.real_ );
02245 case booleanValue:
02246 return value_.bool_ ? 1 : 0;
02247 case stringValue:
02248 case arrayValue:
02249 case objectValue:
02250 JSON_FAIL_MESSAGE( "Type is not convertible to int" );
02251 default:
02252 JSON_ASSERT_UNREACHABLE;
02253 }
02254 return 0;
02255 }
02256
02257
02258 Value::UInt
02259 Value::asUInt() const
02260 {
02261 switch ( type_ )
02262 {
02263 case nullValue:
02264 return 0;
02265 case intValue:
02266 JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" );
02267 JSON_ASSERT_MESSAGE( value_.int_ <= maxUInt, "signed integer out of UInt range" );
02268 return UInt(value_.int_);
02269 case uintValue:
02270 JSON_ASSERT_MESSAGE( value_.uint_ <= maxUInt, "unsigned integer out of UInt range" );
02271 return UInt(value_.uint_);
02272 case realValue:
02273 JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" );
02274 return UInt( value_.real_ );
02275 case booleanValue:
02276 return value_.bool_ ? 1 : 0;
02277 case stringValue:
02278 case arrayValue:
02279 case objectValue:
02280 JSON_FAIL_MESSAGE( "Type is not convertible to uint" );
02281 default:
02282 JSON_ASSERT_UNREACHABLE;
02283 }
02284 return 0;
02285 }
02286
02287
02288 # if defined(JSON_HAS_INT64)
02289
02290 Value::Int64
02291 Value::asInt64() const
02292 {
02293 switch ( type_ )
02294 {
02295 case nullValue:
02296 return 0;
02297 case intValue:
02298 return value_.int_;
02299 case uintValue:
02300 JSON_ASSERT_MESSAGE( value_.uint_ <= UInt64(maxInt64), "unsigned integer out of Int64 range" );
02301 return value_.uint_;
02302 case realValue:
02303 JSON_ASSERT_MESSAGE( value_.real_ >= minInt64 && value_.real_ <= maxInt64, "Real out of Int64 range" );
02304 return Int( value_.real_ );
02305 case booleanValue:
02306 return value_.bool_ ? 1 : 0;
02307 case stringValue:
02308 case arrayValue:
02309 case objectValue:
02310 JSON_FAIL_MESSAGE( "Type is not convertible to Int64" );
02311 default:
02312 JSON_ASSERT_UNREACHABLE;
02313 }
02314 return 0;
02315 }
02316
02317
02318 Value::UInt64
02319 Value::asUInt64() const
02320 {
02321 switch ( type_ )
02322 {
02323 case nullValue:
02324 return 0;
02325 case intValue:
02326 JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to UInt64" );
02327 return value_.int_;
02328 case uintValue:
02329 return value_.uint_;
02330 case realValue:
02331 JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt64, "Real out of UInt64 range" );
02332 return UInt( value_.real_ );
02333 case booleanValue:
02334 return value_.bool_ ? 1 : 0;
02335 case stringValue:
02336 case arrayValue:
02337 case objectValue:
02338 JSON_FAIL_MESSAGE( "Type is not convertible to UInt64" );
02339 default:
02340 JSON_ASSERT_UNREACHABLE;
02341 }
02342 return 0;
02343 }
02344 # endif // if defined(JSON_HAS_INT64)
02345
02346
02347 LargestInt
02348 Value::asLargestInt() const
02349 {
02350 #if defined(JSON_NO_INT64)
02351 return asInt();
02352 #else
02353 return asInt64();
02354 #endif
02355 }
02356
02357
02358 LargestUInt
02359 Value::asLargestUInt() const
02360 {
02361 #if defined(JSON_NO_INT64)
02362 return asUInt();
02363 #else
02364 return asUInt64();
02365 #endif
02366 }
02367
02368
02369 double
02370 Value::asDouble() const
02371 {
02372 switch ( type_ )
02373 {
02374 case nullValue:
02375 return 0.0;
02376 case intValue:
02377 return static_cast<double>( value_.int_ );
02378 case uintValue:
02379 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
02380 return static_cast<double>( value_.uint_ );
02381 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
02382 return static_cast<double>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1);
02383 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
02384 case realValue:
02385 return value_.real_;
02386 case booleanValue:
02387 return value_.bool_ ? 1.0 : 0.0;
02388 case stringValue:
02389 case arrayValue:
02390 case objectValue:
02391 JSON_FAIL_MESSAGE( "Type is not convertible to double" );
02392 default:
02393 JSON_ASSERT_UNREACHABLE;
02394 }
02395 return 0;
02396 }
02397
02398 float
02399 Value::asFloat() const
02400 {
02401 switch ( type_ )
02402 {
02403 case nullValue:
02404 return 0.0f;
02405 case intValue:
02406 return static_cast<float>( value_.int_ );
02407 case uintValue:
02408 #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
02409 return static_cast<float>( value_.uint_ );
02410 #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
02411 return static_cast<float>( Int(value_.uint_/2) ) * 2 + Int(value_.uint_ & 1);
02412 #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
02413 case realValue:
02414 return static_cast<float>( value_.real_ );
02415 case booleanValue:
02416 return value_.bool_ ? 1.0f : 0.0f;
02417 case stringValue:
02418 case arrayValue:
02419 case objectValue:
02420 JSON_FAIL_MESSAGE( "Type is not convertible to float" );
02421 default:
02422 JSON_ASSERT_UNREACHABLE;
02423 }
02424 return 0.0f;
02425 }
02426
02427 bool
02428 Value::asBool() const
02429 {
02430 switch ( type_ )
02431 {
02432 case nullValue:
02433 return false;
02434 case intValue:
02435 case uintValue:
02436 return value_.int_ != 0;
02437 case realValue:
02438 return value_.real_ != 0.0;
02439 case booleanValue:
02440 return value_.bool_;
02441 case stringValue:
02442 return value_.string_ && value_.string_[0] != 0;
02443 case arrayValue:
02444 case objectValue:
02445 return value_.map_->size() != 0;
02446 default:
02447 JSON_ASSERT_UNREACHABLE;
02448 }
02449 return false;
02450 }
02451
02452
02453 bool
02454 Value::isConvertibleTo( ValueType other ) const
02455 {
02456 switch ( type_ )
02457 {
02458 case nullValue:
02459 return true;
02460 case intValue:
02461 return ( other == nullValue && value_.int_ == 0 )
02462 || other == intValue
02463 || ( other == uintValue && value_.int_ >= 0 )
02464 || other == realValue
02465 || other == stringValue
02466 || other == booleanValue;
02467 case uintValue:
02468 return ( other == nullValue && value_.uint_ == 0 )
02469 || ( other == intValue && value_.uint_ <= (unsigned)maxInt )
02470 || other == uintValue
02471 || other == realValue
02472 || other == stringValue
02473 || other == booleanValue;
02474 case realValue:
02475 return ( other == nullValue && value_.real_ == 0.0 )
02476 || ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt )
02477 || ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt )
02478 || other == realValue
02479 || other == stringValue
02480 || other == booleanValue;
02481 case booleanValue:
02482 return ( other == nullValue && value_.bool_ == false )
02483 || other == intValue
02484 || other == uintValue
02485 || other == realValue
02486 || other == stringValue
02487 || other == booleanValue;
02488 case stringValue:
02489 return other == stringValue
02490 || ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) );
02491 case arrayValue:
02492 return other == arrayValue
02493 || ( other == nullValue && value_.map_->size() == 0 );
02494 case objectValue:
02495 return other == objectValue
02496 || ( other == nullValue && value_.map_->size() == 0 );
02497 default:
02498 JSON_ASSERT_UNREACHABLE;
02499 }
02500 return false;
02501 }
02502
02503
02505 ArrayIndex
02506 Value::size() const
02507 {
02508 switch ( type_ )
02509 {
02510 case nullValue:
02511 case intValue:
02512 case uintValue:
02513 case realValue:
02514 case booleanValue:
02515 case stringValue:
02516 return 0;
02517 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02518 case arrayValue:
02519 if ( !value_.map_->empty() )
02520 {
02521 ObjectValues::const_iterator itLast = value_.map_->end();
02522 --itLast;
02523 return (*itLast).first.index()+1;
02524 }
02525 return 0;
02526 case objectValue:
02527 return ArrayIndex( value_.map_->size() );
02528 #else
02529 case arrayValue:
02530 return Int( value_.array_->size() );
02531 case objectValue:
02532 return Int( value_.map_->size() );
02533 #endif
02534 default:
02535 JSON_ASSERT_UNREACHABLE;
02536 }
02537 return 0;
02538 }
02539
02540
02541 bool
02542 Value::empty() const
02543 {
02544 if ( isNull() || isArray() || isObject() )
02545 return size() == 0u;
02546 else
02547 return false;
02548 }
02549
02550
02551 bool
02552 Value::operator!() const
02553 {
02554 return isNull();
02555 }
02556
02557
02558 void
02559 Value::clear()
02560 {
02561 JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue );
02562
02563 switch ( type_ )
02564 {
02565 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02566 case arrayValue:
02567 case objectValue:
02568 value_.map_->clear();
02569 break;
02570 #else
02571 case arrayValue:
02572 value_.array_->clear();
02573 break;
02574 case objectValue:
02575 value_.map_->clear();
02576 break;
02577 #endif
02578 default:
02579 break;
02580 }
02581 }
02582
02583 void
02584 Value::resize( ArrayIndex newSize )
02585 {
02586 JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
02587 if ( type_ == nullValue )
02588 *this = Value( arrayValue );
02589 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02590 ArrayIndex oldSize = size();
02591 if ( newSize == 0 )
02592 clear();
02593 else if ( newSize > oldSize )
02594 (*this)[ newSize - 1 ];
02595 else
02596 {
02597 for ( ArrayIndex index = newSize; index < oldSize; ++index )
02598 {
02599 value_.map_->erase( index );
02600 }
02601 assert( size() == newSize );
02602 }
02603 #else
02604 value_.array_->resize( newSize );
02605 #endif
02606 }
02607
02608
02609 Value &
02610 Value::operator[]( ArrayIndex index )
02611 {
02612 JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
02613 if ( type_ == nullValue )
02614 *this = Value( arrayValue );
02615 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02616 CZString key( index );
02617 ObjectValues::iterator it = value_.map_->lower_bound( key );
02618 if ( it != value_.map_->end() && (*it).first == key )
02619 return (*it).second;
02620
02621 ObjectValues::value_type defaultValue( key, null );
02622 it = value_.map_->insert( it, defaultValue );
02623 return (*it).second;
02624 #else
02625 return value_.array_->resolveReference( index );
02626 #endif
02627 }
02628
02629
02630 Value &
02631 Value::operator[]( int index )
02632 {
02633 JSON_ASSERT( index >= 0 );
02634 return (*this)[ ArrayIndex(index) ];
02635 }
02636
02637
02638 const Value &
02639 Value::operator[]( ArrayIndex index ) const
02640 {
02641 JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
02642 if ( type_ == nullValue )
02643 return null;
02644 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02645 CZString key( index );
02646 ObjectValues::const_iterator it = value_.map_->find( key );
02647 if ( it == value_.map_->end() )
02648 return null;
02649 return (*it).second;
02650 #else
02651 Value *value = value_.array_->find( index );
02652 return value ? *value : null;
02653 #endif
02654 }
02655
02656
02657 const Value &
02658 Value::operator[]( int index ) const
02659 {
02660 JSON_ASSERT( index >= 0 );
02661 return (*this)[ ArrayIndex(index) ];
02662 }
02663
02664
02665 Value &
02666 Value::operator[]( const char *key )
02667 {
02668 return resolveReference( key, false );
02669 }
02670
02671
02672 Value &
02673 Value::resolveReference( const char *key,
02674 bool isStatic )
02675 {
02676 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
02677 if ( type_ == nullValue )
02678 *this = Value( objectValue );
02679 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02680 CZString actualKey( key, isStatic ? CZString::noDuplication
02681 : CZString::duplicateOnCopy );
02682 ObjectValues::iterator it = value_.map_->lower_bound( actualKey );
02683 if ( it != value_.map_->end() && (*it).first == actualKey )
02684 return (*it).second;
02685
02686 ObjectValues::value_type defaultValue( actualKey, null );
02687 it = value_.map_->insert( it, defaultValue );
02688 Value &value = (*it).second;
02689 return value;
02690 #else
02691 return value_.map_->resolveReference( key, isStatic );
02692 #endif
02693 }
02694
02695
02696 Value
02697 Value::get( ArrayIndex index,
02698 const Value &defaultValue ) const
02699 {
02700 const Value *value = &((*this)[index]);
02701 return value == &null ? defaultValue : *value;
02702 }
02703
02704
02705 bool
02706 Value::isValidIndex( ArrayIndex index ) const
02707 {
02708 return index < size();
02709 }
02710
02711
02712
02713 const Value &
02714 Value::operator[]( const char *key ) const
02715 {
02716 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
02717 if ( type_ == nullValue )
02718 return null;
02719 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02720 CZString actualKey( key, CZString::noDuplication );
02721 ObjectValues::const_iterator it = value_.map_->find( actualKey );
02722 if ( it == value_.map_->end() )
02723 return null;
02724 return (*it).second;
02725 #else
02726 const Value *value = value_.map_->find( key );
02727 return value ? *value : null;
02728 #endif
02729 }
02730
02731
02732 Value &
02733 Value::operator[]( const std::string &key )
02734 {
02735 return (*this)[ key.c_str() ];
02736 }
02737
02738
02739 const Value &
02740 Value::operator[]( const std::string &key ) const
02741 {
02742 return (*this)[ key.c_str() ];
02743 }
02744
02745 Value &
02746 Value::operator[]( const StaticString &key )
02747 {
02748 return resolveReference( key, true );
02749 }
02750
02751
02752 # ifdef JSON_USE_CPPTL
02753 Value &
02754 Value::operator[]( const CppTL::ConstString &key )
02755 {
02756 return (*this)[ key.c_str() ];
02757 }
02758
02759
02760 const Value &
02761 Value::operator[]( const CppTL::ConstString &key ) const
02762 {
02763 return (*this)[ key.c_str() ];
02764 }
02765 # endif
02766
02767
02768 Value &
02769 Value::append( const Value &value )
02770 {
02771 return (*this)[size()] = value;
02772 }
02773
02774
02775 Value
02776 Value::get( const char *key,
02777 const Value &defaultValue ) const
02778 {
02779 const Value *value = &((*this)[key]);
02780 return value == &null ? defaultValue : *value;
02781 }
02782
02783
02784 Value
02785 Value::get( const std::string &key,
02786 const Value &defaultValue ) const
02787 {
02788 return get( key.c_str(), defaultValue );
02789 }
02790
02791 Value
02792 Value::removeMember( const char* key )
02793 {
02794 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
02795 if ( type_ == nullValue )
02796 return null;
02797 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02798 CZString actualKey( key, CZString::noDuplication );
02799 ObjectValues::iterator it = value_.map_->find( actualKey );
02800 if ( it == value_.map_->end() )
02801 return null;
02802 Value old(it->second);
02803 value_.map_->erase(it);
02804 return old;
02805 #else
02806 Value *value = value_.map_->find( key );
02807 if (value){
02808 Value old(*value);
02809 value_.map_.remove( key );
02810 return old;
02811 } else {
02812 return null;
02813 }
02814 #endif
02815 }
02816
02817 Value
02818 Value::removeMember( const std::string &key )
02819 {
02820 return removeMember( key.c_str() );
02821 }
02822
02823 # ifdef JSON_USE_CPPTL
02824 Value
02825 Value::get( const CppTL::ConstString &key,
02826 const Value &defaultValue ) const
02827 {
02828 return get( key.c_str(), defaultValue );
02829 }
02830 # endif
02831
02832 bool
02833 Value::isMember( const char *key ) const
02834 {
02835 const Value *value = &((*this)[key]);
02836 return value != &null;
02837 }
02838
02839
02840 bool
02841 Value::isMember( const std::string &key ) const
02842 {
02843 return isMember( key.c_str() );
02844 }
02845
02846
02847 # ifdef JSON_USE_CPPTL
02848 bool
02849 Value::isMember( const CppTL::ConstString &key ) const
02850 {
02851 return isMember( key.c_str() );
02852 }
02853 #endif
02854
02855 Value::Members
02856 Value::getMemberNames() const
02857 {
02858 JSON_ASSERT( type_ == nullValue || type_ == objectValue );
02859 if ( type_ == nullValue )
02860 return Value::Members();
02861 Members members;
02862 members.reserve( value_.map_->size() );
02863 #ifndef JSON_VALUE_USE_INTERNAL_MAP
02864 ObjectValues::const_iterator it = value_.map_->begin();
02865 ObjectValues::const_iterator itEnd = value_.map_->end();
02866 for ( ; it != itEnd; ++it )
02867 members.push_back( std::string( (*it).first.c_str() ) );
02868 #else
02869 ValueInternalMap::IteratorState it;
02870 ValueInternalMap::IteratorState itEnd;
02871 value_.map_->makeBeginIterator( it );
02872 value_.map_->makeEndIterator( itEnd );
02873 for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) )
02874 members.push_back( std::string( ValueInternalMap::key( it ) ) );
02875 #endif
02876 return members;
02877 }
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905 bool
02906 Value::isNull() const
02907 {
02908 return type_ == nullValue;
02909 }
02910
02911
02912 bool
02913 Value::isBool() const
02914 {
02915 return type_ == booleanValue;
02916 }
02917
02918
02919 bool
02920 Value::isInt() const
02921 {
02922 return type_ == intValue;
02923 }
02924
02925
02926 bool
02927 Value::isUInt() const
02928 {
02929 return type_ == uintValue;
02930 }
02931
02932
02933 bool
02934 Value::isIntegral() const
02935 {
02936 return type_ == intValue
02937 || type_ == uintValue
02938 || type_ == booleanValue;
02939 }
02940
02941
02942 bool
02943 Value::isDouble() const
02944 {
02945 return type_ == realValue;
02946 }
02947
02948
02949 bool
02950 Value::isNumeric() const
02951 {
02952 return isIntegral() || isDouble();
02953 }
02954
02955
02956 bool
02957 Value::isString() const
02958 {
02959 return type_ == stringValue;
02960 }
02961
02962
02963 bool
02964 Value::isArray() const
02965 {
02966 return type_ == nullValue || type_ == arrayValue;
02967 }
02968
02969
02970 bool
02971 Value::isObject() const
02972 {
02973 return type_ == nullValue || type_ == objectValue;
02974 }
02975
02976
02977 void
02978 Value::setComment( const char *comment,
02979 CommentPlacement placement )
02980 {
02981 if ( !comments_ )
02982 comments_ = new CommentInfo[numberOfCommentPlacement];
02983 comments_[placement].setComment( comment );
02984 }
02985
02986
02987 void
02988 Value::setComment( const std::string &comment,
02989 CommentPlacement placement )
02990 {
02991 setComment( comment.c_str(), placement );
02992 }
02993
02994
02995 bool
02996 Value::hasComment( CommentPlacement placement ) const
02997 {
02998 return comments_ != 0 && comments_[placement].comment_ != 0;
02999 }
03000
03001 std::string
03002 Value::getComment( CommentPlacement placement ) const
03003 {
03004 if ( hasComment(placement) )
03005 return comments_[placement].comment_;
03006 return "";
03007 }
03008
03009
03010 std::string
03011 Value::toStyledString() const
03012 {
03013 StyledWriter writer;
03014 return writer.write( *this );
03015 }
03016
03017
03018 Value::const_iterator
03019 Value::begin() const
03020 {
03021 switch ( type_ )
03022 {
03023 #ifdef JSON_VALUE_USE_INTERNAL_MAP
03024 case arrayValue:
03025 if ( value_.array_ )
03026 {
03027 ValueInternalArray::IteratorState it;
03028 value_.array_->makeBeginIterator( it );
03029 return const_iterator( it );
03030 }
03031 break;
03032 case objectValue:
03033 if ( value_.map_ )
03034 {
03035 ValueInternalMap::IteratorState it;
03036 value_.map_->makeBeginIterator( it );
03037 return const_iterator( it );
03038 }
03039 break;
03040 #else
03041 case arrayValue:
03042 case objectValue:
03043 if ( value_.map_ )
03044 return const_iterator( value_.map_->begin() );
03045 break;
03046 #endif
03047 default:
03048 break;
03049 }
03050 return const_iterator();
03051 }
03052
03053 Value::const_iterator
03054 Value::end() const
03055 {
03056 switch ( type_ )
03057 {
03058 #ifdef JSON_VALUE_USE_INTERNAL_MAP
03059 case arrayValue:
03060 if ( value_.array_ )
03061 {
03062 ValueInternalArray::IteratorState it;
03063 value_.array_->makeEndIterator( it );
03064 return const_iterator( it );
03065 }
03066 break;
03067 case objectValue:
03068 if ( value_.map_ )
03069 {
03070 ValueInternalMap::IteratorState it;
03071 value_.map_->makeEndIterator( it );
03072 return const_iterator( it );
03073 }
03074 break;
03075 #else
03076 case arrayValue:
03077 case objectValue:
03078 if ( value_.map_ )
03079 return const_iterator( value_.map_->end() );
03080 break;
03081 #endif
03082 default:
03083 break;
03084 }
03085 return const_iterator();
03086 }
03087
03088
03089 Value::iterator
03090 Value::begin()
03091 {
03092 switch ( type_ )
03093 {
03094 #ifdef JSON_VALUE_USE_INTERNAL_MAP
03095 case arrayValue:
03096 if ( value_.array_ )
03097 {
03098 ValueInternalArray::IteratorState it;
03099 value_.array_->makeBeginIterator( it );
03100 return iterator( it );
03101 }
03102 break;
03103 case objectValue:
03104 if ( value_.map_ )
03105 {
03106 ValueInternalMap::IteratorState it;
03107 value_.map_->makeBeginIterator( it );
03108 return iterator( it );
03109 }
03110 break;
03111 #else
03112 case arrayValue:
03113 case objectValue:
03114 if ( value_.map_ )
03115 return iterator( value_.map_->begin() );
03116 break;
03117 #endif
03118 default:
03119 break;
03120 }
03121 return iterator();
03122 }
03123
03124 Value::iterator
03125 Value::end()
03126 {
03127 switch ( type_ )
03128 {
03129 #ifdef JSON_VALUE_USE_INTERNAL_MAP
03130 case arrayValue:
03131 if ( value_.array_ )
03132 {
03133 ValueInternalArray::IteratorState it;
03134 value_.array_->makeEndIterator( it );
03135 return iterator( it );
03136 }
03137 break;
03138 case objectValue:
03139 if ( value_.map_ )
03140 {
03141 ValueInternalMap::IteratorState it;
03142 value_.map_->makeEndIterator( it );
03143 return iterator( it );
03144 }
03145 break;
03146 #else
03147 case arrayValue:
03148 case objectValue:
03149 if ( value_.map_ )
03150 return iterator( value_.map_->end() );
03151 break;
03152 #endif
03153 default:
03154 break;
03155 }
03156 return iterator();
03157 }
03158
03159
03160
03161
03162
03163 PathArgument::PathArgument()
03164 : kind_( kindNone )
03165 {
03166 }
03167
03168
03169 PathArgument::PathArgument( ArrayIndex index )
03170 : index_( index )
03171 , kind_( kindIndex )
03172 {
03173 }
03174
03175
03176 PathArgument::PathArgument( const char *key )
03177 : key_( key )
03178 , kind_( kindKey )
03179 {
03180 }
03181
03182
03183 PathArgument::PathArgument( const std::string &key )
03184 : key_( key.c_str() )
03185 , kind_( kindKey )
03186 {
03187 }
03188
03189
03190
03191
03192 Path::Path( const std::string &path,
03193 const PathArgument &a1,
03194 const PathArgument &a2,
03195 const PathArgument &a3,
03196 const PathArgument &a4,
03197 const PathArgument &a5 )
03198 {
03199 InArgs in;
03200 in.push_back( &a1 );
03201 in.push_back( &a2 );
03202 in.push_back( &a3 );
03203 in.push_back( &a4 );
03204 in.push_back( &a5 );
03205 makePath( path, in );
03206 }
03207
03208
03209 void
03210 Path::makePath( const std::string &path,
03211 const InArgs &in )
03212 {
03213 const char *current = path.c_str();
03214 const char *end = current + path.length();
03215 InArgs::const_iterator itInArg = in.begin();
03216 while ( current != end )
03217 {
03218 if ( *current == '[' )
03219 {
03220 ++current;
03221 if ( *current == '%' )
03222 addPathInArg( path, in, itInArg, PathArgument::kindIndex );
03223 else
03224 {
03225 ArrayIndex index = 0;
03226 for ( ; current != end && *current >= '0' && *current <= '9'; ++current )
03227 index = index * 10 + ArrayIndex(*current - '0');
03228 args_.push_back( index );
03229 }
03230 if ( current == end || *current++ != ']' )
03231 invalidPath( path, int(current - path.c_str()) );
03232 }
03233 else if ( *current == '%' )
03234 {
03235 addPathInArg( path, in, itInArg, PathArgument::kindKey );
03236 ++current;
03237 }
03238 else if ( *current == '.' )
03239 {
03240 ++current;
03241 }
03242 else
03243 {
03244 const char *beginName = current;
03245 while ( current != end && !strchr( "[.", *current ) )
03246 ++current;
03247 args_.push_back( std::string( beginName, current ) );
03248 }
03249 }
03250 }
03251
03252
03253 void
03254 Path::addPathInArg( const std::string &path,
03255 const InArgs &in,
03256 InArgs::const_iterator &itInArg,
03257 PathArgument::Kind kind )
03258 {
03259 if ( itInArg == in.end() )
03260 {
03261
03262 }
03263 else if ( (*itInArg)->kind_ != kind )
03264 {
03265
03266 }
03267 else
03268 {
03269 args_.push_back( **itInArg );
03270 }
03271 }
03272
03273
03274 void
03275 Path::invalidPath( const std::string &path,
03276 int location )
03277 {
03278
03279 }
03280
03281
03282 const Value &
03283 Path::resolve( const Value &root ) const
03284 {
03285 const Value *node = &root;
03286 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
03287 {
03288 const PathArgument &arg = *it;
03289 if ( arg.kind_ == PathArgument::kindIndex )
03290 {
03291 if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
03292 {
03293
03294 }
03295 node = &((*node)[arg.index_]);
03296 }
03297 else if ( arg.kind_ == PathArgument::kindKey )
03298 {
03299 if ( !node->isObject() )
03300 {
03301
03302 }
03303 node = &((*node)[arg.key_]);
03304 if ( node == &Value::null )
03305 {
03306
03307 }
03308 }
03309 }
03310 return *node;
03311 }
03312
03313
03314 Value
03315 Path::resolve( const Value &root,
03316 const Value &defaultValue ) const
03317 {
03318 const Value *node = &root;
03319 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
03320 {
03321 const PathArgument &arg = *it;
03322 if ( arg.kind_ == PathArgument::kindIndex )
03323 {
03324 if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
03325 return defaultValue;
03326 node = &((*node)[arg.index_]);
03327 }
03328 else if ( arg.kind_ == PathArgument::kindKey )
03329 {
03330 if ( !node->isObject() )
03331 return defaultValue;
03332 node = &((*node)[arg.key_]);
03333 if ( node == &Value::null )
03334 return defaultValue;
03335 }
03336 }
03337 return *node;
03338 }
03339
03340
03341 Value &
03342 Path::make( Value &root ) const
03343 {
03344 Value *node = &root;
03345 for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
03346 {
03347 const PathArgument &arg = *it;
03348 if ( arg.kind_ == PathArgument::kindIndex )
03349 {
03350 if ( !node->isArray() )
03351 {
03352
03353 }
03354 node = &((*node)[arg.index_]);
03355 }
03356 else if ( arg.kind_ == PathArgument::kindKey )
03357 {
03358 if ( !node->isObject() )
03359 {
03360
03361 }
03362 node = &((*node)[arg.key_]);
03363 }
03364 }
03365 return *node;
03366 }
03367
03368
03369 }
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389 #if !defined(JSON_IS_AMALGAMATION)
03390 # include <json/writer.h>
03391 # include "json_tool.h"
03392 #endif // if !defined(JSON_IS_AMALGAMATION)
03393 #include <utility>
03394 #include <assert.h>
03395 #include <stdio.h>
03396 #include <string.h>
03397 #include <iostream>
03398 #include <sstream>
03399 #include <iomanip>
03400
03401 #if _MSC_VER >= 1400 // VC++ 8.0
03402 #pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
03403 #endif
03404
03405 namespace Json {
03406
03407 static bool containsControlCharacter( const char* str )
03408 {
03409 while ( *str )
03410 {
03411 if ( isControlCharacter( *(str++) ) )
03412 return true;
03413 }
03414 return false;
03415 }
03416
03417
03418 std::string valueToString( LargestInt value )
03419 {
03420 UIntToStringBuffer buffer;
03421 char *current = buffer + sizeof(buffer);
03422 bool isNegative = value < 0;
03423 if ( isNegative )
03424 value = -value;
03425 uintToString( LargestUInt(value), current );
03426 if ( isNegative )
03427 *--current = '-';
03428 assert( current >= buffer );
03429 return current;
03430 }
03431
03432
03433 std::string valueToString( LargestUInt value )
03434 {
03435 UIntToStringBuffer buffer;
03436 char *current = buffer + sizeof(buffer);
03437 uintToString( value, current );
03438 assert( current >= buffer );
03439 return current;
03440 }
03441
03442 #if defined(JSON_HAS_INT64)
03443
03444 std::string valueToString( Int value )
03445 {
03446 return valueToString( LargestInt(value) );
03447 }
03448
03449
03450 std::string valueToString( UInt value )
03451 {
03452 return valueToString( LargestUInt(value) );
03453 }
03454
03455 #endif // # if defined(JSON_HAS_INT64)
03456
03457
03458 std::string valueToString( double value )
03459 {
03460 char buffer[32];
03461 #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning.
03462 sprintf_s(buffer, sizeof(buffer), "%#.16g", value);
03463 #else
03464 sprintf(buffer, "%#.16g", value);
03465 #endif
03466 char* ch = buffer + strlen(buffer) - 1;
03467 if (*ch != '0') return buffer;
03468 while(ch > buffer && *ch == '0'){
03469 --ch;
03470 }
03471 char* last_nonzero = ch;
03472 while(ch >= buffer){
03473 switch(*ch){
03474 case '0':
03475 case '1':
03476 case '2':
03477 case '3':
03478 case '4':
03479 case '5':
03480 case '6':
03481 case '7':
03482 case '8':
03483 case '9':
03484 --ch;
03485 continue;
03486 case '.':
03487
03488 *(last_nonzero+2) = '\0';
03489 return buffer;
03490 default:
03491 return buffer;
03492 }
03493 }
03494 return buffer;
03495 }
03496
03497
03498 std::string valueToString( bool value )
03499 {
03500 return value ? "true" : "false";
03501 }
03502
03503 std::string valueToQuotedString( const char *value )
03504 {
03505
03506 if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value ))
03507 return std::string("\"") + value + "\"";
03508
03509
03510
03511 std::string::size_type maxsize = strlen(value)*2 + 3;
03512 std::string result;
03513 result.reserve(maxsize);
03514 result += "\"";
03515 for (const char* c=value; *c != 0; ++c)
03516 {
03517 switch(*c)
03518 {
03519 case '\"':
03520 result += "\\\"";
03521 break;
03522 case '\\':
03523 result += "\\\\";
03524 break;
03525 case '\b':
03526 result += "\\b";
03527 break;
03528 case '\f':
03529 result += "\\f";
03530 break;
03531 case '\n':
03532 result += "\\n";
03533 break;
03534 case '\r':
03535 result += "\\r";
03536 break;
03537 case '\t':
03538 result += "\\t";
03539 break;
03540
03541
03542
03543
03544
03545
03546
03547
03548 default:
03549 if ( isControlCharacter( *c ) )
03550 {
03551 std::ostringstream oss;
03552 oss << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*c);
03553 result += oss.str();
03554 }
03555 else
03556 {
03557 result += *c;
03558 }
03559 break;
03560 }
03561 }
03562 result += "\"";
03563 return result;
03564 }
03565
03566
03567
03568 Writer::~Writer()
03569 {
03570 }
03571
03572
03573
03574
03575
03576 FastWriter::FastWriter()
03577 : yamlCompatiblityEnabled_( false )
03578 {
03579 }
03580
03581
03582 void
03583 FastWriter::enableYAMLCompatibility()
03584 {
03585 yamlCompatiblityEnabled_ = true;
03586 }
03587
03588
03589 std::string
03590 FastWriter::write( const Value &root )
03591 {
03592 document_ = "";
03593 writeValue( root );
03594 document_ += "\n";
03595 return document_;
03596 }
03597
03598
03599 void
03600 FastWriter::writeValue( const Value &value )
03601 {
03602 switch ( value.type() )
03603 {
03604 case nullValue:
03605 document_ += "null";
03606 break;
03607 case intValue:
03608 document_ += valueToString( value.asLargestInt() );
03609 break;
03610 case uintValue:
03611 document_ += valueToString( value.asLargestUInt() );
03612 break;
03613 case realValue:
03614 document_ += valueToString( value.asDouble() );
03615 break;
03616 case stringValue:
03617 document_ += valueToQuotedString( value.asCString() );
03618 break;
03619 case booleanValue:
03620 document_ += valueToString( value.asBool() );
03621 break;
03622 case arrayValue:
03623 {
03624 document_ += "[";
03625 int size = value.size();
03626 for ( int index =0; index < size; ++index )
03627 {
03628 if ( index > 0 )
03629 document_ += ",";
03630 writeValue( value[index] );
03631 }
03632 document_ += "]";
03633 }
03634 break;
03635 case objectValue:
03636 {
03637 Value::Members members( value.getMemberNames() );
03638 document_ += "{";
03639 for ( Value::Members::iterator it = members.begin();
03640 it != members.end();
03641 ++it )
03642 {
03643 const std::string &name = *it;
03644 if ( it != members.begin() )
03645 document_ += ",";
03646 document_ += valueToQuotedString( name.c_str() );
03647 document_ += yamlCompatiblityEnabled_ ? ": "
03648 : ":";
03649 writeValue( value[name] );
03650 }
03651 document_ += "}";
03652 }
03653 break;
03654 }
03655 }
03656
03657
03658
03659
03660
03661 StyledWriter::StyledWriter()
03662 : rightMargin_( 74 )
03663 , indentSize_( 3 )
03664 {
03665 }
03666
03667
03668 std::string
03669 StyledWriter::write( const Value &root )
03670 {
03671 document_ = "";
03672 addChildValues_ = false;
03673 indentString_ = "";
03674 writeCommentBeforeValue( root );
03675 writeValue( root );
03676 writeCommentAfterValueOnSameLine( root );
03677 document_ += "\n";
03678 return document_;
03679 }
03680
03681
03682 void
03683 StyledWriter::writeValue( const Value &value )
03684 {
03685 switch ( value.type() )
03686 {
03687 case nullValue:
03688 pushValue( "null" );
03689 break;
03690 case intValue:
03691 pushValue( valueToString( value.asLargestInt() ) );
03692 break;
03693 case uintValue:
03694 pushValue( valueToString( value.asLargestUInt() ) );
03695 break;
03696 case realValue:
03697 pushValue( valueToString( value.asDouble() ) );
03698 break;
03699 case stringValue:
03700 pushValue( valueToQuotedString( value.asCString() ) );
03701 break;
03702 case booleanValue:
03703 pushValue( valueToString( value.asBool() ) );
03704 break;
03705 case arrayValue:
03706 writeArrayValue( value);
03707 break;
03708 case objectValue:
03709 {
03710 Value::Members members( value.getMemberNames() );
03711 if ( members.empty() )
03712 pushValue( "{}" );
03713 else
03714 {
03715 writeWithIndent( "{" );
03716 indent();
03717 Value::Members::iterator it = members.begin();
03718 for (;;)
03719 {
03720 const std::string &name = *it;
03721 const Value &childValue = value[name];
03722 writeCommentBeforeValue( childValue );
03723 writeWithIndent( valueToQuotedString( name.c_str() ) );
03724 document_ += " : ";
03725 writeValue( childValue );
03726 if ( ++it == members.end() )
03727 {
03728 writeCommentAfterValueOnSameLine( childValue );
03729 break;
03730 }
03731 document_ += ",";
03732 writeCommentAfterValueOnSameLine( childValue );
03733 }
03734 unindent();
03735 writeWithIndent( "}" );
03736 }
03737 }
03738 break;
03739 }
03740 }
03741
03742
03743 void
03744 StyledWriter::writeArrayValue( const Value &value )
03745 {
03746 unsigned size = value.size();
03747 if ( size == 0 )
03748 pushValue( "[]" );
03749 else
03750 {
03751 bool isArrayMultiLine = isMultineArray( value );
03752 if ( isArrayMultiLine )
03753 {
03754 writeWithIndent( "[" );
03755 indent();
03756 bool hasChildValue = !childValues_.empty();
03757 unsigned index =0;
03758 for (;;)
03759 {
03760 const Value &childValue = value[index];
03761 writeCommentBeforeValue( childValue );
03762 if ( hasChildValue )
03763 writeWithIndent( childValues_[index] );
03764 else
03765 {
03766 writeIndent();
03767 writeValue( childValue );
03768 }
03769 if ( ++index == size )
03770 {
03771 writeCommentAfterValueOnSameLine( childValue );
03772 break;
03773 }
03774 document_ += ",";
03775 writeCommentAfterValueOnSameLine( childValue );
03776 }
03777 unindent();
03778 writeWithIndent( "]" );
03779 }
03780 else
03781 {
03782 assert( childValues_.size() == size );
03783 document_ += "[ ";
03784 for ( unsigned index =0; index < size; ++index )
03785 {
03786 if ( index > 0 )
03787 document_ += ", ";
03788 document_ += childValues_[index];
03789 }
03790 document_ += " ]";
03791 }
03792 }
03793 }
03794
03795
03796 bool
03797 StyledWriter::isMultineArray( const Value &value )
03798 {
03799 int size = value.size();
03800 bool isMultiLine = size*3 >= rightMargin_ ;
03801 childValues_.clear();
03802 for ( int index =0; index < size && !isMultiLine; ++index )
03803 {
03804 const Value &childValue = value[index];
03805 isMultiLine = isMultiLine ||
03806 ( (childValue.isArray() || childValue.isObject()) &&
03807 childValue.size() > 0 );
03808 }
03809 if ( !isMultiLine )
03810 {
03811 childValues_.reserve( size );
03812 addChildValues_ = true;
03813 int lineLength = 4 + (size-1)*2;
03814 for ( int index =0; index < size && !isMultiLine; ++index )
03815 {
03816 writeValue( value[index] );
03817 lineLength += int( childValues_[index].length() );
03818 isMultiLine = isMultiLine && hasCommentForValue( value[index] );
03819 }
03820 addChildValues_ = false;
03821 isMultiLine = isMultiLine || lineLength >= rightMargin_;
03822 }
03823 return isMultiLine;
03824 }
03825
03826
03827 void
03828 StyledWriter::pushValue( const std::string &value )
03829 {
03830 if ( addChildValues_ )
03831 childValues_.push_back( value );
03832 else
03833 document_ += value;
03834 }
03835
03836
03837 void
03838 StyledWriter::writeIndent()
03839 {
03840 if ( !document_.empty() )
03841 {
03842 char last = document_[document_.length()-1];
03843 if ( last == ' ' )
03844 return;
03845 if ( last != '\n' )
03846 document_ += '\n';
03847 }
03848 document_ += indentString_;
03849 }
03850
03851
03852 void
03853 StyledWriter::writeWithIndent( const std::string &value )
03854 {
03855 writeIndent();
03856 document_ += value;
03857 }
03858
03859
03860 void
03861 StyledWriter::indent()
03862 {
03863 indentString_ += std::string( indentSize_, ' ' );
03864 }
03865
03866
03867 void
03868 StyledWriter::unindent()
03869 {
03870 assert( int(indentString_.size()) >= indentSize_ );
03871 indentString_.resize( indentString_.size() - indentSize_ );
03872 }
03873
03874
03875 void
03876 StyledWriter::writeCommentBeforeValue( const Value &root )
03877 {
03878 if ( !root.hasComment( commentBefore ) )
03879 return;
03880 document_ += normalizeEOL( root.getComment( commentBefore ) );
03881 document_ += "\n";
03882 }
03883
03884
03885 void
03886 StyledWriter::writeCommentAfterValueOnSameLine( const Value &root )
03887 {
03888 if ( root.hasComment( commentAfterOnSameLine ) )
03889 document_ += " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
03890
03891 if ( root.hasComment( commentAfter ) )
03892 {
03893 document_ += "\n";
03894 document_ += normalizeEOL( root.getComment( commentAfter ) );
03895 document_ += "\n";
03896 }
03897 }
03898
03899
03900 bool
03901 StyledWriter::hasCommentForValue( const Value &value )
03902 {
03903 return value.hasComment( commentBefore )
03904 || value.hasComment( commentAfterOnSameLine )
03905 || value.hasComment( commentAfter );
03906 }
03907
03908
03909 std::string
03910 StyledWriter::normalizeEOL( const std::string &text )
03911 {
03912 std::string normalized;
03913 normalized.reserve( text.length() );
03914 const char *begin = text.c_str();
03915 const char *end = begin + text.length();
03916 const char *current = begin;
03917 while ( current != end )
03918 {
03919 char c = *current++;
03920 if ( c == '\r' )
03921 {
03922 if ( *current == '\n' )
03923 ++current;
03924 normalized += '\n';
03925 }
03926 else
03927 normalized += c;
03928 }
03929 return normalized;
03930 }
03931
03932
03933
03934
03935
03936 StyledStreamWriter::StyledStreamWriter( std::string indentation )
03937 : document_(NULL)
03938 , rightMargin_( 74 )
03939 , indentation_( indentation )
03940 {
03941 }
03942
03943
03944 void
03945 StyledStreamWriter::write( std::ostream &out, const Value &root )
03946 {
03947 document_ = &out;
03948 addChildValues_ = false;
03949 indentString_ = "";
03950 writeCommentBeforeValue( root );
03951 writeValue( root );
03952 writeCommentAfterValueOnSameLine( root );
03953 *document_ << "\n";
03954 document_ = NULL;
03955 }
03956
03957
03958 void
03959 StyledStreamWriter::writeValue( const Value &value )
03960 {
03961 switch ( value.type() )
03962 {
03963 case nullValue:
03964 pushValue( "null" );
03965 break;
03966 case intValue:
03967 pushValue( valueToString( value.asLargestInt() ) );
03968 break;
03969 case uintValue:
03970 pushValue( valueToString( value.asLargestUInt() ) );
03971 break;
03972 case realValue:
03973 pushValue( valueToString( value.asDouble() ) );
03974 break;
03975 case stringValue:
03976 pushValue( valueToQuotedString( value.asCString() ) );
03977 break;
03978 case booleanValue:
03979 pushValue( valueToString( value.asBool() ) );
03980 break;
03981 case arrayValue:
03982 writeArrayValue( value);
03983 break;
03984 case objectValue:
03985 {
03986 Value::Members members( value.getMemberNames() );
03987 if ( members.empty() )
03988 pushValue( "{}" );
03989 else
03990 {
03991 writeWithIndent( "{" );
03992 indent();
03993 Value::Members::iterator it = members.begin();
03994 for (;;)
03995 {
03996 const std::string &name = *it;
03997 const Value &childValue = value[name];
03998 writeCommentBeforeValue( childValue );
03999 writeWithIndent( valueToQuotedString( name.c_str() ) );
04000 *document_ << " : ";
04001 writeValue( childValue );
04002 if ( ++it == members.end() )
04003 {
04004 writeCommentAfterValueOnSameLine( childValue );
04005 break;
04006 }
04007 *document_ << ",";
04008 writeCommentAfterValueOnSameLine( childValue );
04009 }
04010 unindent();
04011 writeWithIndent( "}" );
04012 }
04013 }
04014 break;
04015 }
04016 }
04017
04018
04019 void
04020 StyledStreamWriter::writeArrayValue( const Value &value )
04021 {
04022 unsigned size = value.size();
04023 if ( size == 0 )
04024 pushValue( "[]" );
04025 else
04026 {
04027 bool isArrayMultiLine = isMultineArray( value );
04028 if ( isArrayMultiLine )
04029 {
04030 writeWithIndent( "[" );
04031 indent();
04032 bool hasChildValue = !childValues_.empty();
04033 unsigned index =0;
04034 for (;;)
04035 {
04036 const Value &childValue = value[index];
04037 writeCommentBeforeValue( childValue );
04038 if ( hasChildValue )
04039 writeWithIndent( childValues_[index] );
04040 else
04041 {
04042 writeIndent();
04043 writeValue( childValue );
04044 }
04045 if ( ++index == size )
04046 {
04047 writeCommentAfterValueOnSameLine( childValue );
04048 break;
04049 }
04050 *document_ << ",";
04051 writeCommentAfterValueOnSameLine( childValue );
04052 }
04053 unindent();
04054 writeWithIndent( "]" );
04055 }
04056 else
04057 {
04058 assert( childValues_.size() == size );
04059 *document_ << "[ ";
04060 for ( unsigned index =0; index < size; ++index )
04061 {
04062 if ( index > 0 )
04063 *document_ << ", ";
04064 *document_ << childValues_[index];
04065 }
04066 *document_ << " ]";
04067 }
04068 }
04069 }
04070
04071
04072 bool
04073 StyledStreamWriter::isMultineArray( const Value &value )
04074 {
04075 int size = value.size();
04076 bool isMultiLine = size*3 >= rightMargin_ ;
04077 childValues_.clear();
04078 for ( int index =0; index < size && !isMultiLine; ++index )
04079 {
04080 const Value &childValue = value[index];
04081 isMultiLine = isMultiLine ||
04082 ( (childValue.isArray() || childValue.isObject()) &&
04083 childValue.size() > 0 );
04084 }
04085 if ( !isMultiLine )
04086 {
04087 childValues_.reserve( size );
04088 addChildValues_ = true;
04089 int lineLength = 4 + (size-1)*2;
04090 for ( int index =0; index < size && !isMultiLine; ++index )
04091 {
04092 writeValue( value[index] );
04093 lineLength += int( childValues_[index].length() );
04094 isMultiLine = isMultiLine && hasCommentForValue( value[index] );
04095 }
04096 addChildValues_ = false;
04097 isMultiLine = isMultiLine || lineLength >= rightMargin_;
04098 }
04099 return isMultiLine;
04100 }
04101
04102
04103 void
04104 StyledStreamWriter::pushValue( const std::string &value )
04105 {
04106 if ( addChildValues_ )
04107 childValues_.push_back( value );
04108 else
04109 *document_ << value;
04110 }
04111
04112
04113 void
04114 StyledStreamWriter::writeIndent()
04115 {
04116
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127
04128 *document_ << '\n' << indentString_;
04129 }
04130
04131
04132 void
04133 StyledStreamWriter::writeWithIndent( const std::string &value )
04134 {
04135 writeIndent();
04136 *document_ << value;
04137 }
04138
04139
04140 void
04141 StyledStreamWriter::indent()
04142 {
04143 indentString_ += indentation_;
04144 }
04145
04146
04147 void
04148 StyledStreamWriter::unindent()
04149 {
04150 assert( indentString_.size() >= indentation_.size() );
04151 indentString_.resize( indentString_.size() - indentation_.size() );
04152 }
04153
04154
04155 void
04156 StyledStreamWriter::writeCommentBeforeValue( const Value &root )
04157 {
04158 if ( !root.hasComment( commentBefore ) )
04159 return;
04160 *document_ << normalizeEOL( root.getComment( commentBefore ) );
04161 *document_ << "\n";
04162 }
04163
04164
04165 void
04166 StyledStreamWriter::writeCommentAfterValueOnSameLine( const Value &root )
04167 {
04168 if ( root.hasComment( commentAfterOnSameLine ) )
04169 *document_ << " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
04170
04171 if ( root.hasComment( commentAfter ) )
04172 {
04173 *document_ << "\n";
04174 *document_ << normalizeEOL( root.getComment( commentAfter ) );
04175 *document_ << "\n";
04176 }
04177 }
04178
04179
04180 bool
04181 StyledStreamWriter::hasCommentForValue( const Value &value )
04182 {
04183 return value.hasComment( commentBefore )
04184 || value.hasComment( commentAfterOnSameLine )
04185 || value.hasComment( commentAfter );
04186 }
04187
04188
04189 std::string
04190 StyledStreamWriter::normalizeEOL( const std::string &text )
04191 {
04192 std::string normalized;
04193 normalized.reserve( text.length() );
04194 const char *begin = text.c_str();
04195 const char *end = begin + text.length();
04196 const char *current = begin;
04197 while ( current != end )
04198 {
04199 char c = *current++;
04200 if ( c == '\r' )
04201 {
04202 if ( *current == '\n' )
04203 ++current;
04204 normalized += '\n';
04205 }
04206 else
04207 normalized += c;
04208 }
04209 return normalized;
04210 }
04211
04212
04213 std::ostream& operator<<( std::ostream &sout, const Value &root )
04214 {
04215 Json::StyledStreamWriter writer;
04216 writer.write(sout, root);
04217 return sout;
04218 }
04219
04220
04221 }
04222
04223
04224
04225
04226
04227
04228
04229
04230