00001 #ifndef CPPTL_JSON_H_INCLUDED
00002 # define CPPTL_JSON_H_INCLUDED
00003
00004 # include "forwards.h"
00005 # include <string>
00006 # include <vector>
00007
00008 # ifndef JSON_USE_CPPTL_SMALLMAP
00009 # include <map>
00010 # else
00011 # include <cpptl/smallmap.h>
00012 # endif
00013 # ifdef JSON_USE_CPPTL
00014 # include <cpptl/forwards.h>
00015 # endif
00016
00019 namespace Json {
00020
00023 enum ValueType
00024 {
00025 nullValue = 0,
00026 intValue,
00027 uintValue,
00028 realValue,
00029 stringValue,
00030 booleanValue,
00031 arrayValue,
00032 objectValue
00033 };
00034
00035 enum CommentPlacement
00036 {
00037 commentBefore = 0,
00038 commentAfterOnSameLine,
00039 commentAfter,
00040 numberOfCommentPlacement
00041 };
00042
00043
00044
00045
00046
00047
00062 class JSON_API StaticString
00063 {
00064 public:
00065 explicit StaticString( const char *czstring )
00066 : str_( czstring )
00067 {
00068 }
00069
00070 operator const char *() const
00071 {
00072 return str_;
00073 }
00074
00075 const char *c_str() const
00076 {
00077 return str_;
00078 }
00079
00080 private:
00081 const char *str_;
00082 };
00083
00111 class JSON_API Value
00112 {
00113 friend class ValueIteratorBase;
00114 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00115 friend class ValueInternalLink;
00116 friend class ValueInternalMap;
00117 # endif
00118 public:
00119 typedef std::vector<std::string> Members;
00120 typedef ValueIterator iterator;
00121 typedef ValueConstIterator const_iterator;
00122 typedef Json::UInt UInt;
00123 typedef Json::Int Int;
00124 typedef UInt ArrayIndex;
00125
00126 static const Value null;
00127 static const Int minInt;
00128 static const Int maxInt;
00129 static const UInt maxUInt;
00130
00131 private:
00132 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00133 # ifndef JSON_VALUE_USE_INTERNAL_MAP
00134 class CZString
00135 {
00136 public:
00137 enum DuplicationPolicy
00138 {
00139 noDuplication = 0,
00140 duplicate,
00141 duplicateOnCopy
00142 };
00143 CZString( int index );
00144 CZString( const char *cstr, DuplicationPolicy allocate );
00145 CZString( const CZString &other );
00146 ~CZString();
00147 CZString &operator =( const CZString &other );
00148 bool operator<( const CZString &other ) const;
00149 bool operator==( const CZString &other ) const;
00150 int index() const;
00151 const char *c_str() const;
00152 bool isStaticString() const;
00153 private:
00154 void swap( CZString &other );
00155 const char *cstr_;
00156 int index_;
00157 };
00158
00159 public:
00160 # ifndef JSON_USE_CPPTL_SMALLMAP
00161 typedef std::map<CZString, Value> ObjectValues;
00162 # else
00163 typedef CppTL::SmallMap<CZString, Value> ObjectValues;
00164 # endif // ifndef JSON_USE_CPPTL_SMALLMAP
00165 # endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
00166 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00167
00168 public:
00184 Value( ValueType type = nullValue );
00185 Value( Int value );
00186 Value( UInt value );
00187 Value( double value );
00188 Value( const char *value );
00189 Value( const char *beginValue, const char *endValue );
00200 Value( const StaticString &value );
00201 Value( const std::string &value );
00202 # ifdef JSON_USE_CPPTL
00203 Value( const CppTL::ConstString &value );
00204 # endif
00205 Value( bool value );
00206 Value( const Value &other );
00207 ~Value();
00208
00209 Value &operator=( const Value &other );
00213 void swap( Value &other );
00214
00215 ValueType type() const;
00216
00217 bool operator <( const Value &other ) const;
00218 bool operator <=( const Value &other ) const;
00219 bool operator >=( const Value &other ) const;
00220 bool operator >( const Value &other ) const;
00221
00222 bool operator ==( const Value &other ) const;
00223 bool operator !=( const Value &other ) const;
00224
00225 int compare( const Value &other );
00226
00227 const char *asCString() const;
00228 std::string asString() const;
00229 # ifdef JSON_USE_CPPTL
00230 CppTL::ConstString asConstString() const;
00231 # endif
00232 Int asInt() const;
00233 UInt asUInt() const;
00234 double asDouble() const;
00235 bool asBool() const;
00236
00237 bool isNull() const;
00238 bool isBool() const;
00239 bool isInt() const;
00240 bool isUInt() const;
00241 bool isIntegral() const;
00242 bool isDouble() const;
00243 bool isNumeric() const;
00244 bool isString() const;
00245 bool isArray() const;
00246 bool isObject() const;
00247
00248 bool isConvertibleTo( ValueType other ) const;
00249
00251 UInt size() const;
00252
00255 bool empty() const;
00256
00258 bool operator!() const;
00259
00263 void clear();
00264
00270 void resize( UInt size );
00271
00277 Value &operator[]( UInt index );
00281 const Value &operator[]( UInt index ) const;
00284 Value get( UInt index,
00285 const Value &defaultValue ) const;
00287 bool isValidIndex( UInt index ) const;
00291 Value &append( const Value &value );
00292
00294 Value &operator[]( const char *key );
00296 const Value &operator[]( const char *key ) const;
00298 Value &operator[]( const std::string &key );
00300 const Value &operator[]( const std::string &key ) const;
00312 Value &operator[]( const StaticString &key );
00313 # ifdef JSON_USE_CPPTL
00314
00315 Value &operator[]( const CppTL::ConstString &key );
00317 const Value &operator[]( const CppTL::ConstString &key ) const;
00318 # endif
00319
00320 Value get( const char *key,
00321 const Value &defaultValue ) const;
00323 Value get( const std::string &key,
00324 const Value &defaultValue ) const;
00325 # ifdef JSON_USE_CPPTL
00326
00327 Value get( const CppTL::ConstString &key,
00328 const Value &defaultValue ) const;
00329 # endif
00330
00331
00332
00333
00334
00335
00336 Value removeMember( const char* key );
00338 Value removeMember( const std::string &key );
00339
00341 bool isMember( const char *key ) const;
00343 bool isMember( const std::string &key ) const;
00344 # ifdef JSON_USE_CPPTL
00345
00346 bool isMember( const CppTL::ConstString &key ) const;
00347 # endif
00348
00354 Members getMemberNames() const;
00355
00356
00357
00358
00359
00360
00362 void setComment( const char *comment,
00363 CommentPlacement placement );
00365 void setComment( const std::string &comment,
00366 CommentPlacement placement );
00367 bool hasComment( CommentPlacement placement ) const;
00369 std::string getComment( CommentPlacement placement ) const;
00370
00371 std::string toStyledString() const;
00372
00373 const_iterator begin() const;
00374 const_iterator end() const;
00375
00376 iterator begin();
00377 iterator end();
00378
00379 private:
00380 Value &resolveReference( const char *key,
00381 bool isStatic );
00382
00383 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00384 inline bool isItemAvailable() const
00385 {
00386 return itemIsUsed_ == 0;
00387 }
00388
00389 inline void setItemUsed( bool isUsed = true )
00390 {
00391 itemIsUsed_ = isUsed ? 1 : 0;
00392 }
00393
00394 inline bool isMemberNameStatic() const
00395 {
00396 return memberNameIsStatic_ == 0;
00397 }
00398
00399 inline void setMemberNameIsStatic( bool isStatic )
00400 {
00401 memberNameIsStatic_ = isStatic ? 1 : 0;
00402 }
00403 # endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
00404
00405 private:
00406 struct CommentInfo
00407 {
00408 CommentInfo();
00409 ~CommentInfo();
00410
00411 void setComment( const char *text );
00412
00413 char *comment_;
00414 };
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 union ValueHolder
00426 {
00427 Int int_;
00428 UInt uint_;
00429 double real_;
00430 bool bool_;
00431 char *string_;
00432 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00433 ValueInternalArray *array_;
00434 ValueInternalMap *map_;
00435 #else
00436 ObjectValues *map_;
00437 # endif
00438 } value_;
00439 ValueType type_ : 8;
00440 int allocated_ : 1;
00441 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00442 unsigned int itemIsUsed_ : 1;
00443 int memberNameIsStatic_ : 1;
00444 # endif
00445 CommentInfo *comments_;
00446 };
00447
00448
00451 class PathArgument
00452 {
00453 public:
00454 friend class Path;
00455
00456 PathArgument();
00457 PathArgument( UInt index );
00458 PathArgument( const char *key );
00459 PathArgument( const std::string &key );
00460
00461 private:
00462 enum Kind
00463 {
00464 kindNone = 0,
00465 kindIndex,
00466 kindKey
00467 };
00468 std::string key_;
00469 UInt index_;
00470 Kind kind_;
00471 };
00472
00484 class Path
00485 {
00486 public:
00487 Path( const std::string &path,
00488 const PathArgument &a1 = PathArgument(),
00489 const PathArgument &a2 = PathArgument(),
00490 const PathArgument &a3 = PathArgument(),
00491 const PathArgument &a4 = PathArgument(),
00492 const PathArgument &a5 = PathArgument() );
00493
00494 const Value &resolve( const Value &root ) const;
00495 Value resolve( const Value &root,
00496 const Value &defaultValue ) const;
00498 Value &make( Value &root ) const;
00499
00500 private:
00501 typedef std::vector<const PathArgument *> InArgs;
00502 typedef std::vector<PathArgument> Args;
00503
00504 void makePath( const std::string &path,
00505 const InArgs &in );
00506 void addPathInArg( const std::string &path,
00507 const InArgs &in,
00508 InArgs::const_iterator &itInArg,
00509 PathArgument::Kind kind );
00510 void invalidPath( const std::string &path,
00511 int location );
00512
00513 Args args_;
00514 };
00515
00523 class ValueAllocator
00524 {
00525 public:
00526 enum { unknown = (unsigned)-1 };
00527
00528 virtual ~ValueAllocator();
00529
00530 virtual char *makeMemberName( const char *memberName ) = 0;
00531 virtual void releaseMemberName( char *memberName ) = 0;
00532 virtual char *duplicateStringValue( const char *value,
00533 unsigned int length = unknown ) = 0;
00534 virtual void releaseStringValue( char *value ) = 0;
00535 };
00536
00537 #ifdef JSON_VALUE_USE_INTERNAL_MAP
00538
00582 class JSON_API ValueMapAllocator
00583 {
00584 public:
00585 virtual ~ValueMapAllocator();
00586 virtual ValueInternalMap *newMap() = 0;
00587 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
00588 virtual void destructMap( ValueInternalMap *map ) = 0;
00589 virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
00590 virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
00591 virtual ValueInternalLink *allocateMapLink() = 0;
00592 virtual void releaseMapLink( ValueInternalLink *link ) = 0;
00593 };
00594
00598 class JSON_API ValueInternalLink
00599 {
00600 public:
00601 enum { itemPerLink = 6 };
00602 enum InternalFlags {
00603 flagAvailable = 0,
00604 flagUsed = 1
00605 };
00606
00607 ValueInternalLink();
00608
00609 ~ValueInternalLink();
00610
00611 Value items_[itemPerLink];
00612 char *keys_[itemPerLink];
00613 ValueInternalLink *previous_;
00614 ValueInternalLink *next_;
00615 };
00616
00617
00630 class JSON_API ValueInternalMap
00631 {
00632 friend class ValueIteratorBase;
00633 friend class Value;
00634 public:
00635 typedef unsigned int HashKey;
00636 typedef unsigned int BucketIndex;
00637
00638 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00639 struct IteratorState
00640 {
00641 IteratorState()
00642 : map_(0)
00643 , link_(0)
00644 , itemIndex_(0)
00645 , bucketIndex_(0)
00646 {
00647 }
00648 ValueInternalMap *map_;
00649 ValueInternalLink *link_;
00650 BucketIndex itemIndex_;
00651 BucketIndex bucketIndex_;
00652 };
00653 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00654
00655 ValueInternalMap();
00656 ValueInternalMap( const ValueInternalMap &other );
00657 ValueInternalMap &operator =( const ValueInternalMap &other );
00658 ~ValueInternalMap();
00659
00660 void swap( ValueInternalMap &other );
00661
00662 BucketIndex size() const;
00663
00664 void clear();
00665
00666 bool reserveDelta( BucketIndex growth );
00667
00668 bool reserve( BucketIndex newItemCount );
00669
00670 const Value *find( const char *key ) const;
00671
00672 Value *find( const char *key );
00673
00674 Value &resolveReference( const char *key,
00675 bool isStatic );
00676
00677 void remove( const char *key );
00678
00679 void doActualRemove( ValueInternalLink *link,
00680 BucketIndex index,
00681 BucketIndex bucketIndex );
00682
00683 ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
00684
00685 Value &setNewItem( const char *key,
00686 bool isStatic,
00687 ValueInternalLink *link,
00688 BucketIndex index );
00689
00690 Value &unsafeAdd( const char *key,
00691 bool isStatic,
00692 HashKey hashedKey );
00693
00694 HashKey hash( const char *key ) const;
00695
00696 int compare( const ValueInternalMap &other ) const;
00697
00698 private:
00699 void makeBeginIterator( IteratorState &it ) const;
00700 void makeEndIterator( IteratorState &it ) const;
00701 static bool equals( const IteratorState &x, const IteratorState &other );
00702 static void increment( IteratorState &iterator );
00703 static void incrementBucket( IteratorState &iterator );
00704 static void decrement( IteratorState &iterator );
00705 static const char *key( const IteratorState &iterator );
00706 static const char *key( const IteratorState &iterator, bool &isStatic );
00707 static Value &value( const IteratorState &iterator );
00708 static int distance( const IteratorState &x, const IteratorState &y );
00709
00710 private:
00711 ValueInternalLink *buckets_;
00712 ValueInternalLink *tailLink_;
00713 BucketIndex bucketsSize_;
00714 BucketIndex itemCount_;
00715 };
00716
00728 class JSON_API ValueInternalArray
00729 {
00730 friend class Value;
00731 friend class ValueIteratorBase;
00732 public:
00733 enum { itemsPerPage = 8 };
00734 typedef Value::ArrayIndex ArrayIndex;
00735 typedef unsigned int PageIndex;
00736
00737 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00738 struct IteratorState
00739 {
00740 IteratorState()
00741 : array_(0)
00742 , currentPageIndex_(0)
00743 , currentItemIndex_(0)
00744 {
00745 }
00746 ValueInternalArray *array_;
00747 Value **currentPageIndex_;
00748 unsigned int currentItemIndex_;
00749 };
00750 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00751
00752 ValueInternalArray();
00753 ValueInternalArray( const ValueInternalArray &other );
00754 ValueInternalArray &operator =( const ValueInternalArray &other );
00755 ~ValueInternalArray();
00756 void swap( ValueInternalArray &other );
00757
00758 void clear();
00759 void resize( ArrayIndex newSize );
00760
00761 Value &resolveReference( ArrayIndex index );
00762
00763 Value *find( ArrayIndex index ) const;
00764
00765 ArrayIndex size() const;
00766
00767 int compare( const ValueInternalArray &other ) const;
00768
00769 private:
00770 static bool equals( const IteratorState &x, const IteratorState &other );
00771 static void increment( IteratorState &iterator );
00772 static void decrement( IteratorState &iterator );
00773 static Value &dereference( const IteratorState &iterator );
00774 static Value &unsafeDereference( const IteratorState &iterator );
00775 static int distance( const IteratorState &x, const IteratorState &y );
00776 static ArrayIndex indexOf( const IteratorState &iterator );
00777 void makeBeginIterator( IteratorState &it ) const;
00778 void makeEndIterator( IteratorState &it ) const;
00779 void makeIterator( IteratorState &it, ArrayIndex index ) const;
00780
00781 void makeIndexValid( ArrayIndex index );
00782
00783 Value **pages_;
00784 ArrayIndex size_;
00785 PageIndex pageCount_;
00786 };
00787
00847 class JSON_API ValueArrayAllocator
00848 {
00849 public:
00850 virtual ~ValueArrayAllocator();
00851 virtual ValueInternalArray *newArray() = 0;
00852 virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
00853 virtual void destructArray( ValueInternalArray *array ) = 0;
00865 virtual void reallocateArrayPageIndex( Value **&indexes,
00866 ValueInternalArray::PageIndex &indexCount,
00867 ValueInternalArray::PageIndex minNewIndexCount ) = 0;
00868 virtual void releaseArrayPageIndex( Value **indexes,
00869 ValueInternalArray::PageIndex indexCount ) = 0;
00870 virtual Value *allocateArrayPage() = 0;
00871 virtual void releaseArrayPage( Value *value ) = 0;
00872 };
00873 #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
00874
00875
00879 class ValueIteratorBase
00880 {
00881 public:
00882 typedef unsigned int size_t;
00883 typedef int difference_type;
00884 typedef ValueIteratorBase SelfType;
00885
00886 ValueIteratorBase();
00887 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00888 explicit ValueIteratorBase( const Value::ObjectValues::iterator ¤t );
00889 #else
00890 ValueIteratorBase( const ValueInternalArray::IteratorState &state );
00891 ValueIteratorBase( const ValueInternalMap::IteratorState &state );
00892 #endif
00893
00894 bool operator ==( const SelfType &other ) const
00895 {
00896 return isEqual( other );
00897 }
00898
00899 bool operator !=( const SelfType &other ) const
00900 {
00901 return !isEqual( other );
00902 }
00903
00904 difference_type operator -( const SelfType &other ) const
00905 {
00906 return computeDistance( other );
00907 }
00908
00910 Value key() const;
00911
00913 UInt index() const;
00914
00916 const char *memberName() const;
00917
00918 protected:
00919 Value &deref() const;
00920
00921 void increment();
00922
00923 void decrement();
00924
00925 difference_type computeDistance( const SelfType &other ) const;
00926
00927 bool isEqual( const SelfType &other ) const;
00928
00929 void copy( const SelfType &other );
00930
00931 private:
00932 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00933 Value::ObjectValues::iterator current_;
00934
00935 bool isNull_;
00936 #else
00937 union
00938 {
00939 ValueInternalArray::IteratorState array_;
00940 ValueInternalMap::IteratorState map_;
00941 } iterator_;
00942 bool isArray_;
00943 #endif
00944 };
00945
00949 class ValueConstIterator : public ValueIteratorBase
00950 {
00951 friend class Value;
00952 public:
00953 typedef unsigned int size_t;
00954 typedef int difference_type;
00955 typedef const Value &reference;
00956 typedef const Value *pointer;
00957 typedef ValueConstIterator SelfType;
00958
00959 ValueConstIterator();
00960 private:
00963 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00964 explicit ValueConstIterator( const Value::ObjectValues::iterator ¤t );
00965 #else
00966 ValueConstIterator( const ValueInternalArray::IteratorState &state );
00967 ValueConstIterator( const ValueInternalMap::IteratorState &state );
00968 #endif
00969 public:
00970 SelfType &operator =( const ValueIteratorBase &other );
00971
00972 SelfType operator++( int )
00973 {
00974 SelfType temp( *this );
00975 ++*this;
00976 return temp;
00977 }
00978
00979 SelfType operator--( int )
00980 {
00981 SelfType temp( *this );
00982 --*this;
00983 return temp;
00984 }
00985
00986 SelfType &operator--()
00987 {
00988 decrement();
00989 return *this;
00990 }
00991
00992 SelfType &operator++()
00993 {
00994 increment();
00995 return *this;
00996 }
00997
00998 reference operator *() const
00999 {
01000 return deref();
01001 }
01002 };
01003
01004
01007 class ValueIterator : public ValueIteratorBase
01008 {
01009 friend class Value;
01010 public:
01011 typedef unsigned int size_t;
01012 typedef int difference_type;
01013 typedef Value &reference;
01014 typedef Value *pointer;
01015 typedef ValueIterator SelfType;
01016
01017 ValueIterator();
01018 ValueIterator( const ValueConstIterator &other );
01019 ValueIterator( const ValueIterator &other );
01020 private:
01023 #ifndef JSON_VALUE_USE_INTERNAL_MAP
01024 explicit ValueIterator( const Value::ObjectValues::iterator ¤t );
01025 #else
01026 ValueIterator( const ValueInternalArray::IteratorState &state );
01027 ValueIterator( const ValueInternalMap::IteratorState &state );
01028 #endif
01029 public:
01030
01031 SelfType &operator =( const SelfType &other );
01032
01033 SelfType operator++( int )
01034 {
01035 SelfType temp( *this );
01036 ++*this;
01037 return temp;
01038 }
01039
01040 SelfType operator--( int )
01041 {
01042 SelfType temp( *this );
01043 --*this;
01044 return temp;
01045 }
01046
01047 SelfType &operator--()
01048 {
01049 decrement();
01050 return *this;
01051 }
01052
01053 SelfType &operator++()
01054 {
01055 increment();
01056 return *this;
01057 }
01058
01059 reference operator *() const
01060 {
01061 return deref();
01062 }
01063 };
01064
01065
01066 }
01067
01068
01069 #endif // CPPTL_JSON_H_INCLUDED