jsoncpp.cpp
Go to the documentation of this file.
00001 
00002 
00003 
00004 // //////////////////////////////////////////////////////////////////////
00005 // Beginning of content of file: LICENSE
00006 // //////////////////////////////////////////////////////////////////////
00007 
00008 /*
00009 The JsonCpp library's source code, including accompanying documentation, 
00010 tests and demonstration applications, are licensed under the following
00011 conditions...
00012 
00013 The author (Baptiste Lepilleur) explicitly disclaims copyright in all 
00014 jurisdictions which recognize such a disclaimer. In such jurisdictions, 
00015 this software is released into the Public Domain.
00016 
00017 In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
00018 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
00019 released under the terms of the MIT License (see below).
00020 
00021 In jurisdictions which recognize Public Domain property, the user of this 
00022 software may choose to accept it either as 1) Public Domain, 2) under the 
00023 conditions of the MIT License (see below), or 3) under the terms of dual 
00024 Public Domain/MIT License conditions described here, as they choose.
00025 
00026 The MIT License is about as close to Public Domain as a license can get, and is
00027 described in clear, concise terms at:
00028 
00029    http://en.wikipedia.org/wiki/MIT_License
00030    
00031 The full text of the MIT License follows:
00032 
00033 ========================================================================
00034 Copyright (c) 2007-2010 Baptiste Lepilleur
00035 
00036 Permission is hereby granted, free of charge, to any person
00037 obtaining a copy of this software and associated documentation
00038 files (the "Software"), to deal in the Software without
00039 restriction, including without limitation the rights to use, copy,
00040 modify, merge, publish, distribute, sublicense, and/or sell copies
00041 of the Software, and to permit persons to whom the Software is
00042 furnished to do so, subject to the following conditions:
00043 
00044 The above copyright notice and this permission notice shall be
00045 included in all copies or substantial portions of the Software.
00046 
00047 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00048 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00049 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00050 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00051 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00052 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00053 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00054 SOFTWARE.
00055 ========================================================================
00056 (END LICENSE TEXT)
00057 
00058 The MIT license is compatible with both the GPL and commercial
00059 software, affording one all of the rights of Public Domain with the
00060 minor nuisance of being required to keep the above copyright notice
00061 and license text in the source code. Note also that by accepting the
00062 Public Domain "license" you can re-license your copy using whatever
00063 license you like.
00064 
00065 */
00066 
00067 // //////////////////////////////////////////////////////////////////////
00068 // End of content of file: LICENSE
00069 // //////////////////////////////////////////////////////////////////////
00070 
00071 
00072 
00073 
00074 
00075 
00076 #include <json/json.h>
00077 
00078 
00079 // //////////////////////////////////////////////////////////////////////
00080 // Beginning of content of file: src/lib_json/json_tool.h
00081 // //////////////////////////////////////////////////////////////////////
00082 
00083 // Copyright 2007-2010 Baptiste Lepilleur
00084 // Distributed under MIT license, or public domain if desired and
00085 // recognized in your jurisdiction.
00086 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
00087 
00088 #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
00089 # define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
00090 
00091 /* This header provides common string manipulation support, such as UTF-8,
00092  * portable conversion from/to string...
00093  *
00094  * It is an internal header that must not be exposed.
00095  */
00096 
00097 namespace Json {
00098 
00100 static inline std::string 
00101 codePointToUTF8(unsigned int cp)
00102 {
00103    std::string result;
00104    
00105    // based on description from http://en.wikipedia.org/wiki/UTF-8
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 // Defines a char buffer for use with uintToString().
00152 typedef char UIntToStringBuffer[uintToStringBufferSize];
00153 
00154 
00160 static inline void 
00161 uintToString( LargestUInt value, 
00162               char *&current )
00163 {
00164    *--current = 0;
00165    do
00166    {
00167       *--current = char(value % 10) + '0';
00168       value /= 10;
00169    }
00170    while ( value != 0 );
00171 }
00172 
00173 } // namespace Json {
00174 
00175 #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
00176 
00177 // //////////////////////////////////////////////////////////////////////
00178 // End of content of file: src/lib_json/json_tool.h
00179 // //////////////////////////////////////////////////////////////////////
00180 
00181 
00182 
00183 
00184 
00185 
00186 // //////////////////////////////////////////////////////////////////////
00187 // Beginning of content of file: src/lib_json/json_reader.cpp
00188 // //////////////////////////////////////////////////////////////////////
00189 
00190 // Copyright 2007-2010 Baptiste Lepilleur
00191 // Distributed under MIT license, or public domain if desired and
00192 // recognized in your jurisdiction.
00193 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
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 // Implementation of class Features
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 // Implementation of class Reader
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 // Class Reader
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    //std::istream_iterator<char> begin(sin);
00300    //std::istream_iterator<char> end;
00301    // Those would allow streamed input from a file, if parse() were a
00302    // template function.
00303 
00304    // Since std::string is reference-counted, this at least does not
00305    // create an extra copy.
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          // Set error location to start of doc, ideally should be first token found in doc
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_ = &currentValue();
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 &/*tokenStart*/ )
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() )  // empty object
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 ) // error already set
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 &/*tokenStart*/ )
00701 {
00702    currentValue() = Value( arrayValue );
00703    skipSpaces();
00704    if ( *current_ == ']' ) // empty array
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 ) // error already set
00718          return recoverFromError( tokenArrayEnd );
00719 
00720       Token token;
00721       // Accept Comment after last item in the array.
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    // Attempts to parse the number as an integer. If the number is
00755    // larger than the maximum supported value of an integer then
00756    // we decode the number as a double.
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          // If the current digit is not the last one, or if it is
00776          // greater than the last digit of the maximum integer value,
00777          // the parse the number as a double.
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; // skip '"'
00838    Location end = token.end_ - 1;      // do not include '"'
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 &current, 
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       // surrogate pairs
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 &current, 
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 ); // discard errors caused by recovery
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    // column & line start at 1
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 // Deprecated. Preserved for backward compatibility
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     //JSON_ASSERT( ok );
01064     if (!ok) throw std::runtime_error(reader.getFormattedErrorMessages());
01065     return sin;
01066 }
01067 
01068 
01069 } // namespace Json
01070 
01071 // //////////////////////////////////////////////////////////////////////
01072 // End of content of file: src/lib_json/json_reader.cpp
01073 // //////////////////////////////////////////////////////////////////////
01074 
01075 
01076 
01077 
01078 
01079 
01080 // //////////////////////////////////////////////////////////////////////
01081 // Beginning of content of file: src/lib_json/json_batchallocator.h
01082 // //////////////////////////////////////////////////////////////////////
01083 
01084 // Copyright 2007-2010 Baptiste Lepilleur
01085 // Distributed under MIT license, or public domain if desired and
01086 // recognized in your jurisdiction.
01087 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
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 /* Fast memory allocator.
01100  *
01101  * This memory allocator allocates memory for a batch of object (specified by
01102  * the page size, the number of object in each page).
01103  *
01104  * It does not allow the destruction of a single object. All the allocated objects
01105  * can be destroyed at once. The memory can be either released or reused for future
01106  * allocation.
01107  * 
01108  * The in-place new operator must be used to construct the object using the pointer
01109  * returned by allocate.
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 //      printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
01123       assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
01124       assert( objectsPerPage >= 16 );
01125       batches_ = allocateBatch( 0 );   // allocated a dummy page
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_ ) // returns node from free list.
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_  ) // no free batch found, allocate a new one
01156          { 
01157             currentBatch_ = allocateBatch( objectsPerPage_ );
01158             currentBatch_->next_ = batches_; // insert at the head of the list
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    // disabled copy constructor and assignement operator.
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 } // namespace Json
01209 
01210 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
01211 
01212 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
01213 
01214 
01215 // //////////////////////////////////////////////////////////////////////
01216 // End of content of file: src/lib_json/json_batchallocator.h
01217 // //////////////////////////////////////////////////////////////////////
01218 
01219 
01220 
01221 
01222 
01223 
01224 // //////////////////////////////////////////////////////////////////////
01225 // Beginning of content of file: src/lib_json/json_valueiterator.inl
01226 // //////////////////////////////////////////////////////////////////////
01227 
01228 // Copyright 2007-2010 Baptiste Lepilleur
01229 // Distributed under MIT license, or public domain if desired and
01230 // recognized in your jurisdiction.
01231 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
01232 
01233 // included by json_value.cpp
01234 
01235 namespace Json {
01236 
01237 // //////////////////////////////////////////////////////////////////
01238 // //////////////////////////////////////////////////////////////////
01239 // //////////////////////////////////////////////////////////////////
01240 // class ValueIteratorBase
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 &current )
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    // Iterator for null value are initialized using the default
01328    // constructor, which initialize current_ to the default
01329    // std::map::iterator. As begin() and end() are two instance 
01330    // of the default std::map::iterator, they can not be compared.
01331    // To allow this, we handle this comparison specifically.
01332    if ( isNull_  &&  other.isNull_ )
01333    {
01334       return 0;
01335    }
01336 
01337 
01338    // Usage of std::distance is not portable (does not compile with Sun Studio 12 RogueWave STL,
01339    // which is the one used by default).
01340    // Using a portable hand-made version for non random iterator instead:
01341    //   return difference_type( std::distance( current_, other.current_ ) );
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 // class ValueConstIterator
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 &current )
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 // class ValueIterator
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 &current )
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 } // namespace Json
01527 
01528 // //////////////////////////////////////////////////////////////////////
01529 // End of content of file: src/lib_json/json_valueiterator.inl
01530 // //////////////////////////////////////////////////////////////////////
01531 
01532 
01533 
01534 
01535 
01536 
01537 // //////////////////////////////////////////////////////////////////////
01538 // Beginning of content of file: src/lib_json/json_value.cpp
01539 // //////////////////////////////////////////////////////////////////////
01540 
01541 // Copyright 2007-2010 Baptiste Lepilleur
01542 // Distributed under MIT license, or public domain if desired and
01543 // recognized in your jurisdiction.
01544 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
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>    // size_t
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 } // namespace Json
01617 
01618 
01619 // //////////////////////////////////////////////////////////////////
01620 // //////////////////////////////////////////////////////////////////
01621 // //////////////////////////////////////////////////////////////////
01622 // ValueInternals...
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 // class Value::CommentInfo
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    // It seems that /**/ style comments are acceptable as well.
01666    comment_ = duplicateStringValue( text );
01667 }
01668 
01669 
01670 // //////////////////////////////////////////////////////////////////
01671 // //////////////////////////////////////////////////////////////////
01672 // //////////////////////////////////////////////////////////////////
01673 // class Value::CZString
01674 // //////////////////////////////////////////////////////////////////
01675 // //////////////////////////////////////////////////////////////////
01676 // //////////////////////////////////////////////////////////////////
01677 # ifndef JSON_VALUE_USE_INTERNAL_MAP
01678 
01679 // Notes: index_ indicates if the string was allocated when
01680 // a string is stored.
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 // class Value::Value
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;  // unreachable
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    //if ( type_ != other.type_ )
02143    // GCC 2.95.3 says:
02144    // attempt to take address of bit-field structure member `Json::Value::type_'
02145    // Beats me, but a temp solves the problem.
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;  // unreachable
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 ""; // unreachable
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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; // unreachable;
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:  // size of the array is highest index + 1
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; // unreachable;
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 //# ifdef JSON_USE_CPPTL
02880 //EnumMemberNames
02881 //Value::enumMemberNames() const
02882 //{
02883 //   if ( type_ == objectValue )
02884 //   {
02885 //      return CppTL::Enum::any(  CppTL::Enum::transform(
02886 //         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
02887 //         MemberNamesTransform() ) );
02888 //   }
02889 //   return EnumMemberNames();
02890 //}
02891 //
02892 //
02893 //EnumValues 
02894 //Value::enumValues() const
02895 //{
02896 //   if ( type_ == objectValue  ||  type_ == arrayValue )
02897 //      return CppTL::Enum::anyValues( *(value_.map_), 
02898 //                                     CppTL::Type<const Value &>() );
02899 //   return EnumValues();
02900 //}
02901 //
02902 //# endif
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 // class PathArgument
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 // class Path
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       // Error: missing argument %d
03262    }
03263    else if ( (*itInArg)->kind_ != kind )
03264    {
03265       // Error: bad argument type
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    // Error: invalid path.
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             // Error: unable to resolve path (array value expected at position...
03294          }
03295          node = &((*node)[arg.index_]);
03296       }
03297       else if ( arg.kind_ == PathArgument::kindKey )
03298       {
03299          if ( !node->isObject() )
03300          {
03301             // Error: unable to resolve path (object value expected at position...)
03302          }
03303          node = &((*node)[arg.key_]);
03304          if ( node == &Value::null )
03305          {
03306             // Error: unable to resolve path (object has no member named '' at position...)
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             // Error: node is not an array at position ...
03353          }
03354          node = &((*node)[arg.index_]);
03355       }
03356       else if ( arg.kind_ == PathArgument::kindKey )
03357       {
03358          if ( !node->isObject() )
03359          {
03360             // Error: node is not an object at position...
03361          }
03362          node = &((*node)[arg.key_]);
03363       }
03364    }
03365    return *node;
03366 }
03367 
03368 
03369 } // namespace Json
03370 
03371 // //////////////////////////////////////////////////////////////////////
03372 // End of content of file: src/lib_json/json_value.cpp
03373 // //////////////////////////////////////////////////////////////////////
03374 
03375 
03376 
03377 
03378 
03379 
03380 // //////////////////////////////////////////////////////////////////////
03381 // Beginning of content of file: src/lib_json/json_writer.cpp
03382 // //////////////////////////////////////////////////////////////////////
03383 
03384 // Copyright 2007-2010 Baptiste Lepilleur
03385 // Distributed under MIT license, or public domain if desired and
03386 // recognized in your jurisdiction.
03387 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
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; // nothing to truncate, so save time
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        // Truncate zeroes to save bytes in output, but keep one.
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    // Not sure how to handle unicode...
03506    if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value ))
03507       return std::string("\"") + value + "\"";
03508    // We have to walk value and escape any special characters.
03509    // Appending to std::string is not efficient, but this should be rare.
03510    // (Note: forward slashes are *not* rare, but I am not escaping them.)
03511    std::string::size_type maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL
03512    std::string result;
03513    result.reserve(maxsize); // to avoid lots of mallocs
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          //case '/':
03541             // Even though \/ is considered a legal escape in JSON, a bare
03542             // slash is also legal, so I see no reason to escape it.
03543             // (I hope I am not misunderstanding something.
03544             // blep notes: actually escaping \/ may be useful in javascript to avoid </ 
03545             // sequence.
03546             // Should add a flag to allow this compatibility mode and prevent this 
03547             // sequence from occurring.
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 // Class Writer
03567 // //////////////////////////////////////////////////////////////////
03568 Writer::~Writer()
03569 {
03570 }
03571 
03572 
03573 // Class FastWriter
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 // Class StyledWriter
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 // output on a single line
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 ) // check if line length > max line length
03810    {
03811       childValues_.reserve( size );
03812       addChildValues_ = true;
03813       int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
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 == ' ' )     // already indented
03844          return;
03845       if ( last != '\n' )    // Comments may add new-line
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' ) // mac or dos EOL
03921       {
03922          if ( *current == '\n' ) // convert dos EOL
03923             ++current;
03924          normalized += '\n';
03925       }
03926       else // handle unix EOL & other char
03927          normalized += c;
03928    }
03929    return normalized;
03930 }
03931 
03932 
03933 // Class StyledStreamWriter
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; // Forget the stream, for safety.
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 // output on a single line
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 ) // check if line length > max line length
04086    {
04087       childValues_.reserve( size );
04088       addChildValues_ = true;
04089       int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
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     Some comments in this method would have been nice. ;-)
04118 
04119    if ( !document_.empty() )
04120    {
04121       char last = document_[document_.length()-1];
04122       if ( last == ' ' )     // already indented
04123          return;
04124       if ( last != '\n' )    // Comments may add new-line
04125          *document_ << '\n';
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' ) // mac or dos EOL
04201       {
04202          if ( *current == '\n' ) // convert dos EOL
04203             ++current;
04204          normalized += '\n';
04205       }
04206       else // handle unix EOL & other char
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 } // namespace Json
04222 
04223 // //////////////////////////////////////////////////////////////////////
04224 // End of content of file: src/lib_json/json_writer.cpp
04225 // //////////////////////////////////////////////////////////////////////
04226 
04227 
04228 
04229 
04230 


find_object_2d
Author(s): Mathieu Labbe
autogenerated on Thu Aug 27 2015 13:00:33