HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_JSONValueMap.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_JSONValueMap.h ( UT Library, C++)
7  *
8  * COMMENTS: The order is maintained as objects are added to the map
9  */
10 
11 #ifndef __UT_JSONValueMap__
12 #define __UT_JSONValueMap__
13 
14 #include "UT_API.h"
15 #include "UT_Array.h"
16 #include "UT_ArrayStringMap.h"
17 #include "UT_StringArray.h"
18 #include "UT_StringHolder.h"
19 #include <SYS/SYS_AtomicInt.h>
20 #include <SYS/SYS_Compiler.h>
21 #include <SYS/SYS_Types.h>
22 #include <SYS/SYS_Hash.h>
23 
24 #include <stdexcept>
25 
26 class UT_JSONValue;
27 class UT_JSONValueArray;
28 class UT_JSONWriter;
29 
30 class UT_API UT_JSONValueException : public std::runtime_error
31 {
32 public:
33  UT_JSONValueException() : std::runtime_error("Invalid JSONValue") {}
34  UT_JSONValueException(const char* what) : std::runtime_error(what) {}
35 };
36 
37 /// @brief UT_JSONValueMap stores a map/dictionary of UT_JSONValue objects
38 ///
39 /// UT_JSONValueMap stores a map of UT_JSONValue objects. Unlike a standard
40 /// Houdini UT_StringMap, this object maintains the sort order in which
41 /// objects were added.
42 ///
43 /// @see UT_JSONValue, UT_JSONValueArray
45 public:
47  ~UT_JSONValueMap();
48 
49  /// Reference count (for shared maps).
50  void bumpRef(int d)
51  {
52  if (!myRef.add(d))
53  delete this;
54  }
55  /// Get the number of references to this map.
56  SYS_NO_DISCARD_RESULT int getRef() const { return myRef.relaxedLoad(); }
57 
58  /// Save to an output stream
59  bool save(UT_JSONWriter &os) const;
60 
61  /// Dump to stdout (same as save to std::cout)
62  void dump() const;
63 
64  /// Get the list of keys
65  int64 getKeys(UT_StringArray &keys) const;
66 
67  /// Get a list of the keys. However, rather than duplicating the string
68  /// values, this method simply keeps shallow references. While it's more
69  /// efficient, it's also relies on the fact that the map will not change
70  /// while the string array exists.
71  int64 getKeyReferences(UT_StringArray &keys) const;
72 
73  /// Return the number of entries in the map
75  { return myArray.entries(); }
76 
77  /// Clear the entries in the map.
78  void clear();
79 
80  /// Access const entry by index
82  { return get(i); }
83  /// Access entry by index
85  { return get(i); }
86  /// Access const entry by name (may be NULL pointer if k is not a key)
88  { return get(k); }
89  /// Access entry by name (may be NULL pointer if k is not a key)
91  { return get(k); }
92 
93  /// Access const entry by index
95  { return get(i); }
96  /// Access entry by index
98  { return get(i); }
99  /// Access const entry by name (may be NULL pointer if k is not a key)
101  { return get(k); }
102  /// Access entry by name (may be NULL pointer if k is not a key)
104  { return get(k); }
105 
106  /// Access a const entry by index
108  { return myArray(i); }
109  /// Access an entry by index
111  { return myArray(i); }
112  /// Access const entry by name (may be NULL pointer if k is not a key)
113  SYS_NO_DISCARD_RESULT const UT_JSONValue *get(const UT_StringRef &k) const;
114  /// Access entry by name (may be NULL pointer if k is not a key)
116 
117  /// Access entry by name. If not found the default value is returned.
118  SYS_NO_DISCARD_RESULT int32 get(const UT_StringRef& key, int32 def_value) const;
119  /// Access entry by name. If not found the default value is returned.
120  SYS_NO_DISCARD_RESULT int64 get(const UT_StringRef& key, int64 def_value) const;
121  /// Access entry by name. If not found the default value is returned.
122  SYS_NO_DISCARD_RESULT UT_StringHolder get(const UT_StringRef& key, const UT_StringRef& def_value) const;
123  /// Access entry by name. If not found the default value is returned.
124  SYS_NO_DISCARD_RESULT UT_StringArray get(const UT_StringRef& key, const UT_StringArray& def_value) const;
125  /// Access entry by name. If not found a json value exception is thrown.
126  template <typename T>
128  {
129  T value{};
130  if (!import<T>(key, value))
131  throw UT_JSONValueException();
132  return value;
133  }
134 
135  /// Access const object entry by name (may be NULL pointer if k is not a key)
136  /// This is a convenience function to get() if we know the key is an object.
137  SYS_NO_DISCARD_RESULT const UT_JSONValueMap *getObject(const UT_StringRef& k) const;
138  /// Access object entry by name (may be NULL pointer if k is not a key)
139  /// This is a convenience function to get() if we know the key is an object.
141  /// Access const array entry by name (may be NULL pointer if k is not a key)
142  /// This is a convenience function to get() if we know the key is an array.
143  SYS_NO_DISCARD_RESULT const UT_JSONValueArray* getArray(const UT_StringRef& k) const;
144  /// Access array entry by name (may be NULL pointer if k is not a key)
145  /// This is a convenience function to get() if we know the key is an array.
147 
148  /// Add key/value pair to the map. If the key already exists, the previous
149  /// value will be deleted.
150  int64 append(const UT_StringHolder &key, UT_JSONValue *v);
151 
152  /// Remove key/value pair from the map.
153  /// Do nothing if the key does not exist.
154  void remove(const UT_StringHolder &key);
155 
156  /// Rename a key in the map.
157  /// Do nothing if the old key does not exist.
158  /// If the old key exists and another entry uses the new key
159  /// then remove the other entry and rename the entry with the old key.
160  void rename(
161  const UT_StringHolder &old_key,
162  const UT_StringHolder &new_key);
163 
164  /// Adds a new array child to this map.
165  UT_JSONValueArray *addArrayChild(const UT_StringHolder &map_key);
166 
167  /// Adds a new map child to this map.
168  UT_JSONValueMap *addMapChild(const UT_StringHolder &map_key);
169 
170  /// Key/Value imports. See UT_JSONValue for all available import types.
171  /// Returns false if the key isn't in the map, or if the import from the
172  /// UT_JSONValue fails.
173  template <typename T>
174  bool import(const UT_StringRef &key, T &result) const;
175 
176  SYS_NO_DISCARD_RESULT SYS_HashType hash() const;
177  /// @{
178  /// Check equality
179  SYS_NO_DISCARD_RESULT bool operator==(const UT_JSONValueMap &arr) const;
181  { return !(*this == arr); }
182  /// @}
183 
184 
185 private:
186  using BaseMap = UT_ArrayStringMap<UT_JSONValue *>;
187 
188  /// Iterator functionality so we can utilize C++11 range base for loops.
189  /// C++17 has deprecated inheritance from std::iterator.
190  /// We could easily promote myMap's iterators here but then we wouldn't
191  /// respect the 'append' order.
192 public:
193  class iterator
194  {
195  public:
196  iterator(exint _num, UT_JSONValueMap *_obj) : myIndex(_num), myObj(_obj){}
198  {
199  if (myIndex < myObj->myArray.entries())
200  ++myIndex;
201  return *this;
202  }
204  {
205  iterator retval = *this; ++(*this);
206  return retval;
207  }
209  {
210  if (myIndex > 0)
211  --myIndex;
212  return *this;
213  }
215  {
216  iterator retval = *this; --(*this);
217  return retval;
218  }
219  bool operator==(const iterator &other) const {return (myObj == other.myObj) && (myIndex == other.myIndex);}
220  bool operator!=(const iterator &other) const {return !(*this == other);}
222  {
223  // ordering is strictly based on the myArray order.
224  UT_StringArray keys;
225  myObj->getKeys(keys);
226  return *myObj->myMap.find(keys[myIndex]);
227  }
229  {
230  // ordering is strictly based on the myArray order.
231  UT_StringArray keys;
232  myObj->getKeys(keys);
233  return myObj->myMap.find(keys[myIndex]);
234  }
235 
236  // iterator traits
239  using pointer = const exint*;
240  using reference = const exint&;
241  using iterator_category = std::forward_iterator_tag;
242  private:
243  exint myIndex = 0;
244  UT_JSONValueMap *myObj;
245  };
246  iterator begin() { return iterator(0, this); }
247  iterator end() { return iterator(this->myArray.entries(), this); }
248  using const_iterator = const iterator;
249 
250 private:
251  /// Access entry by name. If not found a json value exception is thrown.
252  SYS_NO_DISCARD_RESULT int64 getExpectedI(const UT_StringRef& key) const;
253  /// Access entry by name. If not found a json value exception is thrown.
254  SYS_NO_DISCARD_RESULT UT_StringHolder getExpectedS(const UT_StringRef& key) const;
255  /// Access entry by name. If not found a json value exception is thrown.
256  SYS_NO_DISCARD_RESULT UT_StringArray getExpectedStringArray(const UT_StringRef& key) const;
257 
258  UT_Array<UT_JSONValue *> myArray;
260  SYS_AtomicInt32 myRef;
261 
262  friend class iterator;
263 };
264 
265 #endif
266 
void bumpRef(int d)
Reference count (for shared maps).
UT_JSONValueMap stores a map/dictionary of UT_JSONValue objects.
int int32
Definition: SYS_Types.h:39
SYS_NO_DISCARD_RESULT const UT_JSONValue * operator()(int64 i) const
Access const entry by index.
SYS_NO_DISCARD_RESULT UT_JSONValue * operator[](const UT_StringRef &k)
Access entry by name (may be NULL pointer if k is not a key)
SYS_NO_DISCARD_RESULT int64 entries() const
Return the number of entries in the map.
BaseMap::value_type value_type
SYS_NO_DISCARD_RESULT UT_JSONValue * operator[](int64 i)
Access entry by index.
OIIO_API bool rename(string_view from, string_view to, std::string &err)
UT_JSONValueArray stores a list of UT_JSONValue objects.
SYS_NO_DISCARD_RESULT bool operator!=(const UT_JSONValueMap &arr) const
int64 exint
Definition: SYS_Types.h:125
std::size_t SYS_HashType
Define the type for hash values.
Definition: SYS_Hash.h:19
#define UT_API
Definition: UT_API.h:13
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:34
const GLdouble * v
Definition: glew.h:1391
BaseMap::value_type * operator->()
SYS_NO_DISCARD_RESULT const UT_JSONValue * operator[](const UT_StringRef &k) const
Access const entry by name (may be NULL pointer if k is not a key)
uint64 value_type
Definition: GA_PrimCompat.h:29
exint find(const UT_StringRef &str, exint s=0) const
bool operator==(const iterator &other) const
bool operator!=(const iterator &other) const
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
SYS_NO_DISCARD_RESULT const UT_JSONValue * operator[](int64 i) const
Access const entry by index.
BaseMap::value_type & operator*()
long long int64
Definition: SYS_Types.h:116
#define SYS_NO_DISCARD_RESULT
Definition: SYS_Compiler.h:93
iterator(exint _num, UT_JSONValueMap *_obj)
SYS_NO_DISCARD_RESULT const UT_JSONValue * operator()(const UT_StringRef &k) const
Access const entry by name (may be NULL pointer if k is not a key)
SYS_NO_DISCARD_RESULT UT_JSONValue * operator()(int64 i)
Access entry by index.
SYS_NO_DISCARD_RESULT UT_JSONValue * operator()(const UT_StringRef &k)
Access entry by name (may be NULL pointer if k is not a key)
std::forward_iterator_tag iterator_category
SYS_NO_DISCARD_RESULT int getRef() const
Get the number of references to this map.
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:77
GLuint64EXT * result
Definition: glew.h:14007
SYS_NO_DISCARD_RESULT T getExpected(const UT_StringRef &key) const
Access entry by name. If not found a json value exception is thrown.
GLsizei const GLfloat * value
Definition: glew.h:1849
UT_JSONValueException(const char *what)