JsonCpp project page JsonCpp home page

value.h
Go to the documentation of this file.
1 #ifndef CPPTL_JSON_H_INCLUDED
2 # define CPPTL_JSON_H_INCLUDED
3 
4 # include "forwards.h"
5 # include <string>
6 # include <vector>
7 
8 # ifndef JSON_USE_CPPTL_SMALLMAP
9 # include <map>
10 # else
11 # include <cpptl/smallmap.h>
12 # endif
13 # ifdef JSON_USE_CPPTL
14 # include <cpptl/forwards.h>
15 # endif
16 
19 namespace Json {
20 
23  enum ValueType
24  {
25  nullValue = 0,
33  };
34 
36  {
41  };
42 
43 //# ifdef JSON_USE_CPPTL
44 // typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
45 // typedef CppTL::AnyEnumerator<const Value &> EnumValues;
46 //# endif
47 
63  {
64  public:
65  explicit StaticString( const char *czstring )
66  : str_( czstring )
67  {
68  }
69 
70  operator const char *() const
71  {
72  return str_;
73  }
74 
75  const char *c_str() const
76  {
77  return str_;
78  }
79 
80  private:
81  const char *str_;
82  };
83 
112  {
113  friend class ValueIteratorBase;
114 # ifdef JSON_VALUE_USE_INTERNAL_MAP
115  friend class ValueInternalLink;
116  friend class ValueInternalMap;
117 # endif
118  public:
119  typedef std::vector<std::string> Members;
122  typedef Json::UInt UInt;
123  typedef Json::Int Int;
124  typedef UInt ArrayIndex;
125 
126  static const Value null;
127  static const Int minInt;
128  static const Int maxInt;
129  static const UInt maxUInt;
130 
131  private:
132 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
133 # ifndef JSON_VALUE_USE_INTERNAL_MAP
134  class CZString
135  {
136  public:
137  enum DuplicationPolicy
138  {
139  noDuplication = 0,
140  duplicate,
141  duplicateOnCopy
142  };
143  CZString( int index );
144  CZString( const char *cstr, DuplicationPolicy allocate );
145  CZString( const CZString &other );
146  ~CZString();
147  CZString &operator =( const CZString &other );
148  bool operator<( const CZString &other ) const;
149  bool operator==( const CZString &other ) const;
150  int index() const;
151  const char *c_str() const;
152  bool isStaticString() const;
153  private:
154  void swap( CZString &other );
155  const char *cstr_;
156  int index_;
157  };
158 
159  public:
160 # ifndef JSON_USE_CPPTL_SMALLMAP
161  typedef std::map<CZString, Value> ObjectValues;
162 # else
163  typedef CppTL::SmallMap<CZString, Value> ObjectValues;
164 # endif // ifndef JSON_USE_CPPTL_SMALLMAP
165 # endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
166 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
167 
168  public:
184  Value( ValueType type = nullValue );
185  Value( Int value );
186  Value( UInt value );
187  Value( double value );
188  Value( const char *value );
189  Value( const char *beginValue, const char *endValue );
200  Value( const StaticString &value );
201  Value( const std::string &value );
202 # ifdef JSON_USE_CPPTL
203  Value( const CppTL::ConstString &value );
204 # endif
205  Value( bool value );
206  Value( const Value &other );
207  ~Value();
208 
209  Value &operator=( const Value &other );
213  void swap( Value &other );
214 
215  ValueType type() const;
216 
217  bool operator <( const Value &other ) const;
218  bool operator <=( const Value &other ) const;
219  bool operator >=( const Value &other ) const;
220  bool operator >( const Value &other ) const;
221 
222  bool operator ==( const Value &other ) const;
223  bool operator !=( const Value &other ) const;
224 
225  int compare( const Value &other );
226 
227  const char *asCString() const;
228  std::string asString() const;
229 # ifdef JSON_USE_CPPTL
230  CppTL::ConstString asConstString() const;
231 # endif
232  Int asInt() const;
233  UInt asUInt() const;
234  double asDouble() const;
235  bool asBool() const;
236 
237  bool isNull() const;
238  bool isBool() const;
239  bool isInt() const;
240  bool isUInt() const;
241  bool isIntegral() const;
242  bool isDouble() const;
243  bool isNumeric() const;
244  bool isString() const;
245  bool isArray() const;
246  bool isObject() const;
247 
248  bool isConvertibleTo( ValueType other ) const;
249 
251  UInt size() const;
252 
255  bool empty() const;
256 
258  bool operator!() const;
259 
263  void clear();
264 
270  void resize( UInt size );
271 
277  Value &operator[]( UInt index );
281  const Value &operator[]( UInt index ) const;
284  Value get( UInt index,
285  const Value &defaultValue ) const;
287  bool isValidIndex( UInt index ) const;
291  Value &append( const Value &value );
292 
294  Value &operator[]( const char *key );
296  const Value &operator[]( const char *key ) const;
298  Value &operator[]( const std::string &key );
300  const Value &operator[]( const std::string &key ) const;
312  Value &operator[]( const StaticString &key );
313 # ifdef JSON_USE_CPPTL
314 
315  Value &operator[]( const CppTL::ConstString &key );
317  const Value &operator[]( const CppTL::ConstString &key ) const;
318 # endif
319 
320  Value get( const char *key,
321  const Value &defaultValue ) const;
323  Value get( const std::string &key,
324  const Value &defaultValue ) const;
325 # ifdef JSON_USE_CPPTL
326 
327  Value get( const CppTL::ConstString &key,
328  const Value &defaultValue ) const;
329 # endif
330 
331 
332 
333 
334 
335 
336  Value removeMember( const char* key );
338  Value removeMember( const std::string &key );
339 
341  bool isMember( const char *key ) const;
343  bool isMember( const std::string &key ) const;
344 # ifdef JSON_USE_CPPTL
345 
346  bool isMember( const CppTL::ConstString &key ) const;
347 # endif
348 
354  Members getMemberNames() const;
355 
356 //# ifdef JSON_USE_CPPTL
357 // EnumMemberNames enumMemberNames() const;
358 // EnumValues enumValues() const;
359 //# endif
360 
362  void setComment( const char *comment,
363  CommentPlacement placement );
365  void setComment( const std::string &comment,
366  CommentPlacement placement );
367  bool hasComment( CommentPlacement placement ) const;
369  std::string getComment( CommentPlacement placement ) const;
370 
371  std::string toStyledString() const;
372 
373  const_iterator begin() const;
374  const_iterator end() const;
375 
376  iterator begin();
377  iterator end();
378 
379  private:
380  Value &resolveReference( const char *key,
381  bool isStatic );
382 
383 # ifdef JSON_VALUE_USE_INTERNAL_MAP
384  inline bool isItemAvailable() const
385  {
386  return itemIsUsed_ == 0;
387  }
388 
389  inline void setItemUsed( bool isUsed = true )
390  {
391  itemIsUsed_ = isUsed ? 1 : 0;
392  }
393 
394  inline bool isMemberNameStatic() const
395  {
396  return memberNameIsStatic_ == 0;
397  }
398 
399  inline void setMemberNameIsStatic( bool isStatic )
400  {
401  memberNameIsStatic_ = isStatic ? 1 : 0;
402  }
403 # endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
404 
405  private:
406  struct CommentInfo
407  {
408  CommentInfo();
409  ~CommentInfo();
410 
411  void setComment( const char *text );
412 
413  char *comment_;
414  };
415 
416  //struct MemberNamesTransform
417  //{
418  // typedef const char *result_type;
419  // const char *operator()( const CZString &name ) const
420  // {
421  // return name.c_str();
422  // }
423  //};
424 
425  union ValueHolder
426  {
427  Int int_;
428  UInt uint_;
429  double real_;
430  bool bool_;
431  char *string_;
432 # ifdef JSON_VALUE_USE_INTERNAL_MAP
433  ValueInternalArray *array_;
434  ValueInternalMap *map_;
435 #else
436  ObjectValues *map_;
437 # endif
438  } value_;
439  ValueType type_ : 8;
440  int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
441 # ifdef JSON_VALUE_USE_INTERNAL_MAP
442  unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
443  int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
444 # endif
445  CommentInfo *comments_;
446  };
447 
448 
452  {
453  public:
454  friend class Path;
455 
456  PathArgument();
457  PathArgument( UInt index );
458  PathArgument( const char *key );
459  PathArgument( const std::string &key );
460 
461  private:
462  enum Kind
463  {
464  kindNone = 0,
465  kindIndex,
466  kindKey
467  };
468  std::string key_;
469  UInt index_;
470  Kind kind_;
471  };
472 
484  class Path
485  {
486  public:
487  Path( const std::string &path,
488  const PathArgument &a1 = PathArgument(),
489  const PathArgument &a2 = PathArgument(),
490  const PathArgument &a3 = PathArgument(),
491  const PathArgument &a4 = PathArgument(),
492  const PathArgument &a5 = PathArgument() );
493 
494  const Value &resolve( const Value &root ) const;
495  Value resolve( const Value &root,
496  const Value &defaultValue ) const;
498  Value &make( Value &root ) const;
499 
500  private:
501  typedef std::vector<const PathArgument *> InArgs;
502  typedef std::vector<PathArgument> Args;
503 
504  void makePath( const std::string &path,
505  const InArgs &in );
506  void addPathInArg( const std::string &path,
507  const InArgs &in,
508  InArgs::const_iterator &itInArg,
509  PathArgument::Kind kind );
510  void invalidPath( const std::string &path,
511  int location );
512 
513  Args args_;
514  };
515 
524  {
525  public:
526  enum { unknown = (unsigned)-1 };
527 
528  virtual ~ValueAllocator();
529 
530  virtual char *makeMemberName( const char *memberName ) = 0;
531  virtual void releaseMemberName( char *memberName ) = 0;
532  virtual char *duplicateStringValue( const char *value,
533  unsigned int length = unknown ) = 0;
534  virtual void releaseStringValue( char *value ) = 0;
535  };
536 
537 #ifdef JSON_VALUE_USE_INTERNAL_MAP
538 
583  {
584  public:
585  virtual ~ValueMapAllocator();
586  virtual ValueInternalMap *newMap() = 0;
587  virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
588  virtual void destructMap( ValueInternalMap *map ) = 0;
589  virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
590  virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
591  virtual ValueInternalLink *allocateMapLink() = 0;
592  virtual void releaseMapLink( ValueInternalLink *link ) = 0;
593  };
594 
599  {
600  public:
601  enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
603  flagAvailable = 0,
604  flagUsed = 1
605  };
606 
608 
610 
611  Value items_[itemPerLink];
612  char *keys_[itemPerLink];
615  };
616 
617 
631  {
632  friend class ValueIteratorBase;
633  friend class Value;
634  public:
635  typedef unsigned int HashKey;
636  typedef unsigned int BucketIndex;
637 
638 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
639  struct IteratorState
640  {
641  IteratorState()
642  : map_(0)
643  , link_(0)
644  , itemIndex_(0)
645  , bucketIndex_(0)
646  {
647  }
648  ValueInternalMap *map_;
649  ValueInternalLink *link_;
650  BucketIndex itemIndex_;
651  BucketIndex bucketIndex_;
652  };
653 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
654 
656  ValueInternalMap( const ValueInternalMap &other );
657  ValueInternalMap &operator =( const ValueInternalMap &other );
658  ~ValueInternalMap();
659 
660  void swap( ValueInternalMap &other );
661 
662  BucketIndex size() const;
663 
664  void clear();
665 
666  bool reserveDelta( BucketIndex growth );
667 
668  bool reserve( BucketIndex newItemCount );
669 
670  const Value *find( const char *key ) const;
671 
672  Value *find( const char *key );
673 
674  Value &resolveReference( const char *key,
675  bool isStatic );
676 
677  void remove( const char *key );
678 
679  void doActualRemove( ValueInternalLink *link,
680  BucketIndex index,
681  BucketIndex bucketIndex );
682 
683  ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
684 
685  Value &setNewItem( const char *key,
686  bool isStatic,
687  ValueInternalLink *link,
688  BucketIndex index );
689 
690  Value &unsafeAdd( const char *key,
691  bool isStatic,
692  HashKey hashedKey );
693 
694  HashKey hash( const char *key ) const;
695 
696  int compare( const ValueInternalMap &other ) const;
697 
698  private:
699  void makeBeginIterator( IteratorState &it ) const;
700  void makeEndIterator( IteratorState &it ) const;
701  static bool equals( const IteratorState &x, const IteratorState &other );
702  static void increment( IteratorState &iterator );
703  static void incrementBucket( IteratorState &iterator );
704  static void decrement( IteratorState &iterator );
705  static const char *key( const IteratorState &iterator );
706  static const char *key( const IteratorState &iterator, bool &isStatic );
707  static Value &value( const IteratorState &iterator );
708  static int distance( const IteratorState &x, const IteratorState &y );
709 
710  private:
711  ValueInternalLink *buckets_;
712  ValueInternalLink *tailLink_;
713  BucketIndex bucketsSize_;
714  BucketIndex itemCount_;
715  };
716 
729  {
730  friend class Value;
731  friend class ValueIteratorBase;
732  public:
733  enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo.
735  typedef unsigned int PageIndex;
736 
737 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
738  struct IteratorState // Must be a POD
739  {
740  IteratorState()
741  : array_(0)
742  , currentPageIndex_(0)
743  , currentItemIndex_(0)
744  {
745  }
746  ValueInternalArray *array_;
747  Value **currentPageIndex_;
748  unsigned int currentItemIndex_;
749  };
750 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
751 
753  ValueInternalArray( const ValueInternalArray &other );
754  ValueInternalArray &operator =( const ValueInternalArray &other );
756  void swap( ValueInternalArray &other );
757 
758  void clear();
759  void resize( ArrayIndex newSize );
760 
761  Value &resolveReference( ArrayIndex index );
762 
763  Value *find( ArrayIndex index ) const;
764 
765  ArrayIndex size() const;
766 
767  int compare( const ValueInternalArray &other ) const;
768 
769  private:
770  static bool equals( const IteratorState &x, const IteratorState &other );
771  static void increment( IteratorState &iterator );
772  static void decrement( IteratorState &iterator );
773  static Value &dereference( const IteratorState &iterator );
774  static Value &unsafeDereference( const IteratorState &iterator );
775  static int distance( const IteratorState &x, const IteratorState &y );
776  static ArrayIndex indexOf( const IteratorState &iterator );
777  void makeBeginIterator( IteratorState &it ) const;
778  void makeEndIterator( IteratorState &it ) const;
779  void makeIterator( IteratorState &it, ArrayIndex index ) const;
780 
781  void makeIndexValid( ArrayIndex index );
782 
783  Value **pages_;
784  ArrayIndex size_;
785  PageIndex pageCount_;
786  };
787 
848  {
849  public:
850  virtual ~ValueArrayAllocator();
851  virtual ValueInternalArray *newArray() = 0;
852  virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
853  virtual void destructArray( ValueInternalArray *array ) = 0;
865  virtual void reallocateArrayPageIndex( Value **&indexes,
866  ValueInternalArray::PageIndex &indexCount,
867  ValueInternalArray::PageIndex minNewIndexCount ) = 0;
868  virtual void releaseArrayPageIndex( Value **indexes,
869  ValueInternalArray::PageIndex indexCount ) = 0;
870  virtual Value *allocateArrayPage() = 0;
871  virtual void releaseArrayPage( Value *value ) = 0;
872  };
873 #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
874 
875 
880  {
881  public:
882  typedef unsigned int size_t;
883  typedef int difference_type;
885 
887 #ifndef JSON_VALUE_USE_INTERNAL_MAP
888  explicit ValueIteratorBase( const Value::ObjectValues::iterator &current );
889 #else
890  ValueIteratorBase( const ValueInternalArray::IteratorState &state );
891  ValueIteratorBase( const ValueInternalMap::IteratorState &state );
892 #endif
893 
894  bool operator ==( const SelfType &other ) const
895  {
896  return isEqual( other );
897  }
898 
899  bool operator !=( const SelfType &other ) const
900  {
901  return !isEqual( other );
902  }
903 
904  difference_type operator -( const SelfType &other ) const
905  {
906  return computeDistance( other );
907  }
908 
910  Value key() const;
911 
913  UInt index() const;
914 
916  const char *memberName() const;
917 
918  protected:
919  Value &deref() const;
920 
921  void increment();
922 
923  void decrement();
924 
925  difference_type computeDistance( const SelfType &other ) const;
926 
927  bool isEqual( const SelfType &other ) const;
928 
929  void copy( const SelfType &other );
930 
931  private:
932 #ifndef JSON_VALUE_USE_INTERNAL_MAP
933  Value::ObjectValues::iterator current_;
934  // Indicates that iterator is for a null value.
935  bool isNull_;
936 #else
937  union
938  {
939  ValueInternalArray::IteratorState array_;
940  ValueInternalMap::IteratorState map_;
941  } iterator_;
942  bool isArray_;
943 #endif
944  };
945 
950  {
951  friend class Value;
952  public:
953  typedef unsigned int size_t;
954  typedef int difference_type;
955  typedef const Value &reference;
956  typedef const Value *pointer;
958 
960  private:
963 #ifndef JSON_VALUE_USE_INTERNAL_MAP
964  explicit ValueConstIterator( const Value::ObjectValues::iterator &current );
965 #else
966  ValueConstIterator( const ValueInternalArray::IteratorState &state );
967  ValueConstIterator( const ValueInternalMap::IteratorState &state );
968 #endif
969  public:
970  SelfType &operator =( const ValueIteratorBase &other );
971 
972  SelfType operator++( int )
973  {
974  SelfType temp( *this );
975  ++*this;
976  return temp;
977  }
978 
979  SelfType operator--( int )
980  {
981  SelfType temp( *this );
982  --*this;
983  return temp;
984  }
985 
986  SelfType &operator--()
987  {
988  decrement();
989  return *this;
990  }
991 
992  SelfType &operator++()
993  {
994  increment();
995  return *this;
996  }
997 
998  reference operator *() const
999  {
1000  return deref();
1001  }
1002  };
1003 
1004 
1008  {
1009  friend class Value;
1010  public:
1011  typedef unsigned int size_t;
1012  typedef int difference_type;
1013  typedef Value &reference;
1014  typedef Value *pointer;
1016 
1017  ValueIterator();
1018  ValueIterator( const ValueConstIterator &other );
1019  ValueIterator( const ValueIterator &other );
1020  private:
1023 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1024  explicit ValueIterator( const Value::ObjectValues::iterator &current );
1025 #else
1026  ValueIterator( const ValueInternalArray::IteratorState &state );
1027  ValueIterator( const ValueInternalMap::IteratorState &state );
1028 #endif
1029  public:
1030 
1031  SelfType &operator =( const SelfType &other );
1032 
1033  SelfType operator++( int )
1034  {
1035  SelfType temp( *this );
1036  ++*this;
1037  return temp;
1038  }
1039 
1040  SelfType operator--( int )
1041  {
1042  SelfType temp( *this );
1043  --*this;
1044  return temp;
1045  }
1046 
1047  SelfType &operator--()
1048  {
1049  decrement();
1050  return *this;
1051  }
1052 
1053  SelfType &operator++()
1054  {
1055  increment();
1056  return *this;
1057  }
1058 
1059  reference operator *() const
1060  {
1061  return deref();
1062  }
1063  };
1064 
1065 
1066 } // namespace Json
1067 
1068 
1069 #endif // CPPTL_JSON_H_INCLUDED

SourceForge Logo hosts this site. Send comments to:
Json-cpp Developers