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