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();
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  char *value_as_string_; // Used when asString is called on non-string types.
485  };
486 
487 
491  {
492  public:
493  friend class Path;
494 
495  PathArgument();
496  PathArgument( UInt index );
497  PathArgument( const char *key );
498  PathArgument( const std::string &key );
499 
500  private:
501  enum Kind
502  {
503  kindNone = 0,
504  kindIndex,
505  kindKey
506  };
507  std::string key_;
508  UInt index_;
509  Kind kind_;
510  };
511 
523  class Path
524  {
525  public:
526  Path( const std::string &path,
527  const PathArgument &a1 = PathArgument(),
528  const PathArgument &a2 = PathArgument(),
529  const PathArgument &a3 = PathArgument(),
530  const PathArgument &a4 = PathArgument(),
531  const PathArgument &a5 = PathArgument() );
532 
533  const Value &resolve( const Value &root ) const;
534  Value resolve( const Value &root,
535  const Value &defaultValue ) const;
537  Value &make( Value &root ) const;
538 
539  private:
540  typedef std::vector<const PathArgument *> InArgs;
541  typedef std::vector<PathArgument> Args;
542 
543  void makePath( const std::string &path,
544  const InArgs &in );
545  void addPathInArg( const std::string &path,
546  const InArgs &in,
547  InArgs::const_iterator &itInArg,
548  PathArgument::Kind kind );
549  void invalidPath( const std::string &path,
550  int location ) const;
551 
552  Args args_;
553  };
554 
563  {
564  public:
565  enum { unknown = (unsigned)-1 };
566 
567  virtual ~ValueAllocator();
568 
569  virtual char *makeMemberName( const char *memberName ) = 0;
570  virtual void releaseMemberName( char *memberName ) = 0;
571  virtual char *duplicateStringValue( const char *value,
572  unsigned int length = unknown ) = 0;
573  virtual void releaseStringValue( char *value ) = 0;
574  };
575 
576 #ifdef JSON_VALUE_USE_INTERNAL_MAP
577 
621  class JSON_API ValueMapAllocator
622  {
623  public:
624  virtual ~ValueMapAllocator();
625  virtual ValueInternalMap *newMap() = 0;
626  virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
627  virtual void destructMap( ValueInternalMap *map ) = 0;
628  virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
629  virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
630  virtual ValueInternalLink *allocateMapLink() = 0;
631  virtual void releaseMapLink( ValueInternalLink *link ) = 0;
632  };
633 
637  class JSON_API ValueInternalLink
638  {
639  public:
640  enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
641  enum InternalFlags {
642  flagAvailable = 0,
643  flagUsed = 1
644  };
645 
646  ValueInternalLink();
647 
648  ~ValueInternalLink();
649 
650  Value items_[itemPerLink];
651  char *keys_[itemPerLink];
652  ValueInternalLink *previous_;
653  ValueInternalLink *next_;
654  };
655 
656 
669  class JSON_API ValueInternalMap
670  {
671  friend class ValueIteratorBase;
672  friend class Value;
673  public:
674  typedef unsigned int HashKey;
675  typedef unsigned int BucketIndex;
676 
677 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
678  struct IteratorState
679  {
680  IteratorState()
681  : map_(0)
682  , link_(0)
683  , itemIndex_(0)
684  , bucketIndex_(0)
685  {
686  }
687  ValueInternalMap *map_;
688  ValueInternalLink *link_;
689  BucketIndex itemIndex_;
690  BucketIndex bucketIndex_;
691  };
692 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
693 
694  ValueInternalMap();
695  ValueInternalMap( const ValueInternalMap &other );
696  ValueInternalMap &operator =( const ValueInternalMap &other );
697  ~ValueInternalMap();
698 
699  void swap( ValueInternalMap &other );
700 
701  BucketIndex size() const;
702 
703  void clear();
704 
705  bool reserveDelta( BucketIndex growth );
706 
707  bool reserve( BucketIndex newItemCount );
708 
709  const Value *find( const char *key ) const;
710 
711  Value *find( const char *key );
712 
713  Value &resolveReference( const char *key,
714  bool isStatic );
715 
716  void remove( const char *key );
717 
718  void doActualRemove( ValueInternalLink *link,
719  BucketIndex index,
720  BucketIndex bucketIndex );
721 
722  ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
723 
724  Value &setNewItem( const char *key,
725  bool isStatic,
726  ValueInternalLink *link,
727  BucketIndex index );
728 
729  Value &unsafeAdd( const char *key,
730  bool isStatic,
731  HashKey hashedKey );
732 
733  HashKey hash( const char *key ) const;
734 
735  int compare( const ValueInternalMap &other ) const;
736 
737  private:
738  void makeBeginIterator( IteratorState &it ) const;
739  void makeEndIterator( IteratorState &it ) const;
740  static bool equals( const IteratorState &x, const IteratorState &other );
741  static void increment( IteratorState &iterator );
742  static void incrementBucket( IteratorState &iterator );
743  static void decrement( IteratorState &iterator );
744  static const char *key( const IteratorState &iterator );
745  static const char *key( const IteratorState &iterator, bool &isStatic );
746  static Value &value( const IteratorState &iterator );
747  static int distance( const IteratorState &x, const IteratorState &y );
748 
749  private:
750  ValueInternalLink *buckets_;
751  ValueInternalLink *tailLink_;
752  BucketIndex bucketsSize_;
753  BucketIndex itemCount_;
754  };
755 
767  class JSON_API ValueInternalArray
768  {
769  friend class Value;
770  friend class ValueIteratorBase;
771  public:
772  enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo.
773  typedef Value::ArrayIndex ArrayIndex;
774  typedef unsigned int PageIndex;
775 
776 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
777  struct IteratorState // Must be a POD
778  {
779  IteratorState()
780  : array_(0)
781  , currentPageIndex_(0)
782  , currentItemIndex_(0)
783  {
784  }
785  ValueInternalArray *array_;
786  Value **currentPageIndex_;
787  unsigned int currentItemIndex_;
788  };
789 # endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
790 
791  ValueInternalArray();
792  ValueInternalArray( const ValueInternalArray &other );
793  ValueInternalArray &operator =( const ValueInternalArray &other );
794  ~ValueInternalArray();
795  void swap( ValueInternalArray &other );
796 
797  void clear();
798  void resize( ArrayIndex newSize );
799 
800  Value &resolveReference( ArrayIndex index );
801 
802  Value *find( ArrayIndex index ) const;
803 
804  ArrayIndex size() const;
805 
806  int compare( const ValueInternalArray &other ) const;
807 
808  private:
809  static bool equals( const IteratorState &x, const IteratorState &other );
810  static void increment( IteratorState &iterator );
811  static void decrement( IteratorState &iterator );
812  static Value &dereference( const IteratorState &iterator );
813  static Value &unsafeDereference( const IteratorState &iterator );
814  static int distance( const IteratorState &x, const IteratorState &y );
815  static ArrayIndex indexOf( const IteratorState &iterator );
816  void makeBeginIterator( IteratorState &it ) const;
817  void makeEndIterator( IteratorState &it ) const;
818  void makeIterator( IteratorState &it, ArrayIndex index ) const;
819 
820  void makeIndexValid( ArrayIndex index );
821 
822  Value **pages_;
823  ArrayIndex size_;
824  PageIndex pageCount_;
825  };
826 
886  class JSON_API ValueArrayAllocator
887  {
888  public:
889  virtual ~ValueArrayAllocator();
890  virtual ValueInternalArray *newArray() = 0;
891  virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
892  virtual void destructArray( ValueInternalArray *array ) = 0;
904  virtual void reallocateArrayPageIndex( Value **&indexes,
905  ValueInternalArray::PageIndex &indexCount,
906  ValueInternalArray::PageIndex minNewIndexCount ) = 0;
907  virtual void releaseArrayPageIndex( Value **indexes,
908  ValueInternalArray::PageIndex indexCount ) = 0;
909  virtual Value *allocateArrayPage() = 0;
910  virtual void releaseArrayPage( Value *value ) = 0;
911  };
912 #endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
913 
914 
919  {
920  public:
921  typedef unsigned int size_t;
922  typedef int difference_type;
923  typedef ValueIteratorBase SelfType;
924 
926 #ifndef JSON_VALUE_USE_INTERNAL_MAP
927  explicit ValueIteratorBase( const Value::ObjectValues::iterator &current );
928 #else
929  ValueIteratorBase( const ValueInternalArray::IteratorState &state );
930  ValueIteratorBase( const ValueInternalMap::IteratorState &state );
931 #endif
932 
933  bool operator ==( const SelfType &other ) const
934  {
935  return isEqual( other );
936  }
937 
938  bool operator !=( const SelfType &other ) const
939  {
940  return !isEqual( other );
941  }
942 
943  difference_type operator -( const SelfType &other ) const
944  {
945  return computeDistance( other );
946  }
947 
949  Value key() const;
950 
952  UInt index() const;
953 
955  const char *memberName() const;
956 
957  protected:
958  Value &deref() const;
959 
960  void increment();
961 
962  void decrement();
963 
964  difference_type computeDistance( const SelfType &other ) const;
965 
966  bool isEqual( const SelfType &other ) const;
967 
968  void copy( const SelfType &other );
969 
970  private:
971 #ifndef JSON_VALUE_USE_INTERNAL_MAP
972  Value::ObjectValues::iterator current_;
973  // Indicates that iterator is for a null value.
974  bool isNull_;
975 #else
976  union
977  {
978  ValueInternalArray::IteratorState array_;
979  ValueInternalMap::IteratorState map_;
980  } iterator_;
981  bool isArray_;
982 #endif
983  };
984 
989  {
990  friend class Value;
991  public:
992  typedef unsigned int size_t;
993  typedef int difference_type;
994  typedef const Value &reference;
995  typedef const Value *pointer;
997 
999  private:
1002 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1003  explicit ValueConstIterator( const Value::ObjectValues::iterator &current );
1004 #else
1005  ValueConstIterator( const ValueInternalArray::IteratorState &state );
1006  ValueConstIterator( const ValueInternalMap::IteratorState &state );
1007 #endif
1008  public:
1009  SelfType &operator =( const ValueIteratorBase &other );
1010 
1011  SelfType operator++( int )
1012  {
1013  SelfType temp( *this );
1014  ++*this;
1015  return temp;
1016  }
1017 
1018  SelfType operator--( int )
1019  {
1020  SelfType temp( *this );
1021  --*this;
1022  return temp;
1023  }
1024 
1025  SelfType &operator--()
1026  {
1027  decrement();
1028  return *this;
1029  }
1030 
1031  SelfType &operator++()
1032  {
1033  increment();
1034  return *this;
1035  }
1036 
1037  reference operator *() const
1038  {
1039  return deref();
1040  }
1041  };
1042 
1043 
1047  {
1048  friend class Value;
1049  public:
1050  typedef unsigned int size_t;
1051  typedef int difference_type;
1052  typedef Value &reference;
1053  typedef Value *pointer;
1054  typedef ValueIterator SelfType;
1055 
1056  ValueIterator();
1057  ValueIterator( const ValueConstIterator &other );
1058  ValueIterator( const ValueIterator &other );
1059  private:
1062 #ifndef JSON_VALUE_USE_INTERNAL_MAP
1063  explicit ValueIterator( const Value::ObjectValues::iterator &current );
1064 #else
1065  ValueIterator( const ValueInternalArray::IteratorState &state );
1066  ValueIterator( const ValueInternalMap::IteratorState &state );
1067 #endif
1068  public:
1069 
1070  SelfType &operator =( const SelfType &other );
1071 
1072  SelfType operator++( int )
1073  {
1074  SelfType temp( *this );
1075  ++*this;
1076  return temp;
1077  }
1078 
1079  SelfType operator--( int )
1080  {
1081  SelfType temp( *this );
1082  --*this;
1083  return temp;
1084  }
1085 
1086  SelfType &operator--()
1087  {
1088  decrement();
1089  return *this;
1090  }
1091 
1092  SelfType &operator++()
1093  {
1094  increment();
1095  return *this;
1096  }
1097 
1098  reference operator *() const
1099  {
1100  return deref();
1101  }
1102  };
1103 
1104 
1105 } // namespace Json
1106 
1107 
1108 #endif // CPPTL_JSON_H_INCLUDED