CppUnit project page CppUnit home page

value.h

Go to the documentation of this file.
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 //# ifdef JSON_USE_CPPTL
00044 //   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
00045 //   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
00046 //# endif
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 int Int;
00121       typedef unsigned int UInt;
00122       typedef ValueIterator iterator;
00123       typedef ValueConstIterator const_iterator;
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:
00169       Value( ValueType type = nullValue );
00170       Value( Int value );
00171       Value( UInt value );
00172       Value( double value );
00173       Value( const char *value );
00183       Value( const StaticString &value );
00184       Value( const std::string &value );
00185 # ifdef JSON_USE_CPPTL
00186       Value( const CppTL::ConstString &value );
00187 # endif
00188       Value( bool value );
00189       Value( const Value &other );
00190       ~Value();
00191 
00192       Value &operator=( const Value &other );
00193       void swap( Value &other );
00194 
00195       ValueType type() const;
00196 
00197       bool operator <( const Value &other ) const;
00198       bool operator <=( const Value &other ) const;
00199       bool operator >=( const Value &other ) const;
00200       bool operator >( const Value &other ) const;
00201 
00202       bool operator ==( const Value &other ) const;
00203       bool operator !=( const Value &other ) const;
00204 
00205       int compare( const Value &other );
00206 
00207       const char *asCString() const;
00208       std::string asString() const;
00209 # ifdef JSON_USE_CPPTL
00210       CppTL::ConstString asConstString() const;
00211 # endif
00212       Int asInt() const;
00213       UInt asUInt() const;
00214       double asDouble() const;
00215       bool asBool() const;
00216 
00217       bool isBool() const;
00218       bool isInt() const;
00219       bool isUInt() const;
00220       bool isIntegral() const;
00221       bool isDouble() const;
00222       bool isNumeric() const;
00223       bool isString() const;
00224       bool isArray() const;
00225       bool isObject() const;
00226 
00227       bool isConvertibleTo( ValueType other ) const;
00228 
00230       UInt size() const;
00231 
00233       void clear();
00234 
00238       void resize( UInt size );
00239 
00243       Value &operator[]( UInt index );
00245       const Value &operator[]( UInt index ) const;
00248       Value get( UInt index, 
00249                  const Value &defaultValue ) const;
00251       bool isValidIndex( UInt index ) const;
00254       Value &append( const Value &value );
00255 
00257       Value &operator[]( const char *key );
00259       const Value &operator[]( const char *key ) const;
00261       Value &operator[]( const std::string &key );
00263       const Value &operator[]( const std::string &key ) const;
00274       Value &operator[]( const StaticString &key );
00275 # ifdef JSON_USE_CPPTL
00277       Value &operator[]( const CppTL::ConstString &key );
00279       const Value &operator[]( const CppTL::ConstString &key ) const;
00280 # endif
00282       Value get( const char *key, 
00283                  const Value &defaultValue ) const;
00285       Value get( const std::string &key,
00286                  const Value &defaultValue ) const;
00287 # ifdef JSON_USE_CPPTL
00289       Value get( const CppTL::ConstString &key,
00290                  const Value &defaultValue ) const;
00291 # endif
00293       bool isMember( const char *key ) const;
00295       bool isMember( const std::string &key ) const;
00296 # ifdef JSON_USE_CPPTL
00298       bool isMember( const CppTL::ConstString &key ) const;
00299 # endif
00300 
00301       // Returns a list of the member names.
00302       Members getMemberNames() const;
00303 
00304 //# ifdef JSON_USE_CPPTL
00305 //      EnumMemberNames enumMemberNames() const;
00306 //      EnumValues enumValues() const;
00307 //# endif
00308 
00309       void setComment( const char *comment,
00310                        CommentPlacement placement );
00311       void setComment( const std::string &comment,
00312                        CommentPlacement placement );
00313       bool hasComment( CommentPlacement placement ) const;
00314       std::string getComment( CommentPlacement placement ) const;
00315 
00316       std::string toStyledString() const;
00317 
00318       const_iterator begin() const;
00319       const_iterator end() const;
00320 
00321       iterator begin();
00322       iterator end();
00323 
00324    private:
00325       Value &resolveReference( const char *key, 
00326                                bool isStatic );
00327 
00328 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00329       inline bool isItemAvailable() const
00330       {
00331          return itemIsUsed_ == 0;
00332       }
00333 
00334       inline void setItemUsed( bool isUsed = true )
00335       {
00336          itemIsUsed_ = isUsed ? 1 : 0;
00337       }
00338 
00339       inline bool isMemberNameStatic() const
00340       {
00341          return memberNameIsStatic_ == 0;
00342       }
00343 
00344       inline void setMemberNameIsStatic( bool isStatic )
00345       {
00346          memberNameIsStatic_ = isStatic ? 1 : 0;
00347       }
00348 # endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
00349 
00350    private:
00351       struct CommentInfo
00352       {
00353          CommentInfo();
00354          ~CommentInfo();
00355 
00356          void setComment( const char *text );
00357 
00358          char *comment_;
00359       };
00360 
00361       //struct MemberNamesTransform
00362       //{
00363       //   typedef const char *result_type;
00364       //   const char *operator()( const CZString &name ) const
00365       //   {
00366       //      return name.c_str();
00367       //   }
00368       //};
00369 
00370       union ValueHolder
00371       {
00372          Int int_;
00373          UInt uint_;
00374          double real_;
00375          bool bool_;
00376          char *string_;
00377 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00378          ValueInternalArray *array_;
00379          ValueInternalMap *map_;
00380 #else
00381          ObjectValues *map_;
00382 # endif
00383       } value_;
00384       ValueType type_ : 8;
00385       int allocated_ : 1;     // Notes: if declared as bool, bitfield is useless.
00386 # ifdef JSON_VALUE_USE_INTERNAL_MAP
00387       unsigned int itemIsUsed_ : 1;      // used by the ValueInternalMap container.
00388       int memberNameIsStatic_ : 1;       // used by the ValueInternalMap container.
00389 # endif
00390       CommentInfo *comments_;
00391    };
00392 
00393 
00396    class PathArgument
00397    {
00398    public:
00399       friend class Path;
00400 
00401       PathArgument();
00402       PathArgument( Value::UInt index );
00403       PathArgument( const char *key );
00404       PathArgument( const std::string &key );
00405 
00406    private:
00407       enum Kind
00408       {
00409          kindNone = 0,
00410          kindIndex,
00411          kindKey
00412       };
00413       std::string key_;
00414       Value::UInt index_;
00415       Kind kind_;
00416    };
00417 
00429    class Path
00430    {
00431    public:
00432       Path( const std::string &path,
00433             const PathArgument &a1 = PathArgument(),
00434             const PathArgument &a2 = PathArgument(),
00435             const PathArgument &a3 = PathArgument(),
00436             const PathArgument &a4 = PathArgument(),
00437             const PathArgument &a5 = PathArgument() );
00438 
00439       const Value &resolve( const Value &root ) const;
00440       Value resolve( const Value &root, 
00441                      const Value &defaultValue ) const;
00443       Value &make( Value &root ) const;
00444 
00445    private:
00446       typedef std::vector<const PathArgument *> InArgs;
00447       typedef std::vector<PathArgument> Args;
00448 
00449       void makePath( const std::string &path,
00450                      const InArgs &in );
00451       void addPathInArg( const std::string &path, 
00452                          const InArgs &in, 
00453                          InArgs::const_iterator &itInArg, 
00454                          PathArgument::Kind kind );
00455       void invalidPath( const std::string &path, 
00456                         int location );
00457 
00458       Args args_;
00459    };
00460 
00468    class ValueAllocator
00469    {
00470    public:
00471       enum { unknown = -1 };
00472 
00473       virtual ~ValueAllocator();
00474 
00475       virtual char *makeMemberName( const char *memberName ) = 0;
00476       virtual void releaseMemberName( char *memberName ) = 0;
00477       virtual char *duplicateStringValue( const char *value, 
00478                                           unsigned int length = unknown ) = 0;
00479       virtual void releaseStringValue( char *value ) = 0;
00480    };
00481 
00482 #ifdef JSON_VALUE_USE_INTERNAL_MAP
00483 
00527    class JSON_API ValueMapAllocator
00528    {
00529    public:
00530       virtual ~ValueMapAllocator();
00531       virtual ValueInternalMap *newMap() = 0;
00532       virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
00533       virtual void destructMap( ValueInternalMap *map ) = 0;
00534       virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
00535       virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
00536       virtual ValueInternalLink *allocateMapLink() = 0;
00537       virtual void releaseMapLink( ValueInternalLink *link ) = 0;
00538    };
00539 
00543    class JSON_API ValueInternalLink
00544    {
00545    public:
00546       enum { itemPerLink = 6 };  // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
00547       enum InternalFlags { 
00548          flagAvailable = 0,
00549          flagUsed = 1
00550       };
00551 
00552       ValueInternalLink();
00553 
00554       ~ValueInternalLink();
00555 
00556       Value items_[itemPerLink];
00557       char *keys_[itemPerLink];
00558       ValueInternalLink *previous_;
00559       ValueInternalLink *next_;
00560    };
00561 
00562 
00575    class JSON_API ValueInternalMap
00576    {
00577       friend class ValueIteratorBase;
00578       friend class Value;
00579    public:
00580       typedef unsigned int HashKey;
00581       typedef unsigned int BucketIndex;
00582 
00583 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00584       struct IteratorState
00585       {
00586          ValueInternalMap *map_;
00587          ValueInternalLink *link_;
00588          BucketIndex itemIndex_;
00589          BucketIndex bucketIndex_;
00590       };
00591 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00592 
00593       ValueInternalMap();
00594       ValueInternalMap( const ValueInternalMap &other );
00595       ValueInternalMap &operator =( const ValueInternalMap &other );
00596       ~ValueInternalMap();
00597 
00598       void swap( ValueInternalMap &other );
00599 
00600       BucketIndex size() const;
00601 
00602       void clear();
00603 
00604       bool reserveDelta( BucketIndex growth );
00605 
00606       bool reserve( BucketIndex newItemCount );
00607 
00608       const Value *find( const char *key ) const;
00609 
00610       Value *find( const char *key );
00611 
00612       Value &resolveReference( const char *key, 
00613                                bool isStatic );
00614 
00615       void remove( const char *key );
00616 
00617       void doActualRemove( ValueInternalLink *link, 
00618                            BucketIndex index,
00619                            BucketIndex bucketIndex );
00620 
00621       ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
00622 
00623       Value &setNewItem( const char *key, 
00624                          bool isStatic, 
00625                          ValueInternalLink *link, 
00626                          BucketIndex index );
00627 
00628       Value &unsafeAdd( const char *key, 
00629                         bool isStatic, 
00630                         HashKey hashedKey );
00631 
00632       HashKey hash( const char *key ) const;
00633 
00634       int compare( const ValueInternalMap &other ) const;
00635 
00636    private:
00637       void makeBeginIterator( IteratorState &it ) const;
00638       void makeEndIterator( IteratorState &it ) const;
00639       static bool equals( const IteratorState &x, const IteratorState &other );
00640       static void increment( IteratorState &iterator );
00641       static void incrementBucket( IteratorState &iterator );
00642       static void decrement( IteratorState &iterator );
00643       static const char *key( const IteratorState &iterator );
00644       static const char *key( const IteratorState &iterator, bool &isStatic );
00645       static Value &value( const IteratorState &iterator );
00646       static int distance( const IteratorState &x, const IteratorState &y );
00647 
00648    private:
00649       ValueInternalLink *buckets_;
00650       ValueInternalLink *tailLink_;
00651       BucketIndex bucketsSize_;
00652       BucketIndex itemCount_;
00653    };
00654 
00666    class JSON_API ValueInternalArray
00667    {
00668       friend class Value;
00669       friend class ValueIteratorBase;
00670    public:
00671       enum { itemsPerPage = 8 };    // should be a power of 2 for fast divide and modulo.
00672       typedef Value::ArrayIndex ArrayIndex;
00673       typedef unsigned int PageIndex;
00674 
00675 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00676       struct IteratorState // Must be a POD
00677       {
00678          ValueInternalArray *array_;
00679          Value **currentPageIndex_;
00680          unsigned int currentItemIndex_;
00681       };
00682 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00683 
00684       ValueInternalArray();
00685       ValueInternalArray( const ValueInternalArray &other );
00686       ValueInternalArray &operator =( const ValueInternalArray &other );
00687       ~ValueInternalArray();
00688       void swap( ValueInternalArray &other );
00689 
00690       void clear();
00691       void resize( ArrayIndex newSize );
00692 
00693       Value &resolveReference( ArrayIndex index );
00694 
00695       Value *find( ArrayIndex index ) const;
00696 
00697       ArrayIndex size() const;
00698 
00699       int compare( const ValueInternalArray &other ) const;
00700 
00701    private:
00702       static bool equals( const IteratorState &x, const IteratorState &other );
00703       static void increment( IteratorState &iterator );
00704       static void decrement( IteratorState &iterator );
00705       static Value &dereference( const IteratorState &iterator );
00706       static Value &unsafeDereference( const IteratorState &iterator );
00707       static int distance( const IteratorState &x, const IteratorState &y );
00708       static ArrayIndex indexOf( const IteratorState &iterator );
00709       void makeBeginIterator( IteratorState &it ) const;
00710       void makeEndIterator( IteratorState &it ) const;
00711       void makeIterator( IteratorState &it, ArrayIndex index ) const;
00712 
00713       void makeIndexValid( ArrayIndex index );
00714 
00715       Value **pages_;
00716       ArrayIndex size_;
00717       PageIndex pageCount_;
00718    };
00719 
00779    class JSON_API ValueArrayAllocator
00780    {
00781    public:
00782       virtual ~ValueArrayAllocator();
00783       virtual ValueInternalArray *newArray() = 0;
00784       virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
00785       virtual void destructArray( ValueInternalArray *array ) = 0;
00797       virtual void reallocateArrayPageIndex( Value **&indexes, 
00798                                              ValueInternalArray::PageIndex &indexCount,
00799                                              ValueInternalArray::PageIndex minNewIndexCount ) = 0;
00800       virtual void releaseArrayPageIndex( Value **indexes, 
00801                                           ValueInternalArray::PageIndex indexCount ) = 0;
00802       virtual Value *allocateArrayPage() = 0;
00803       virtual void releaseArrayPage( Value *value ) = 0;
00804    };
00805 #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
00806 
00807 
00811    class ValueIteratorBase
00812    {
00813    public:
00814       typedef unsigned int size_t;
00815       typedef int difference_type;
00816       typedef ValueIteratorBase SelfType;
00817 
00818       ValueIteratorBase();
00819 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00820       explicit ValueIteratorBase( const Value::ObjectValues::iterator &current );
00821 #else
00822       ValueIteratorBase( const ValueInternalArray::IteratorState &state );
00823       ValueIteratorBase( const ValueInternalMap::IteratorState &state );
00824 #endif
00825 
00826       bool operator ==( const SelfType &other ) const
00827       {
00828          return isEqual( other );
00829       }
00830 
00831       bool operator !=( const SelfType &other ) const
00832       {
00833          return !isEqual( other );
00834       }
00835 
00836       difference_type operator -( const SelfType &other ) const
00837       {
00838          return computeDistance( other );
00839       }
00840 
00842       Value key() const;
00843 
00845       Value::UInt index() const;
00846 
00848       const char *memberName() const;
00849 
00850    protected:
00851       Value &deref() const;
00852 
00853       void increment();
00854 
00855       void decrement();
00856 
00857       difference_type computeDistance( const SelfType &other ) const;
00858 
00859       bool isEqual( const SelfType &other ) const;
00860 
00861       void copy( const SelfType &other );
00862 
00863    private:
00864 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00865       Value::ObjectValues::iterator current_;
00866 #else
00867       union
00868       {
00869          ValueInternalArray::IteratorState array_;
00870          ValueInternalMap::IteratorState map_;
00871       } iterator_;
00872       bool isArray_;
00873 #endif
00874    };
00875 
00879    class ValueConstIterator : public ValueIteratorBase
00880    {
00881       friend class Value;
00882    public:
00883       typedef unsigned int size_t;
00884       typedef int difference_type;
00885       typedef const Value &reference;
00886       typedef const Value *pointer;
00887       typedef ValueConstIterator SelfType;
00888 
00889       ValueConstIterator();
00890    private:
00893 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00894       explicit ValueConstIterator( const Value::ObjectValues::iterator &current );
00895 #else
00896       ValueConstIterator( const ValueInternalArray::IteratorState &state );
00897       ValueConstIterator( const ValueInternalMap::IteratorState &state );
00898 #endif
00899    public:
00900       SelfType &operator =( const ValueIteratorBase &other );
00901 
00902       SelfType operator++( int )
00903       {
00904          SelfType temp( *this );
00905          ++*this;
00906          return temp;
00907       }
00908 
00909       SelfType operator--( int )
00910       {
00911          SelfType temp( *this );
00912          --*this;
00913          return temp;
00914       }
00915 
00916       SelfType &operator--()
00917       {
00918          decrement();
00919          return *this;
00920       }
00921 
00922       SelfType &operator++()
00923       {
00924          increment();
00925          return *this;
00926       }
00927 
00928       reference operator *() const
00929       {
00930          return deref();
00931       }
00932    };
00933 
00934 
00937    class ValueIterator : public ValueIteratorBase
00938    {
00939       friend class Value;
00940    public:
00941       typedef unsigned int size_t;
00942       typedef int difference_type;
00943       typedef Value &reference;
00944       typedef Value *pointer;
00945       typedef ValueIterator SelfType;
00946 
00947       ValueIterator();
00948       ValueIterator( const ValueConstIterator &other );
00949       ValueIterator( const ValueIterator &other );
00950    private:
00953 #ifndef JSON_VALUE_USE_INTERNAL_MAP
00954       explicit ValueIterator( const Value::ObjectValues::iterator &current );
00955 #else
00956       ValueIterator( const ValueInternalArray::IteratorState &state );
00957       ValueIterator( const ValueInternalMap::IteratorState &state );
00958 #endif
00959    public:
00960 
00961       SelfType &operator =( const SelfType &other );
00962 
00963       SelfType operator++( int )
00964       {
00965          SelfType temp( *this );
00966          ++*this;
00967          return temp;
00968       }
00969 
00970       SelfType operator--( int )
00971       {
00972          SelfType temp( *this );
00973          --*this;
00974          return temp;
00975       }
00976 
00977       SelfType &operator--()
00978       {
00979          decrement();
00980          return *this;
00981       }
00982 
00983       SelfType &operator++()
00984       {
00985          increment();
00986          return *this;
00987       }
00988 
00989       reference operator *() const
00990       {
00991          return deref();
00992       }
00993    };
00994 
00995 
00996 } // namespace Json
00997 
00998 
00999 #endif // CPPTL_JSON_H_INCLUDED

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers