Drizzled Public API Documentation

value.h
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2  *
3  * JSON Library, originally from http://jsoncpp.sourceforge.net/
4  *
5  * Copyright (C) 2011 Stewart Smith
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following disclaimer
17  * in the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * * The names of its contributors may not be used to endorse or
21  * promote products derived from this software without specific prior
22  * written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
38 #pragma once
39 #ifndef CPPTL_JSON_H_INCLUDED
40 # define CPPTL_JSON_H_INCLUDED
41 
42 # include "forwards.h"
43 # include <string>
44 # include <vector>
45 
46 # ifndef JSON_USE_CPPTL_SMALLMAP
47 # include <map>
48 # else
49 # include <cpptl/smallmap.h>
50 # endif
51 # ifdef JSON_USE_CPPTL
52 # include <cpptl/forwards.h>
53 # endif
54 
57 namespace Json {
58 
61  enum ValueType
62  {
63  nullValue = 0,
71  };
72 
74  {
78  numberOfCommentPlacement
79  };
80 
81 //# ifdef JSON_USE_CPPTL
82 // typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
83 // typedef CppTL::AnyEnumerator<const Value &> EnumValues;
84 //# endif
85 
100  class JSON_API StaticString
101  {
102  public:
103  explicit StaticString( const char *czstring )
104  : str_( czstring )
105  {
106  }
107 
108  operator const char *() const
109  {
110  return str_;
111  }
112 
113  const char *c_str() const
114  {
115  return str_;
116  }
117 
118  private:
119  const char *str_;
120  };
121 
149  class JSON_API Value
150  {
151  friend class ValueIteratorBase;
152 # ifdef JSON_VALUE_USE_INTERNAL_MAP
153  friend class ValueInternalLink;
154  friend class ValueInternalMap;
155 # endif
156  public:
157  typedef std::vector<std::string> Members;
158  typedef ValueIterator iterator;
160  typedef Json::UInt UInt;
161  typedef Json::Int Int;
162  typedef UInt ArrayIndex;
163 
164  static const Value null;
165  static const Int minInt;
166  static const Int maxInt;
167  static const UInt maxUInt;
168 
169  private:
170 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
171 # ifndef JSON_VALUE_USE_INTERNAL_MAP
172  class CZString
173  {
174  public:
175  enum DuplicationPolicy
176  {
177  noDuplication = 0,
178  duplicate,
179  duplicateOnCopy
180  };
181  CZString( int index );
182  CZString( const char *cstr, DuplicationPolicy allocate );
183  CZString( const CZString &other );
184  ~CZString();
185  CZString &operator =( const CZString &other );
186  bool operator<( const CZString &other ) const;
187  bool operator==( const CZString &other ) const;
188  int index() const;
189  const char *c_str() const;
190  bool isStaticString() const;
191  private:
192  void swap( CZString &other );
193  const char *cstr_;
194  int index_;
195  };
196 
197  public:
198 # ifndef JSON_USE_CPPTL_SMALLMAP
199  typedef std::map<CZString, Value> ObjectValues;
200 # else
201  typedef CppTL::SmallMap<CZString, Value> ObjectValues;
202 # endif // ifndef JSON_USE_CPPTL_SMALLMAP
203 # endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
204 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
205 
206  public:
222  Value( ValueType type = nullValue );
223  Value( Int value );
224  Value( UInt value );
225  Value( double value );
226  Value( const char *value );
227  Value( const char *beginValue, const char *endValue );
238  Value( const StaticString &value );
239  Value( const std::string &value );
240 # ifdef JSON_USE_CPPTL
241  Value( const CppTL::ConstString &value );
242 # endif
243  Value( bool value );
244  Value( const Value &other );
245  ~Value();
246 
247  Value &operator=( const Value &other );
251  void swap( Value &other );
252 
253  ValueType type() const;
254 
255  bool operator <( const Value &other ) const;
256  bool operator <=( const Value &other ) const;
257  bool operator >=( const Value &other ) const;
258  bool operator >( const Value &other ) const;
259 
260  bool operator ==( const Value &other ) const;
261  bool operator !=( const Value &other ) const;
262 
263  int compare( const Value &other );
264 
265  const char *asCString() const;
266  std::string asString() const;
267 # ifdef JSON_USE_CPPTL
268  CppTL::ConstString asConstString() const;
269 # endif
270  Int asInt() const;
271  UInt asUInt() const;
272  double asDouble() const;
273  bool asBool() const;
274 
275  bool isNull() const;
276  bool isBool() const;
277  bool isInt() const;
278  bool isUInt() const;
279  bool isIntegral() const;
280  bool isDouble() const;
281  bool isNumeric() const;
282  bool isString() const;
283  bool isArray() const;
284  bool isObject() const;
285 
286  bool isConvertibleTo( ValueType other ) const;
287 
289  UInt size() const;
290 
293  bool empty() const;
294 
296  bool operator!() const;
297 
301  void clear();
302 
308  void resize( UInt size );
309 
315  Value &operator[]( UInt index );
319  const Value &operator[]( UInt index ) const;
322  Value get( UInt index,
323  const Value &defaultValue ) const;
325  bool isValidIndex( UInt index ) const;
329  Value &append( const Value &value );
330 
332  Value &operator[]( const char *key );
334  const Value &operator[]( const char *key ) const;
336  Value &operator[]( const std::string &key );
338  const Value &operator[]( const std::string &key ) const;
350  Value &operator[]( const StaticString &key );
351 # ifdef JSON_USE_CPPTL
352  Value &operator[]( const CppTL::ConstString &key );
355  const Value &operator[]( const CppTL::ConstString &key ) const;
356 # endif
357  Value get( const char *key,
359  const Value &defaultValue ) const;
361  Value get( const std::string &key,
362  const Value &defaultValue ) const;
363 # ifdef JSON_USE_CPPTL
364  Value get( const CppTL::ConstString &key,
366  const Value &defaultValue ) const;
367 # endif
368  Value removeMember( const char* key );
376  Value removeMember( const std::string &key );
377 
379  bool isMember( const char *key ) const;
381  bool isMember( const std::string &key ) const;
382 # ifdef JSON_USE_CPPTL
383  bool isMember( const CppTL::ConstString &key ) const;
385 # endif
386 
392  Members getMemberNames() const;
393 
394 //# ifdef JSON_USE_CPPTL
395 // EnumMemberNames enumMemberNames() const;
396 // EnumValues enumValues() const;
397 //# endif
398 
400  void setComment( const char *comment,
401  CommentPlacement placement );
403  void setComment( const std::string &comment,
404  CommentPlacement placement );
405  bool hasComment( CommentPlacement placement ) const;
407  std::string getComment( CommentPlacement placement ) const;
408 
409  std::string toStyledString() const;
410 
411  const_iterator begin() const;
412  const_iterator end() const;
413 
414  iterator begin();
415  iterator end();
416 
417  private:
418  Value &resolveReference( const char *key,
419  bool isStatic );
420 
421 # ifdef JSON_VALUE_USE_INTERNAL_MAP
422  inline bool isItemAvailable() const
423  {
424  return itemIsUsed_ == 0;
425  }
426 
427  inline void setItemUsed( bool isUsed = true )
428  {
429  itemIsUsed_ = isUsed ? 1 : 0;
430  }
431 
432  inline bool isMemberNameStatic() const
433  {
434  return memberNameIsStatic_ == 0;
435  }
436 
437  inline void setMemberNameIsStatic( bool isStatic )
438  {
439  memberNameIsStatic_ = isStatic ? 1 : 0;
440  }
441 # endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
442 
443  private:
444  struct CommentInfo
445  {
446  CommentInfo();
447  ~CommentInfo();
448 
449  void setComment( const char *text );
450 
451  char *comment_;
452  };
453 
454  //struct MemberNamesTransform
455  //{
456  // typedef const char *result_type;
457  // const char *operator()( const CZString &name ) const
458  // {
459  // return name.c_str();
460  // }
461  //};
462 
464  {
465  Int int_;
466  UInt uint_;
467  double real_;
468  bool bool_;
469  char *string_;
470 # ifdef JSON_VALUE_USE_INTERNAL_MAP
471  ValueInternalArray *array_;
472  ValueInternalMap *map_;
473 #else
474  ObjectValues *map_;
475 # endif
476  } value_;
477  ValueType type_;
478  bool allocated_; // Notes: if declared as bool, bitfield is useless.
479 # ifdef JSON_VALUE_USE_INTERNAL_MAP
480  unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
481  int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
482 # endif
483  CommentInfo *comments_;
484  };
485 
486 
490  {
491  public:
492  friend class Path;
493 
494  PathArgument();
495  PathArgument( UInt index );
496  PathArgument( const char *key );
497  PathArgument( const std::string &key );
498 
499  private:
500  enum Kind
501  {
502  kindNone = 0,
503  kindIndex,
504  kindKey
505  };
506  std::string key_;
507  UInt index_;
508  Kind kind_;
509  };
510 
522  class Path
523  {
524  public:
525  Path( const std::string &path,
526  const PathArgument &a1 = PathArgument(),
527  const PathArgument &a2 = PathArgument(),
528  const PathArgument &a3 = PathArgument(),
529  const PathArgument &a4 = PathArgument(),
530  const PathArgument &a5 = PathArgument() );
531 
532  const Value &resolve( const Value &root ) const;
533  Value resolve( const Value &root,
534  const Value &defaultValue ) const;
536  Value &make( Value &root ) const;
537 
538  private:
539  typedef std::vector<const PathArgument *> InArgs;
540  typedef std::vector<PathArgument> Args;
541 
542  void makePath( const std::string &path,
543  const InArgs &in );
544  void addPathInArg( const std::string &path,
545  const InArgs &in,
546  InArgs::const_iterator &itInArg,
547  PathArgument::Kind kind );
548  void invalidPath( const std::string &path,
549  int location ) const;
550 
551  Args args_;
552  };
553 
562  {
563  public:
564  enum { unknown = (unsigned)-1 };
565 
566  virtual ~ValueAllocator();
567 
568  virtual char *makeMemberName( const char *memberName ) = 0;
569  virtual void releaseMemberName( char *memberName ) = 0;
570  virtual char *duplicateStringValue( const char *value,
571  unsigned int length = unknown ) = 0;
572  virtual void releaseStringValue( char *value ) = 0;
573  };
574 
575 #ifdef JSON_VALUE_USE_INTERNAL_MAP
576 
620  class JSON_API ValueMapAllocator
621  {
622  public:
623  virtual ~ValueMapAllocator();
624  virtual ValueInternalMap *newMap() = 0;
625  virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
626  virtual void destructMap( ValueInternalMap *map ) = 0;
627  virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
628  virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
629  virtual ValueInternalLink *allocateMapLink() = 0;
630  virtual void releaseMapLink( ValueInternalLink *link ) = 0;
631  };
632 
636  class JSON_API ValueInternalLink
637  {
638  public:
639  enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
640  enum InternalFlags {
641  flagAvailable = 0,
642  flagUsed = 1
643  };
644 
645  ValueInternalLink();
646 
647  ~ValueInternalLink();
648 
649  Value items_[itemPerLink];
650  char *keys_[itemPerLink];
651  ValueInternalLink *previous_;
652  ValueInternalLink *next_;
653  };
654 
655 
668  class JSON_API ValueInternalMap
669  {
670  friend class ValueIteratorBase;
671  friend class Value;
672  public:
673  typedef unsigned int HashKey;
674  typedef unsigned int BucketIndex;
675 
676 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
677  struct IteratorState
678  {
679  IteratorState()
680  : map_(0)
681  , link_(0)
682  , itemIndex_(0)
683  , bucketIndex_(0)
684  {
685  }
686  ValueInternalMap *map_;
687  ValueInternalLink *link_;
688  BucketIndex itemIndex_;
689  BucketIndex bucketIndex_;
690  };
691 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
692 
693  ValueInternalMap();
694  ValueInternalMap( const ValueInternalMap &other );
695  ValueInternalMap &operator =( const ValueInternalMap &other );
696  ~ValueInternalMap();
697 
698  void swap( ValueInternalMap &other );
699 
700  BucketIndex size() const;
701 
702  void clear();
703 
704  bool reserveDelta( BucketIndex growth );
705 
706  bool reserve( BucketIndex newItemCount );
707 
708  const Value *find( const char *key ) const;
709 
710  Value *find( const char *key );
711 
712  Value &resolveReference( const char *key,
713  bool isStatic );
714 
715  void remove( const char *key );
716 
717  void doActualRemove( ValueInternalLink *link,
718  BucketIndex index,
719  BucketIndex bucketIndex );
720 
721  ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
722 
723  Value &setNewItem( const char *key,
724  bool isStatic,
725  ValueInternalLink *link,
726  BucketIndex index );
727 
728  Value &unsafeAdd( const char *key,
729  bool isStatic,
730  HashKey hashedKey );
731 
732  HashKey hash( const char *key ) const;
733 
734  int compare( const ValueInternalMap &other ) const;
735 
736  private:
737  void makeBeginIterator( IteratorState &it ) const;
738  void makeEndIterator( IteratorState &it ) const;
739  static bool equals( const IteratorState &x, const IteratorState &other );
740  static void increment( IteratorState &iterator );
741  static void incrementBucket( IteratorState &iterator );
742  static void decrement( IteratorState &iterator );
743  static const char *key( const IteratorState &iterator );
744  static const char *key( const IteratorState &iterator, bool &isStatic );
745  static Value &value( const IteratorState &iterator );
746  static int distance( const IteratorState &x, const IteratorState &y );
747 
748  private:
749  ValueInternalLink *buckets_;
750  ValueInternalLink *tailLink_;
751  BucketIndex bucketsSize_;
752  BucketIndex itemCount_;
753  };
754 
766  class JSON_API ValueInternalArray
767  {
768  friend class Value;
769  friend class ValueIteratorBase;
770  public:
771  enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo.
772  typedef Value::ArrayIndex ArrayIndex;
773  typedef unsigned int PageIndex;
774 
775 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
776  struct IteratorState // Must be a POD
777  {
778  IteratorState()
779  : array_(0)
780  , currentPageIndex_(0)
781  , currentItemIndex_(0)
782  {
783  }
784  ValueInternalArray *array_;
785  Value **currentPageIndex_;
786  unsigned int currentItemIndex_;
787  };
788 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
789 
790  ValueInternalArray();
791  ValueInternalArray( const ValueInternalArray &other );
792  ValueInternalArray &operator =( const ValueInternalArray &other );
793  ~ValueInternalArray();
794  void swap( ValueInternalArray &other );
795 
796  void clear();
797  void resize( ArrayIndex newSize );
798 
799  Value &resolveReference( ArrayIndex index );
800 
801  Value *find( ArrayIndex index ) const;
802 
803  ArrayIndex size() const;
804 
805  int compare( const ValueInternalArray &other ) const;
806 
807  private:
808  static bool equals( const IteratorState &x, const IteratorState &other );
809  static void increment( IteratorState &iterator );
810  static void decrement( IteratorState &iterator );
811  static Value &dereference( const IteratorState &iterator );
812  static Value &unsafeDereference( const IteratorState &iterator );
813  static int distance( const IteratorState &x, const IteratorState &y );
814  static ArrayIndex indexOf( const IteratorState &iterator );
815  void makeBeginIterator( IteratorState &it ) const;
816  void makeEndIterator( IteratorState &it ) const;
817  void makeIterator( IteratorState &it, ArrayIndex index ) const;
818 
819  void makeIndexValid( ArrayIndex index );
820 
821  Value **pages_;
822  ArrayIndex size_;
823  PageIndex pageCount_;
824  };
825 
885  class JSON_API ValueArrayAllocator
886  {
887  public:
888  virtual ~ValueArrayAllocator();
889  virtual ValueInternalArray *newArray() = 0;
890  virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
891  virtual void destructArray( ValueInternalArray *array ) = 0;
903  virtual void reallocateArrayPageIndex( Value **&indexes,
904  ValueInternalArray::PageIndex &indexCount,
905  ValueInternalArray::PageIndex minNewIndexCount ) = 0;
906  virtual void releaseArrayPageIndex( Value **indexes,
907  ValueInternalArray::PageIndex indexCount ) = 0;
908  virtual Value *allocateArrayPage() = 0;
909  virtual void releaseArrayPage( Value *value ) = 0;
910  };
911 #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
912 
913 
918  {
919  public:
920  typedef unsigned int size_t;
921  typedef int difference_type;
922  typedef ValueIteratorBase SelfType;
923 
925 #ifndef JSON_VALUE_USE_INTERNAL_MAP
926  explicit ValueIteratorBase( const Value::ObjectValues::iterator &current );
927 #else
928  ValueIteratorBase( const ValueInternalArray::IteratorState &state );
929  ValueIteratorBase( const ValueInternalMap::IteratorState &state );
930 #endif
931 
932  bool operator ==( const SelfType &other ) const
933  {
934  return isEqual( other );
935  }
936 
937  bool operator !=( const SelfType &other ) const
938  {
939  return !isEqual( other );
940  }
941 
942  difference_type operator -( const SelfType &other ) const
943  {
944  return computeDistance( other );
945  }
946 
948  Value key() const;
949 
951  UInt index() const;
952 
954  const char *memberName() const;
955 
956  protected:
957  Value &deref() const;
958 
959  void increment();
960 
961  void decrement();
962 
963  difference_type computeDistance( const SelfType &other ) const;
964 
965  bool isEqual( const SelfType &other ) const;
966 
967  void copy( const SelfType &other );
968 
969  private:
970 #ifndef JSON_VALUE_USE_INTERNAL_MAP
971  Value::ObjectValues::iterator current_;
972  // Indicates that iterator is for a null value.
973  bool isNull_;
974 #else
975  union
976  {
977  ValueInternalArray::IteratorState array_;
978  ValueInternalMap::IteratorState map_;
979  } iterator_;
980  bool isArray_;
981 #endif
982  };
983 
988  {
989  friend class Value;
990  public:
991  typedef unsigned int size_t;
992  typedef int difference_type;
993  typedef const Value &reference;
994  typedef const Value *pointer;
996 
998  private:
1001 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1002  explicit ValueConstIterator( const Value::ObjectValues::iterator &current );
1003 #else
1004  ValueConstIterator( const ValueInternalArray::IteratorState &state );
1005  ValueConstIterator( const ValueInternalMap::IteratorState &state );
1006 #endif
1007  public:
1008  SelfType &operator =( const ValueIteratorBase &other );
1009 
1010  SelfType operator++( int )
1011  {
1012  SelfType temp( *this );
1013  ++*this;
1014  return temp;
1015  }
1016 
1017  SelfType operator--( int )
1018  {
1019  SelfType temp( *this );
1020  --*this;
1021  return temp;
1022  }
1023 
1024  SelfType &operator--()
1025  {
1026  decrement();
1027  return *this;
1028  }
1029 
1030  SelfType &operator++()
1031  {
1032  increment();
1033  return *this;
1034  }
1035 
1036  reference operator *() const
1037  {
1038  return deref();
1039  }
1040  };
1041 
1042 
1046  {
1047  friend class Value;
1048  public:
1049  typedef unsigned int size_t;
1050  typedef int difference_type;
1051  typedef Value &reference;
1052  typedef Value *pointer;
1053  typedef ValueIterator SelfType;
1054 
1055  ValueIterator();
1056  ValueIterator( const ValueConstIterator &other );
1057  ValueIterator( const ValueIterator &other );
1058  private:
1061 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1062  explicit ValueIterator( const Value::ObjectValues::iterator &current );
1063 #else
1064  ValueIterator( const ValueInternalArray::IteratorState &state );
1065  ValueIterator( const ValueInternalMap::IteratorState &state );
1066 #endif
1067  public:
1068 
1069  SelfType &operator =( const SelfType &other );
1070 
1071  SelfType operator++( int )
1072  {
1073  SelfType temp( *this );
1074  ++*this;
1075  return temp;
1076  }
1077 
1078  SelfType operator--( int )
1079  {
1080  SelfType temp( *this );
1081  --*this;
1082  return temp;
1083  }
1084 
1085  SelfType &operator--()
1086  {
1087  decrement();
1088  return *this;
1089  }
1090 
1091  SelfType &operator++()
1092  {
1093  increment();
1094  return *this;
1095  }
1096 
1097  reference operator *() const
1098  {
1099  return deref();
1100  }
1101  };
1102 
1103 
1104 } // namespace Json
1105 
1106 
1107 #endif // CPPTL_JSON_H_INCLUDED