00001
00002
00003
00004
00005
00006 #ifndef CPPTL_JSON_H_INCLUDED
00007 # define CPPTL_JSON_H_INCLUDED
00008
00009 #if !defined(JSON_IS_AMALGAMATION)
00010 # include "forwards.h"
00011 #endif // if !defined(JSON_IS_AMALGAMATION)
00012 # include <string>
00013 # include <vector>
00014
00015 # ifndef JSON_USE_CPPTL_SMALLMAP
00016 # include <map>
00017 # else
00018 # include <cpptl/smallmap.h>
00019 # endif
00020 # ifdef JSON_USE_CPPTL
00021 # include <cpptl/forwards.h>
00022 # endif
00023
00026 namespace Json {
00027
00030 enum ValueType
00031 {
00032 nullValue = 0,
00033 intValue,
00034 uintValue,
00035 realValue,
00036 stringValue,
00037 booleanValue,
00038 arrayValue,
00039 objectValue
00040 };
00041
00042 enum CommentPlacement
00043 {
00044 commentBefore = 0,
00045 commentAfterOnSameLine,
00046 commentAfter,
00047 numberOfCommentPlacement
00048 };
00049
00050
00051
00052
00053
00054
00069 class JSON_API StaticString
00070 {
00071 public:
00072 explicit StaticString( const char *czstring )
00073 : str_( czstring )
00074 {
00075 }
00076
00077 operator const char *() const
00078 {
00079 return str_;
00080 }
00081
00082 const char *c_str() const
00083 {
00084 return str_;
00085 }
00086
00087 private:
00088 const char *str_;
00089 };
00090
00118 class JSON_API Value
00119 {
00120 friend class ValueIteratorBase;
00121 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00122 friend class ValueInternalLink;
00123 friend class ValueInternalMap;
00124 # endif
00125 public:
00126 typedef std::vector<std::string> Members;
00127 typedef ValueIterator iterator;
00128 typedef ValueConstIterator const_iterator;
00129 typedef Json::UInt UInt;
00130 typedef Json::Int Int;
00131 # if defined(JSON_HAS_INT64)
00132 typedef Json::UInt64 UInt64;
00133 typedef Json::Int64 Int64;
00134 #endif // defined(JSON_HAS_INT64)
00135 typedef Json::LargestInt LargestInt;
00136 typedef Json::LargestUInt LargestUInt;
00137 typedef Json::ArrayIndex ArrayIndex;
00138
00139 static const Value null;
00141 static const LargestInt minLargestInt;
00143 static const LargestInt maxLargestInt;
00145 static const LargestUInt maxLargestUInt;
00146
00148 static const Int minInt;
00150 static const Int maxInt;
00152 static const UInt maxUInt;
00153
00155 static const Int64 minInt64;
00157 static const Int64 maxInt64;
00159 static const UInt64 maxUInt64;
00160
00161 private:
00162 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00163 # ifndef JSON_VALUE_USE_INTERNAL_MAP
00164 class CZString
00165 {
00166 public:
00167 enum DuplicationPolicy
00168 {
00169 noDuplication = 0,
00170 duplicate,
00171 duplicateOnCopy
00172 };
00173 CZString( ArrayIndex index );
00174 CZString( const char *cstr, DuplicationPolicy allocate );
00175 CZString( const CZString &other );
00176 ~CZString();
00177 CZString &operator =( const CZString &other );
00178 bool operator<( const CZString &other ) const;
00179 bool operator==( const CZString &other ) const;
00180 ArrayIndex index() const;
00181 const char *c_str() const;
00182 bool isStaticString() const;
00183 private:
00184 void swap( CZString &other );
00185 const char *cstr_;
00186 ArrayIndex index_;
00187 };
00188
00189 public:
00190 # ifndef JSON_USE_CPPTL_SMALLMAP
00191 typedef std::map<CZString, Value> ObjectValues;
00192 # else
00193 typedef CppTL::SmallMap<CZString, Value> ObjectValues;
00194 # endif // ifndef JSON_USE_CPPTL_SMALLMAP
00195 # endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
00196 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00197
00198 public:
00214 Value( ValueType type = nullValue );
00215 Value( Int value );
00216 Value( UInt value );
00217 #if defined(JSON_HAS_INT64)
00218 Value( Int64 value );
00219 Value( UInt64 value );
00220 #endif // if defined(JSON_HAS_INT64)
00221 Value( double value );
00222 Value( const char *value );
00223 Value( const char *beginValue, const char *endValue );
00234 Value( const StaticString &value );
00235 Value( const std::string &value );
00236 # ifdef JSON_USE_CPPTL
00237 Value( const CppTL::ConstString &value );
00238 # endif
00239 Value( bool value );
00240 Value( const Value &other );
00241 ~Value();
00242
00243 Value &operator=( const Value &other );
00247 void swap( Value &other );
00248
00249 ValueType type() const;
00250
00251 bool operator <( const Value &other ) const;
00252 bool operator <=( const Value &other ) const;
00253 bool operator >=( const Value &other ) const;
00254 bool operator >( const Value &other ) const;
00255
00256 bool operator ==( const Value &other ) const;
00257 bool operator !=( const Value &other ) const;
00258
00259 int compare( const Value &other ) const;
00260
00261 const char *asCString() const;
00262 std::string asString() const;
00263 # ifdef JSON_USE_CPPTL
00264 CppTL::ConstString asConstString() const;
00265 # endif
00266 Int asInt() const;
00267 UInt asUInt() const;
00268 Int64 asInt64() const;
00269 UInt64 asUInt64() const;
00270 LargestInt asLargestInt() const;
00271 LargestUInt asLargestUInt() const;
00272 float asFloat() const;
00273 double asDouble() const;
00274 bool asBool() const;
00275
00276 bool isNull() const;
00277 bool isBool() const;
00278 bool isInt() const;
00279 bool isUInt() const;
00280 bool isIntegral() const;
00281 bool isDouble() const;
00282 bool isNumeric() const;
00283 bool isString() const;
00284 bool isArray() const;
00285 bool isObject() const;
00286
00287 bool isConvertibleTo( ValueType other ) const;
00288
00290 ArrayIndex size() const;
00291
00294 bool empty() const;
00295
00297 bool operator!() const;
00298
00302 void clear();
00303
00309 void resize( ArrayIndex size );
00310
00316 Value &operator[]( ArrayIndex index );
00317
00323 Value &operator[]( int index );
00324
00328 const Value &operator[]( ArrayIndex index ) const;
00329
00333 const Value &operator[]( int index ) const;
00334
00337 Value get( ArrayIndex index,
00338 const Value &defaultValue ) const;
00340 bool isValidIndex( ArrayIndex index ) const;
00344 Value &append( const Value &value );
00345
00347 Value &operator[]( const char *key );
00349 const Value &operator[]( const char *key ) const;
00351 Value &operator[]( const std::string &key );
00353 const Value &operator[]( const std::string &key ) const;
00365 Value &operator[]( const StaticString &key );
00366 # ifdef JSON_USE_CPPTL
00368 Value &operator[]( const CppTL::ConstString &key );
00370 const Value &operator[]( const CppTL::ConstString &key ) const;
00371 # endif
00373 Value get( const char *key,
00374 const Value &defaultValue ) const;
00376 Value get( const std::string &key,
00377 const Value &defaultValue ) const;
00378 # ifdef JSON_USE_CPPTL
00380 Value get( const CppTL::ConstString &key,
00381 const Value &defaultValue ) const;
00382 # endif
00389 Value removeMember( const char* key );
00391 Value removeMember( const std::string &key );
00392
00394 bool isMember( const char *key ) const;
00396 bool isMember( const std::string &key ) const;
00397 # ifdef JSON_USE_CPPTL
00399 bool isMember( const CppTL::ConstString &key ) const;
00400 # endif
00401
00407 Members getMemberNames() const;
00408
00409
00410
00411
00412
00413
00415 void setComment( const char *comment,
00416 CommentPlacement placement );
00418 void setComment( const std::string &comment,
00419 CommentPlacement placement );
00420 bool hasComment( CommentPlacement placement ) const;
00422 std::string getComment( CommentPlacement placement ) const;
00423
00424 std::string toStyledString() const;
00425
00426 const_iterator begin() const;
00427 const_iterator end() const;
00428
00429 iterator begin();
00430 iterator end();
00431
00432 private:
00433 Value &resolveReference( const char *key,
00434 bool isStatic );
00435
00436 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00437 inline bool isItemAvailable() const
00438 {
00439 return itemIsUsed_ == 0;
00440 }
00441
00442 inline void setItemUsed( bool isUsed = true )
00443 {
00444 itemIsUsed_ = isUsed ? 1 : 0;
00445 }
00446
00447 inline bool isMemberNameStatic() const
00448 {
00449 return memberNameIsStatic_ == 0;
00450 }
00451
00452 inline void setMemberNameIsStatic( bool isStatic )
00453 {
00454 memberNameIsStatic_ = isStatic ? 1 : 0;
00455 }
00456 # endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
00457
00458 private:
00459 struct CommentInfo
00460 {
00461 CommentInfo();
00462 ~CommentInfo();
00463
00464 void setComment( const char *text );
00465
00466 char *comment_;
00467 };
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 union ValueHolder
00479 {
00480 LargestInt int_;
00481 LargestUInt uint_;
00482 double real_;
00483 bool bool_;
00484 char *string_;
00485 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00486 ValueInternalArray *array_;
00487 ValueInternalMap *map_;
00488 #else
00489 ObjectValues *map_;
00490 # endif
00491 } value_;
00492 ValueType type_ : 8;
00493 int allocated_ : 1;
00494 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00495 unsigned int itemIsUsed_ : 1;
00496 int memberNameIsStatic_ : 1;
00497 # endif
00498 CommentInfo *comments_;
00499 };
00500
00501
00504 class PathArgument
00505 {
00506 public:
00507 friend class Path;
00508
00509 PathArgument();
00510 PathArgument( ArrayIndex index );
00511 PathArgument( const char *key );
00512 PathArgument( const std::string &key );
00513
00514 private:
00515 enum Kind
00516 {
00517 kindNone = 0,
00518 kindIndex,
00519 kindKey
00520 };
00521 std::string key_;
00522 ArrayIndex index_;
00523 Kind kind_;
00524 };
00525
00537 class Path
00538 {
00539 public:
00540 Path( const std::string &path,
00541 const PathArgument &a1 = PathArgument(),
00542 const PathArgument &a2 = PathArgument(),
00543 const PathArgument &a3 = PathArgument(),
00544 const PathArgument &a4 = PathArgument(),
00545 const PathArgument &a5 = PathArgument() );
00546
00547 const Value &resolve( const Value &root ) const;
00548 Value resolve( const Value &root,
00549 const Value &defaultValue ) const;
00551 Value &make( Value &root ) const;
00552
00553 private:
00554 typedef std::vector<const PathArgument *> InArgs;
00555 typedef std::vector<PathArgument> Args;
00556
00557 void makePath( const std::string &path,
00558 const InArgs &in );
00559 void addPathInArg( const std::string &path,
00560 const InArgs &in,
00561 InArgs::const_iterator &itInArg,
00562 PathArgument::Kind kind );
00563 void invalidPath( const std::string &path,
00564 int location );
00565
00566 Args args_;
00567 };
00568
00569
00570
00571 #ifdef JSON_VALUE_USE_INTERNAL_MAP
00572
00616 class JSON_API ValueMapAllocator
00617 {
00618 public:
00619 virtual ~ValueMapAllocator();
00620 virtual ValueInternalMap *newMap() = 0;
00621 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
00622 virtual void destructMap( ValueInternalMap *map ) = 0;
00623 virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
00624 virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
00625 virtual ValueInternalLink *allocateMapLink() = 0;
00626 virtual void releaseMapLink( ValueInternalLink *link ) = 0;
00627 };
00628
00632 class JSON_API ValueInternalLink
00633 {
00634 public:
00635 enum { itemPerLink = 6 };
00636 enum InternalFlags {
00637 flagAvailable = 0,
00638 flagUsed = 1
00639 };
00640
00641 ValueInternalLink();
00642
00643 ~ValueInternalLink();
00644
00645 Value items_[itemPerLink];
00646 char *keys_[itemPerLink];
00647 ValueInternalLink *previous_;
00648 ValueInternalLink *next_;
00649 };
00650
00651
00664 class JSON_API ValueInternalMap
00665 {
00666 friend class ValueIteratorBase;
00667 friend class Value;
00668 public:
00669 typedef unsigned int HashKey;
00670 typedef unsigned int BucketIndex;
00671
00672 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00673 struct IteratorState
00674 {
00675 IteratorState()
00676 : map_(0)
00677 , link_(0)
00678 , itemIndex_(0)
00679 , bucketIndex_(0)
00680 {
00681 }
00682 ValueInternalMap *map_;
00683 ValueInternalLink *link_;
00684 BucketIndex itemIndex_;
00685 BucketIndex bucketIndex_;
00686 };
00687 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00688
00689 ValueInternalMap();
00690 ValueInternalMap( const ValueInternalMap &other );
00691 ValueInternalMap &operator =( const ValueInternalMap &other );
00692 ~ValueInternalMap();
00693
00694 void swap( ValueInternalMap &other );
00695
00696 BucketIndex size() const;
00697
00698 void clear();
00699
00700 bool reserveDelta( BucketIndex growth );
00701
00702 bool reserve( BucketIndex newItemCount );
00703
00704 const Value *find( const char *key ) const;
00705
00706 Value *find( const char *key );
00707
00708 Value &resolveReference( const char *key,
00709 bool isStatic );
00710
00711 void remove( const char *key );
00712
00713 void doActualRemove( ValueInternalLink *link,
00714 BucketIndex index,
00715 BucketIndex bucketIndex );
00716
00717 ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
00718
00719 Value &setNewItem( const char *key,
00720 bool isStatic,
00721 ValueInternalLink *link,
00722 BucketIndex index );
00723
00724 Value &unsafeAdd( const char *key,
00725 bool isStatic,
00726 HashKey hashedKey );
00727
00728 HashKey hash( const char *key ) const;
00729
00730 int compare( const ValueInternalMap &other ) const;
00731
00732 private:
00733 void makeBeginIterator( IteratorState &it ) const;
00734 void makeEndIterator( IteratorState &it ) const;
00735 static bool equals( const IteratorState &x, const IteratorState &other );
00736 static void increment( IteratorState &iterator );
00737 static void incrementBucket( IteratorState &iterator );
00738 static void decrement( IteratorState &iterator );
00739 static const char *key( const IteratorState &iterator );
00740 static const char *key( const IteratorState &iterator, bool &isStatic );
00741 static Value &value( const IteratorState &iterator );
00742 static int distance( const IteratorState &x, const IteratorState &y );
00743
00744 private:
00745 ValueInternalLink *buckets_;
00746 ValueInternalLink *tailLink_;
00747 BucketIndex bucketsSize_;
00748 BucketIndex itemCount_;
00749 };
00750
00762 class JSON_API ValueInternalArray
00763 {
00764 friend class Value;
00765 friend class ValueIteratorBase;
00766 public:
00767 enum { itemsPerPage = 8 };
00768 typedef Value::ArrayIndex ArrayIndex;
00769 typedef unsigned int PageIndex;
00770
00771 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00772 struct IteratorState
00773 {
00774 IteratorState()
00775 : array_(0)
00776 , currentPageIndex_(0)
00777 , currentItemIndex_(0)
00778 {
00779 }
00780 ValueInternalArray *array_;
00781 Value **currentPageIndex_;
00782 unsigned int currentItemIndex_;
00783 };
00784 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00785
00786 ValueInternalArray();
00787 ValueInternalArray( const ValueInternalArray &other );
00788 ValueInternalArray &operator =( const ValueInternalArray &other );
00789 ~ValueInternalArray();
00790 void swap( ValueInternalArray &other );
00791
00792 void clear();
00793 void resize( ArrayIndex newSize );
00794
00795 Value &resolveReference( ArrayIndex index );
00796
00797 Value *find( ArrayIndex index ) const;
00798
00799 ArrayIndex size() const;
00800
00801 int compare( const ValueInternalArray &other ) const;
00802
00803 private:
00804 static bool equals( const IteratorState &x, const IteratorState &other );
00805 static void increment( IteratorState &iterator );
00806 static void decrement( IteratorState &iterator );
00807 static Value &dereference( const IteratorState &iterator );
00808 static Value &unsafeDereference( const IteratorState &iterator );
00809 static int distance( const IteratorState &x, const IteratorState &y );
00810 static ArrayIndex indexOf( const IteratorState &iterator );
00811 void makeBeginIterator( IteratorState &it ) const;
00812 void makeEndIterator( IteratorState &it ) const;
00813 void makeIterator( IteratorState &it, ArrayIndex index ) const;
00814
00815 void makeIndexValid( ArrayIndex index );
00816
00817 Value **pages_;
00818 ArrayIndex size_;
00819 PageIndex pageCount_;
00820 };
00821
00881 class JSON_API ValueArrayAllocator
00882 {
00883 public:
00884 virtual ~ValueArrayAllocator();
00885 virtual ValueInternalArray *newArray() = 0;
00886 virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
00887 virtual void destructArray( ValueInternalArray *array ) = 0;
00899 virtual void reallocateArrayPageIndex( Value **&indexes,
00900 ValueInternalArray::PageIndex &indexCount,
00901 ValueInternalArray::PageIndex minNewIndexCount ) = 0;
00902 virtual void releaseArrayPageIndex( Value **indexes,
00903 ValueInternalArray::PageIndex indexCount ) = 0;
00904 virtual Value *allocateArrayPage() = 0;
00905 virtual void releaseArrayPage( Value *value ) = 0;
00906 };
00907 #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
00908
00909
00913 class ValueIteratorBase
00914 {
00915 public:
00916 typedef unsigned int size_t;
00917 typedef int difference_type;
00918 typedef ValueIteratorBase SelfType;
00919
00920 ValueIteratorBase();
00921 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00922 explicit ValueIteratorBase( const Value::ObjectValues::iterator ¤t );
00923 #else
00924 ValueIteratorBase( const ValueInternalArray::IteratorState &state );
00925 ValueIteratorBase( const ValueInternalMap::IteratorState &state );
00926 #endif
00927
00928 bool operator ==( const SelfType &other ) const
00929 {
00930 return isEqual( other );
00931 }
00932
00933 bool operator !=( const SelfType &other ) const
00934 {
00935 return !isEqual( other );
00936 }
00937
00938 difference_type operator -( const SelfType &other ) const
00939 {
00940 return computeDistance( other );
00941 }
00942
00944 Value key() const;
00945
00947 UInt index() const;
00948
00950 const char *memberName() const;
00951
00952 protected:
00953 Value &deref() const;
00954
00955 void increment();
00956
00957 void decrement();
00958
00959 difference_type computeDistance( const SelfType &other ) const;
00960
00961 bool isEqual( const SelfType &other ) const;
00962
00963 void copy( const SelfType &other );
00964
00965 private:
00966 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00967 Value::ObjectValues::iterator current_;
00968
00969 bool isNull_;
00970 #else
00971 union
00972 {
00973 ValueInternalArray::IteratorState array_;
00974 ValueInternalMap::IteratorState map_;
00975 } iterator_;
00976 bool isArray_;
00977 #endif
00978 };
00979
00983 class ValueConstIterator : public ValueIteratorBase
00984 {
00985 friend class Value;
00986 public:
00987 typedef unsigned int size_t;
00988 typedef int difference_type;
00989 typedef const Value &reference;
00990 typedef const Value *pointer;
00991 typedef ValueConstIterator SelfType;
00992
00993 ValueConstIterator();
00994 private:
00997 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00998 explicit ValueConstIterator( const Value::ObjectValues::iterator ¤t );
00999 #else
01000 ValueConstIterator( const ValueInternalArray::IteratorState &state );
01001 ValueConstIterator( const ValueInternalMap::IteratorState &state );
01002 #endif
01003 public:
01004 SelfType &operator =( const ValueIteratorBase &other );
01005
01006 SelfType operator++( int )
01007 {
01008 SelfType temp( *this );
01009 ++*this;
01010 return temp;
01011 }
01012
01013 SelfType operator--( int )
01014 {
01015 SelfType temp( *this );
01016 --*this;
01017 return temp;
01018 }
01019
01020 SelfType &operator--()
01021 {
01022 decrement();
01023 return *this;
01024 }
01025
01026 SelfType &operator++()
01027 {
01028 increment();
01029 return *this;
01030 }
01031
01032 reference operator *() const
01033 {
01034 return deref();
01035 }
01036 };
01037
01038
01041 class ValueIterator : public ValueIteratorBase
01042 {
01043 friend class Value;
01044 public:
01045 typedef unsigned int size_t;
01046 typedef int difference_type;
01047 typedef Value &reference;
01048 typedef Value *pointer;
01049 typedef ValueIterator SelfType;
01050
01051 ValueIterator();
01052 ValueIterator( const ValueConstIterator &other );
01053 ValueIterator( const ValueIterator &other );
01054 private:
01057 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01058 explicit ValueIterator( const Value::ObjectValues::iterator ¤t );
01059 #else
01060 ValueIterator( const ValueInternalArray::IteratorState &state );
01061 ValueIterator( const ValueInternalMap::IteratorState &state );
01062 #endif
01063 public:
01064
01065 SelfType &operator =( const SelfType &other );
01066
01067 SelfType operator++( int )
01068 {
01069 SelfType temp( *this );
01070 ++*this;
01071 return temp;
01072 }
01073
01074 SelfType operator--( int )
01075 {
01076 SelfType temp( *this );
01077 --*this;
01078 return temp;
01079 }
01080
01081 SelfType &operator--()
01082 {
01083 decrement();
01084 return *this;
01085 }
01086
01087 SelfType &operator++()
01088 {
01089 increment();
01090 return *this;
01091 }
01092
01093 reference operator *() const
01094 {
01095 return deref();
01096 }
01097 };
01098
01099
01100 }
01101
01102
01103 #endif // CPPTL_JSON_H_INCLUDED