JsonCpp project page JsonCpp home page

value.h
Go to the documentation of this file.
1 // Copyright 2007-2010 Baptiste Lepilleur
2 // Distributed under MIT license, or public domain if desired and
3 // recognized in your jurisdiction.
4 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5 
6 #ifndef CPPTL_JSON_H_INCLUDED
7 #define CPPTL_JSON_H_INCLUDED
8 
9 #if !defined(JSON_IS_AMALGAMATION)
10 #include "forwards.h"
11 #endif // if !defined(JSON_IS_AMALGAMATION)
12 #include <string>
13 #include <vector>
14 #include <exception>
15 
16 #ifndef JSON_USE_CPPTL_SMALLMAP
17 #include <map>
18 #else
19 #include <cpptl/smallmap.h>
20 #endif
21 #ifdef JSON_USE_CPPTL
22 #include <cpptl/forwards.h>
23 #endif
24 
25 // Disable warning C4251: <data member>: <type> needs to have dll-interface to
26 // be used by...
27 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
28 #pragma warning(push)
29 #pragma warning(disable : 4251)
30 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
31 
34 namespace Json {
35 
40 class JSON_API Exception : public std::exception {
41 public:
42  Exception(std::string const& msg);
43  ~Exception() throw() override;
44  char const* what() const throw() override;
45 protected:
46  std::string msg_;
47 };
48 
56 public:
57  RuntimeError(std::string const& msg);
58 };
59 
66 class JSON_API LogicError : public Exception {
67 public:
68  LogicError(std::string const& msg);
69 };
70 
72 void throwRuntimeError(std::string const& msg);
74 void throwLogicError(std::string const& msg);
75 
78 enum ValueType {
79  nullValue = 0,
87 };
88 
93 
95 };
96 
97 //# ifdef JSON_USE_CPPTL
98 // typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
99 // typedef CppTL::AnyEnumerator<const Value &> EnumValues;
100 //# endif
101 
117 public:
118  explicit StaticString(const char* czstring) : c_str_(czstring) {}
119 
120  operator const char*() const { return c_str_; }
121 
122  const char* c_str() const { return c_str_; }
123 
124 private:
125  const char* c_str_;
126 };
127 
163  friend class ValueIteratorBase;
164 public:
165  typedef std::vector<std::string> Members;
168  typedef Json::UInt UInt;
169  typedef Json::Int Int;
170 #if defined(JSON_HAS_INT64)
173 #endif // defined(JSON_HAS_INT64)
177 
178  static const Value& null;
179  static const Value& nullRef;
180 
181  static const LargestInt minLargestInt;
183  static const LargestInt maxLargestInt;
186 
188  static const Int minInt;
190  static const Int maxInt;
192  static const UInt maxUInt;
193 
194 #if defined(JSON_HAS_INT64)
195 
196  static const Int64 minInt64;
198  static const Int64 maxInt64;
200  static const UInt64 maxUInt64;
201 #endif // defined(JSON_HAS_INT64)
202 
203 private:
204 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
205  class CZString {
206  public:
207  enum DuplicationPolicy {
208  noDuplication = 0,
209  duplicate,
210  duplicateOnCopy
211  };
212  CZString(ArrayIndex index);
213  CZString(char const* str, unsigned length, DuplicationPolicy allocate);
214  CZString(CZString const& other);
215 #if JSON_HAS_RVALUE_REFERENCES
216  CZString(CZString&& other);
217 #endif
218  ~CZString();
219  CZString& operator=(CZString other);
220  bool operator<(CZString const& other) const;
221  bool operator==(CZString const& other) const;
222  ArrayIndex index() const;
223  //const char* c_str() const; ///< \deprecated
224  char const* data() const;
225  unsigned length() const;
226  bool isStaticString() const;
227 
228  private:
229  void swap(CZString& other);
230 
231  struct StringStorage {
232  unsigned policy_: 2;
233  unsigned length_: 30; // 1GB max
234  };
235 
236  char const* cstr_; // actually, a prefixed string, unless policy is noDup
237  union {
238  ArrayIndex index_;
239  StringStorage storage_;
240  };
241  };
242 
243 public:
244 #ifndef JSON_USE_CPPTL_SMALLMAP
245  typedef std::map<CZString, Value> ObjectValues;
246 #else
247  typedef CppTL::SmallMap<CZString, Value> ObjectValues;
248 #endif // ifndef JSON_USE_CPPTL_SMALLMAP
249 #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
250 
251 public:
267  Value(ValueType type = nullValue);
268  Value(Int value);
269  Value(UInt value);
270 #if defined(JSON_HAS_INT64)
271  Value(Int64 value);
272  Value(UInt64 value);
273 #endif // if defined(JSON_HAS_INT64)
274  Value(double value);
275  Value(const char* value);
276  Value(const char* begin, const char* end);
277 
292  Value(const StaticString& value);
293  Value(const std::string& value);
294 #ifdef JSON_USE_CPPTL
295  Value(const CppTL::ConstString& value);
296 #endif
297  Value(bool value);
299  Value(const Value& other);
300 #if JSON_HAS_RVALUE_REFERENCES
301 
302  Value(Value&& other);
303 #endif
304  ~Value();
305 
308  Value& operator=(Value other);
310  void swap(Value& other);
312  void swapPayload(Value& other);
313 
314  ValueType type() const;
315 
317  bool operator<(const Value& other) const;
318  bool operator<=(const Value& other) const;
319  bool operator>=(const Value& other) const;
320  bool operator>(const Value& other) const;
321  bool operator==(const Value& other) const;
322  bool operator!=(const Value& other) const;
323  int compare(const Value& other) const;
324 
325  const char* asCString() const;
326  std::string asString() const;
327 
330  bool getString(
331  char const** begin, char const** end) const;
332 #ifdef JSON_USE_CPPTL
333  CppTL::ConstString asConstString() const;
334 #endif
335  Int asInt() const;
336  UInt asUInt() const;
337 #if defined(JSON_HAS_INT64)
338  Int64 asInt64() const;
339  UInt64 asUInt64() const;
340 #endif // if defined(JSON_HAS_INT64)
341  LargestInt asLargestInt() const;
342  LargestUInt asLargestUInt() const;
343  float asFloat() const;
344  double asDouble() const;
345  bool asBool() const;
346 
347  bool isNull() const;
348  bool isBool() const;
349  bool isInt() const;
350  bool isInt64() const;
351  bool isUInt() const;
352  bool isUInt64() const;
353  bool isIntegral() const;
354  bool isDouble() const;
355  bool isNumeric() const;
356  bool isString() const;
357  bool isArray() const;
358  bool isObject() const;
359 
360  bool isConvertibleTo(ValueType other) const;
361 
363  ArrayIndex size() const;
364 
367  bool empty() const;
368 
370  bool operator!() const;
371 
375  void clear();
376 
382  void resize(ArrayIndex size);
383 
390  Value& operator[](ArrayIndex index);
391 
398  Value& operator[](int index);
399 
403  const Value& operator[](ArrayIndex index) const;
404 
408  const Value& operator[](int index) const;
409 
413  Value get(ArrayIndex index, const Value& defaultValue) const;
415  bool isValidIndex(ArrayIndex index) const;
419  Value& append(const Value& value);
420 
424  Value& operator[](const char* key);
427  const Value& operator[](const char* key) const;
430  Value& operator[](const std::string& key);
434  const Value& operator[](const std::string& key) const;
447  Value& operator[](const StaticString& key);
448 #ifdef JSON_USE_CPPTL
449 
450  Value& operator[](const CppTL::ConstString& key);
453  const Value& operator[](const CppTL::ConstString& key) const;
454 #endif
455 
456 
457  Value get(const char* key, const Value& defaultValue) const;
461  Value get(const char* begin, const char* end, const Value& defaultValue) const;
465  Value get(const std::string& key, const Value& defaultValue) const;
466 #ifdef JSON_USE_CPPTL
467 
468 
469  Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
470 #endif
471 
472 
473 
474  Value const* find(char const* begin, char const* end) const;
478  Value const* demand(char const* begin, char const* end);
486  Value removeMember(const char* key);
490  Value removeMember(const std::string& key);
493  bool removeMember(const char* key, Value* removed);
500  bool removeMember(std::string const& key, Value* removed);
502  bool removeMember(const char* begin, const char* end, Value* removed);
509  bool removeIndex(ArrayIndex i, Value* removed);
510 
513  bool isMember(const char* key) const;
516  bool isMember(const std::string& key) const;
518  bool isMember(const char* begin, const char* end) const;
519 #ifdef JSON_USE_CPPTL
520 
521  bool isMember(const CppTL::ConstString& key) const;
522 #endif
523 
529  Members getMemberNames() const;
530 
531  //# ifdef JSON_USE_CPPTL
532  // EnumMemberNames enumMemberNames() const;
533  // EnumValues enumValues() const;
534  //# endif
535 
537  JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.")
538  void setComment(const char* comment, CommentPlacement placement);
540  void setComment(const char* comment, size_t len, CommentPlacement placement);
542  void setComment(const std::string& comment, CommentPlacement placement);
543  bool hasComment(CommentPlacement placement) const;
545  std::string getComment(CommentPlacement placement) const;
546 
547  std::string toStyledString() const;
548 
549  const_iterator begin() const;
550  const_iterator end() const;
551 
552  iterator begin();
553  iterator end();
554 
555  // Accessors for the [start, limit) range of bytes within the JSON text from
556  // which this value was parsed, if any.
557  void setOffsetStart(size_t start);
558  void setOffsetLimit(size_t limit);
559  size_t getOffsetStart() const;
560  size_t getOffsetLimit() const;
561 
562 private:
563  void initBasic(ValueType type, bool allocated = false);
564 
565  Value& resolveReference(const char* key);
566  Value& resolveReference(const char* key, const char* end);
567 
568  struct CommentInfo {
569  CommentInfo();
570  ~CommentInfo();
571 
572  void setComment(const char* text, size_t len);
573 
574  char* comment_;
575  };
576 
577  // struct MemberNamesTransform
578  //{
579  // typedef const char *result_type;
580  // const char *operator()( const CZString &name ) const
581  // {
582  // return name.c_str();
583  // }
584  //};
585 
586  union ValueHolder {
587  LargestInt int_;
588  LargestUInt uint_;
589  double real_;
590  bool bool_;
591  char* string_; // actually ptr to unsigned, followed by str, unless !allocated_
592  ObjectValues* map_;
593  } value_;
594  ValueType type_ : 8;
595  unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
596  // If not allocated_, string_ must be null-terminated.
597  CommentInfo* comments_;
598 
599  // [start, limit) byte offsets in the source JSON text from which this Value
600  // was extracted.
601  size_t start_;
602  size_t limit_;
603 };
604 
609 public:
610  friend class Path;
611 
612  PathArgument();
613  PathArgument(ArrayIndex index);
614  PathArgument(const char* key);
615  PathArgument(const std::string& key);
616 
617 private:
618  enum Kind {
619  kindNone = 0,
620  kindIndex,
621  kindKey
622  };
623  std::string key_;
624  ArrayIndex index_;
625  Kind kind_;
626 };
627 
639 class JSON_API Path {
640 public:
641  Path(const std::string& path,
642  const PathArgument& a1 = PathArgument(),
643  const PathArgument& a2 = PathArgument(),
644  const PathArgument& a3 = PathArgument(),
645  const PathArgument& a4 = PathArgument(),
646  const PathArgument& a5 = PathArgument());
647 
648  const Value& resolve(const Value& root) const;
649  Value resolve(const Value& root, const Value& defaultValue) const;
652  Value& make(Value& root) const;
653 
654 private:
655  typedef std::vector<const PathArgument*> InArgs;
656  typedef std::vector<PathArgument> Args;
657 
658  void makePath(const std::string& path, const InArgs& in);
659  void addPathInArg(const std::string& path,
660  const InArgs& in,
661  InArgs::const_iterator& itInArg,
662  PathArgument::Kind kind);
663  void invalidPath(const std::string& path, int location);
664 
665  Args args_;
666 };
667 
672 public:
673  typedef std::bidirectional_iterator_tag iterator_category;
674  typedef unsigned int size_t;
675  typedef int difference_type;
677 
678  bool operator==(const SelfType& other) const { return isEqual(other); }
679 
680  bool operator!=(const SelfType& other) const { return !isEqual(other); }
681 
682  difference_type operator-(const SelfType& other) const {
683  return other.computeDistance(*this);
684  }
685 
688  Value key() const;
689 
691  UInt index() const;
692 
696  std::string name() const;
697 
701  JSONCPP_DEPRECATED("Use `key = name();` instead.")
702  char const* memberName() const;
706  char const* memberName(char const** end) const;
707 
708 protected:
709  Value& deref() const;
710 
711  void increment();
712 
713  void decrement();
714 
715  difference_type computeDistance(const SelfType& other) const;
716 
717  bool isEqual(const SelfType& other) const;
718 
719  void copy(const SelfType& other);
720 
721 private:
722  Value::ObjectValues::iterator current_;
723  // Indicates that iterator is for a null value.
724  bool isNull_;
725 
726 public:
727  // For some reason, BORLAND needs these at the end, rather
728  // than earlier. No idea why.
730  explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
731 };
732 
736 class JSON_API ValueConstIterator : public ValueIteratorBase {
737  friend class Value;
738 
739 public:
740  typedef const Value value_type;
741  //typedef unsigned int size_t;
742  //typedef int difference_type;
743  typedef const Value& reference;
744  typedef const Value* pointer;
746 
748  ValueConstIterator(ValueIterator const& other);
749 
750 private:
753  explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
754 public:
755  SelfType& operator=(const ValueIteratorBase& other);
756 
757  SelfType operator++(int) {
758  SelfType temp(*this);
759  ++*this;
760  return temp;
761  }
762 
763  SelfType operator--(int) {
764  SelfType temp(*this);
765  --*this;
766  return temp;
767  }
768 
769  SelfType& operator--() {
770  decrement();
771  return *this;
772  }
773 
774  SelfType& operator++() {
775  increment();
776  return *this;
777  }
778 
779  reference operator*() const { return deref(); }
780 
781  pointer operator->() const { return &deref(); }
782 };
783 
787  friend class Value;
788 
789 public:
790  typedef Value value_type;
791  typedef unsigned int size_t;
792  typedef int difference_type;
793  typedef Value& reference;
794  typedef Value* pointer;
796 
797  ValueIterator();
798  explicit ValueIterator(const ValueConstIterator& other);
799  ValueIterator(const ValueIterator& other);
800 
801 private:
804  explicit ValueIterator(const Value::ObjectValues::iterator& current);
805 public:
806  SelfType& operator=(const SelfType& other);
807 
809  SelfType temp(*this);
810  ++*this;
811  return temp;
812  }
813 
815  SelfType temp(*this);
816  --*this;
817  return temp;
818  }
819 
821  decrement();
822  return *this;
823  }
824 
826  increment();
827  return *this;
828  }
829 
830  reference operator*() const { return deref(); }
831 
832  pointer operator->() const { return &deref(); }
833 };
834 
835 } // namespace Json
836 
837 
838 namespace std {
840 template<>
841 inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
842 }
843 
844 
845 #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
846 #pragma warning(pop)
847 #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
848 
849 #endif // CPPTL_JSON_H_INCLUDED