HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NET_ConvertToType.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: NET_ConvertToType.h (LM Library, C++)
7  *
8  * COMMENTS: Convert a type to another type
9  */
10 
11 #ifndef __NET_ConvertToType_H__
12 #define __NET_ConvertToType_H__
13 
14 #include "NET_API.h"
15 
16 #include <UT/UT_IntArray.h>
17 #include <UT/UT_JSONValue.h>
18 #include <UT/UT_JSONWriter.h>
19 #include <UT/UT_SGuid.h>
20 #include <UT/UT_String.h>
21 #include <UT/UT_StringArray.h>
22 #include <UT/UT_StringHolder.h>
23 #include <UT/UT_StringSet.h>
24 #include <UT/UT_StringView.h>
25 #include <UT/UT_WorkBuffer.h>
26 
27 #include <type_traits>
28 
29 #define NET_REQUIRE(_cond_) std::enable_if_t<_cond_>
30 
31 // -----------------------------------------------------------------------------
32 // Serialize Object
33 // -----------------------------------------------------------------------------
34 
35 template <typename T>
36 bool NETserialize(UT_JSONWriter& writer, const T& obj)
37 {
38  return obj.serialize(writer);
39 }
40 
41 template <typename T>
42 bool NETserialize(const UT_JSONValue& data, T& obj)
43 {
44  return obj.serialize(data);
45 }
46 
47 // -----------------------------------------------------------------------------
48 // Serialize Integers
49 // -----------------------------------------------------------------------------
50 
51 #define NET_DEFINE_INT_SERIALIZER(_T_) \
52  template <> \
53  inline bool NETserialize<_T_>(UT_JSONWriter& writer, const _T_& obj) \
54 { \
55  writer.jsonValue(obj); \
56  return true; \
57 } \
58  template <> \
59  inline bool NETserialize<_T_>(const UT_JSONValue& data, _T_& item) \
60 { \
61  int64 v = 0; \
62  bool res = data.import(v); \
63  item = static_cast<_T_>(v); \
64  return res; \
65 }
69 #undef NET_DEFINE_INT_SERIALIZER
70 
71 template <>
72 inline bool NETserialize<int64>(UT_JSONWriter& writer, const int64& obj)
73 {
74  writer.jsonValue(obj);
75  return true;
76 }
77 
78 template <>
79 inline bool NETserialize<int64>(const UT_JSONValue& data, int64& obj)
80 {
81  return data.import(obj);
82 }
83 
84 template <>
85 inline bool NETserialize<uint32>(UT_JSONWriter& writer, const uint32& obj)
86 {
87  writer.jsonValue(static_cast<int32>(obj));
88  return true;
89 }
90 
91 template <>
92 inline bool NETserialize<uint32>(const UT_JSONValue& data, uint32& obj)
93 {
94  int64 tmp = 0;
95  bool res = data.import(tmp);
96  obj = static_cast<uint32>(tmp);
97  return res;
98 }
99 
100 // -----------------------------------------------------------------------------
101 // Serialize Bool
102 // -----------------------------------------------------------------------------
103 
104 template <>
105 inline bool NETserialize<bool>(UT_JSONWriter& writer, const bool& obj)
106 {
107  writer.jsonValue(obj);
108  return true;
109 }
110 
111 template <>
112 inline bool NETserialize<bool>(const UT_JSONValue& data, bool& item)
113 {
114  return data.import(item);
115 }
116 
117 // -----------------------------------------------------------------------------
118 // Serialize String Holder
119 // -----------------------------------------------------------------------------
120 
121 template <>
123 {
124  writer.jsonValue(obj);
125  return true;
126 }
127 
128 template <>
130 {
131  return data.import(obj);
132 }
133 
134 template <>
135 inline bool NETserialize<UT_StringRef>(UT_JSONWriter& writer, const UT_StringRef& obj)
136 {
137  writer.jsonValue(obj);
138  return true;
139 }
140 
141 template <>
143 {
144  return false;
145 }
146 
147 template <>
148 inline bool NETserialize<UT_String>(UT_JSONWriter& writer, const UT_String& obj)
149 {
150  writer.jsonValue(obj);
151  return true;
152 }
153 template <>
155 {
156  if (data.getType() != UT_JSONValue::JSON_STRING)
157  return false;
158  obj = data.getS();
159  return true;
160 }
161 
162 template <>
163 inline bool NETserialize<UT_StringLit>(UT_JSONWriter& writer, const UT_StringLit& obj)
164 {
165  writer.jsonValue(obj.asRef());
166  return true;
167 }
168 
169 template <>
170 inline bool NETserialize<UT_StringLit>(const UT_JSONValue& data, UT_StringLit&) = delete;
171 
172 // -----------------------------------------------------------------------------
173 // Serialize WorkBuffer
174 // -----------------------------------------------------------------------------
175 
176 template <>
178 {
179  writer.jsonValue(obj);
180  return true;
181 }
182 
183 template <>
185 {
186  return data.import(obj);
187 }
188 
189 // -----------------------------------------------------------------------------
190 // Serialize UT_SGuid
191 // -----------------------------------------------------------------------------
192 
193 template <>
194 inline bool NETserialize<UT_SGuid>(UT_JSONWriter& writer, const UT_SGuid& id)
195 {
196  writer.jsonValue(id.toString());
197  return true;
198 }
199 
200 template <>
202 {
203  UT_StringHolder str;
204  if (!data.import(str))
205  return false;
206 
207  return id.setString(str);
208 }
209 
210 // -----------------------------------------------------------------------------
211 // Serialize Arrays
212 // -----------------------------------------------------------------------------
213 
214 template <typename T, template <typename> class ARRAY>
215 inline bool NETserializeArray(UT_JSONWriter& writer, const ARRAY<T>& items)
216 {
217  writer.jsonBeginArray();
218  for (auto&& item : items)
219  NETserialize<T>(writer, item);
220  writer.jsonEndArray();
221  return true;
222 }
223 
224 template <typename T, template <typename> class ARRAY>
225 inline bool NETserializeArray(const UT_JSONValue& data, ARRAY<T>& items)
226 {
227  // To support some older clients that were sending empty strings in place
228  // of empty arrays.
229  if (data.getType() == UT_JSONValue::JSON_STRING)
230  {
231  const UT_StringHolder* str = data.getStringHolder();
232  if (str && str->isEmpty())
233  return true;
234  }
235  if (!data.isArray())
236  return false;
237  exint size = data.count();
238  items.setSize(size);
239  for (auto&& [index, value] : data.enumerate())
240  {
241  NETserialize<T>(value, items[index]);
242  }
243  return true;
244 }
245 
246 #define NET_DEFINE_ARRAY_SERIALIZER(_ARRAY_) \
247 template <typename T> \
248 inline bool NETserialize(UT_JSONWriter& writer, const _ARRAY_<typename T::value_type>& items) \
249 { \
250  return NETserializeArray<typename T::value_type, _ARRAY_>(writer, items); \
251 } \
252 template <typename T> \
253 inline bool NETserialize(const UT_JSONValue& data, _ARRAY_<typename T::value_type>& items) \
254 { \
255  return NETserializeArray<typename T::value_type, _ARRAY_>(data, items); \
256 }
259 #undef NET_DEFINE_ARRAY_SERIALIZER
260 
261 template <>
263 {
264  return writer.jsonStringArray(items);
265 }
266 
267 template <>
269 {
270  // To support some older clients that were sending empty strings in place
271  // of empty arrays.
272  if (data.getType() == UT_JSONValue::JSON_STRING)
273  {
274  const UT_StringHolder* str = data.getStringHolder();
275  if (str && str->isEmpty())
276  return true;
277  }
278  return data.import(items);
279 }
280 
281 // -----------------------------------------------------------------------------
282 // Serialize Sets
283 // -----------------------------------------------------------------------------
284 
285 template <typename SetT>
286 inline bool NETserializeSet(UT_JSONWriter& writer, const SetT& items)
287 {
288  using T = typename SetT::value_type;
289  writer.jsonBeginArray();
290  for (auto&& item : items)
291  NETserialize<T>(writer, item);
292  writer.jsonEndArray();
293  return true;
294 }
295 
296 template <typename SetT>
297 inline bool NETserializeSet(const UT_JSONValue& data, SetT& items)
298 {
299  using T = typename SetT::value_type;
300  static_assert(
301  std::is_default_constructible_v<T>,
302  "Serialize of a set requires the type to be default constructibe");
303  // To support some older clients that were sending empty strings in place
304  // of empty arrays.
305  if (data.getType() == UT_JSONValue::JSON_STRING)
306  {
307  UT_StringHolder str = data.getString();
308  if (str.isEmpty())
309  return true;
310  }
311  if (!data.isArray())
312  return false;
313  for (auto&& value : data)
314  {
315  T items_value;
316  NETserialize<T>(value, items_value);
317  items.emplace(items_value);
318  }
319  return true;
320 }
321 
322 #define NET_DEFINE_SET_SERIALIZER(_SET_) \
323 template <typename T> \
324 inline bool NETserialize(UT_JSONWriter& writer, const _SET_<typename T::value_type>& items) \
325 { \
326  return NETserializeSet<T>(writer, items); \
327 } \
328 template <typename T> \
329 inline bool NETserialize(const UT_JSONValue& data, _SET_<typename T::value_type>& items) \
330 { \
331  return NETserializeSet<T>(data, items); \
332 }
334 #undef NET_DEFINE_SET_SERIALIZER
335 
336 template <>
337 inline bool
339 {
340  return writer.jsonSetAsArray(items);
341 }
342 
343 template <>
344 inline bool
346 {
347  // To support some older clients that were sending empty strings in place
348  // of empty arrays.
349  if (data.getType() == UT_JSONValue::JSON_STRING)
350  {
351  const UT_StringHolder* str = data.getStringHolder();
352  if (str && str->isEmpty())
353  return true;
354  }
355 
356  return NETserializeSet<UT_StringSet>(data, items);
357 }
358 
359 // -----------------------------------------------------------------------------
360 // Serialize JSONValue
361 // -----------------------------------------------------------------------------
362 
363 template <>
365 {
366  writer.jsonValue(value);
367  return false;
368 }
369 
370 template <>
372 {
373  item = data;
374  return true;
375 }
376 
377 // -----------------------------------------------------------------------------
378 // Helper for cases where you dont need to serialize something for whatever
379 // reason. Typically this would only ever be used when doing templated calls
380 // where theres little control over how to serialize something.
381 // For example, in some cases the parameter on an api function no longer means
382 // anything then it might make sense to just ignore it.
383 // -----------------------------------------------------------------------------
385 {
386 public:
387 };
388 
390 
391 template <>
392 inline bool
394  UT_JSONWriter& writer,
395  const NET_EmptySerializer&)
396 {
397  return true;
398 }
399 
400 template <>
401 inline bool
403  const UT_JSONValue& data,
405 {
406  return true;
407 }
408 
409 // =============================================================================
410 // Deprecated conversion type.
411 // =============================================================================
412 
413 namespace NET_ConvertToType
414 {
415 // Remove const reference from type
416 template <class T>
418 {
419  typedef std::remove_const_t<std::remove_reference_t<T>> type;
420 };
421 
422 template <class T>
424 
425 // C++ 17 will allow us to support more then just UT_StringHolder and combine
426 // some of this code as well.
427 template <typename Tto, typename Enable = void>
429 {
430 public:
431  static Tto cast(const UT_StringHolder& source)
432  {
433  UT_ASSERT(!"This code should never be entered. You have not setup a proper cast for this type.");
434  return Tto{};
435  }
436 };
437 
438 template <typename Tto>
439 class convertImpl<Tto,
440  std::enable_if_t<std::is_same<UT_StringHolder,
441  NET_remove_cref_t<Tto>>::value>>
442 {
443 public:
444  static Tto cast(const UT_StringHolder &source) { return source; }
445 };
446 
447 template <typename Tto>
448 class convertImpl<Tto,
449  std::enable_if_t<std::is_same<UT_StringArray,
450  NET_remove_cref_t<Tto>>::value>>
451 {
452 public:
453  static Tto cast(const UT_StringHolder &source)
454  {
455  // Try parsing it as a json string array first. If that fails then
456  // try parsing it as a custom array string.
458  if (value.parseValue(source))
459  {
461  if (NETserialize(value, values))
462  return values;
463  }
464 
465  UT_StringView view_source(source.buffer());
466  UT_StringViewArray values = view_source.split(",");
468  result.setCapacity(values.entries());
469  for (auto &&value : values)
470  {
471  result.emplace_back(value);
472  }
473 
474  return result;
475  }
476 };
477 
478 template <typename Tto>
480  Tto,
481  std::enable_if_t<std::is_same<UT_IntArray, NET_remove_cref_t<Tto>>::value>>
482 {
483 public:
484  static Tto cast(const UT_StringHolder &source)
485  {
486  UT_StringView view_source(source.buffer());
487  UT_StringViewArray values = view_source.split(",");
489  result.setCapacity(values.entries());
490  for (auto &&value : values)
491  {
492  UT_String str(value);
493  result.emplace_back(str.toInt());
494  }
495 
496  return result;
497  }
498 };
499 
500 template <typename Tto>
501 class convertImpl<Tto,
502  std::enable_if_t<std::is_integral<Tto>::value &&
503  !std::is_same<Tto, bool>::value>>
504 {
505 public:
506  // Return integer
507  static Tto cast(const UT_StringHolder &source)
508  {
509  UT_ASSERT(source.isInteger());
510  return source.toInt();
511  }
512 };
513 
514 template <typename Tto>
515 class convertImpl<Tto, std::enable_if_t<std::is_floating_point<Tto>::value>>
516 {
517 public:
518  // Return float
519  static Tto cast(const UT_StringHolder &source)
520  {
521  UT_ASSERT(source.isFloat());
522  return source.toFloat();
523  }
524 };
525 
526 template <typename Tto>
527 class convertImpl<Tto, std::enable_if_t<std::is_same<bool, Tto>::value>>
528 {
529 public:
530  // Return bool
531  static Tto cast(const UT_StringHolder &source)
532  {
533  if (source.isInteger())
534  return source.toInt();
535 
536  UT_StringRef low_source = source.toLower();
537  return low_source == "true";
538  }
539 };
540 
541 } // namespace NET_ConvertToType
542 
543 template <typename Tto, typename Tfrom>
544 Tto
545 convert(const Tfrom &source)
546 {
548 }
549 
550 #endif // __NET_ConvertToType_H__
static Tto cast(const UT_StringHolder &source)
typename std::enable_if< B, T >::type enable_if_t
Define Imath::enable_if_t to be std for C++14, equivalent for C++11.
bool NETserialize< UT_String >(UT_JSONWriter &writer, const UT_String &obj)
bool NETserialize< UT_WorkBuffer >(UT_JSONWriter &writer, const UT_WorkBuffer &obj)
Definition: UT_Set.h:58
int int32
Definition: SYS_Types.h:39
bool parseValue(UT_JSONParser &parser, UT_IStream *is=0, bool record_source_offsets=false)
bool NETserializeSet(UT_JSONWriter &writer, const SetT &items)
GLboolean * data
Definition: glcorearb.h:131
GLsizei const GLfloat * value
Definition: glcorearb.h:824
int toInt() const
bool isEmpty() const
Same as !isstring()
bool isFloat(bool skip_spaces=false, bool loose=false) const
Determine if string can be seen as a single floating point number.
typename NET_remove_cref< T >::type NET_remove_cref_t
int64 exint
Definition: SYS_Types.h:125
bool NETserialize< NET_EmptySerializer >(UT_JSONWriter &writer, const NET_EmptySerializer &)
void setCapacity(exint new_capacity)
bool NETserialize< bool >(UT_JSONWriter &writer, const bool &obj)
Tto convert(const Tfrom &source)
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
bool NETserialize< UT_SGuid >(UT_JSONWriter &writer, const UT_SGuid &id)
**But if you need a result
Definition: thread.h:613
uint64 value_type
Definition: GA_PrimCompat.h:29
bool NETserialize< UT_StringArray >(UT_JSONWriter &writer, const UT_StringArray &items)
bool NETserialize< UT_StringLit >(UT_JSONWriter &writer, const UT_StringLit &obj)
fpreal toFloat() const
#define NET_API
Definition: NET_API.h:9
bool isInteger(bool skip_spaces=false) const
Determine if string can be seen as a single integer number.
A utility class to do read-only operations on a subset of an existing string.
Definition: UT_StringView.h:39
exint emplace_back(S &&...s)
Definition: UT_ArrayImpl.h:769
SYS_FORCE_INLINE const char * buffer() const
bool NETserialize< int64 >(UT_JSONWriter &writer, const int64 &obj)
bool NETserialize(UT_JSONWriter &writer, const T &obj)
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
SYS_NO_DISCARD_RESULT indexed_proxy enumerate()
Definition: UT_JSONValue.h:837
long long int64
Definition: SYS_Types.h:116
GLuint id
Definition: glcorearb.h:655
SYS_NO_DISCARD_RESULT bool isArray() const
Definition: UT_JSONValue.h:167
signed char int8
Definition: SYS_Types.h:35
#define NET_DEFINE_SET_SERIALIZER(_SET_)
#define NET_DEFINE_INT_SERIALIZER(_T_)
SYS_NO_DISCARD_RESULT const UT_StringHolder * getStringHolder() const
Return the string value.
GLsizeiptr size
Definition: glcorearb.h:664
bool NETserialize< UT_JSONValue >(UT_JSONWriter &writer, const UT_JSONValue &value)
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
short int16
Definition: SYS_Types.h:37
GLuint index
Definition: glcorearb.h:786
SYS_NO_DISCARD_RESULT exint count() const
Number of elements contained inside the json value.
SYS_NO_DISCARD_RESULT UT_StringRef toLower() const
#define NET_DEFINE_ARRAY_SERIALIZER(_ARRAY_)
bool jsonBeginArray()
Begin a generic array object.
SYS_NO_DISCARD_RESULT Type getType() const
Get the type of data stored in the object.
Definition: UT_JSONValue.h:165
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
unsigned int uint32
Definition: SYS_Types.h:40
bool NETserialize< UT_StringRef >(UT_JSONWriter &writer, const UT_StringRef &obj)
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
Definition: core.h:1131
int toInt() const
SYS_NO_DISCARD_RESULT const UT_StringHolder & getString() const
Definition: UT_JSONValue.h:184
std::remove_const_t< std::remove_reference_t< T > > type
Definition: format.h:895
bool NETserialize< UT_StringHolder >(UT_JSONWriter &writer, const UT_StringHolder &obj)
bool NETserialize< UT_StringSet >(UT_JSONWriter &writer, const UT_StringSet &items)
bool NETserialize< uint32 >(UT_JSONWriter &writer, const uint32 &obj)
bool NETserializeArray(UT_JSONWriter &writer, const ARRAY< T > &items)