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 #include <UT/UT_Options.h>
27 #include <UT/UT_Url.h>
28 
29 #include <type_traits>
30 
31 #define NET_REQUIRE(_cond_) std::enable_if_t<_cond_>
32 
33 // -----------------------------------------------------------------------------
34 // Serialize Object
35 // -----------------------------------------------------------------------------
36 
37 template <typename T>
38 bool NETserialize(UT_JSONWriter& writer, const T& obj)
39 {
40  return obj.serialize(writer);
41 }
42 
43 template <typename T>
44 bool NETserialize(const UT_JSONValue& data, T& obj)
45 {
46  return obj.serialize(data);
47 }
48 
49 // -----------------------------------------------------------------------------
50 // Serialize Integers
51 // -----------------------------------------------------------------------------
52 
53 #define NET_DEFINE_INT_SERIALIZER(_T_) \
54  template <> \
55  inline bool NETserialize<_T_>(UT_JSONWriter& writer, const _T_& obj) \
56 { \
57  writer.jsonValue(obj); \
58  return true; \
59 } \
60  template <> \
61  inline bool NETserialize<_T_>(const UT_JSONValue& data, _T_& item) \
62 { \
63  int64 v = 0; \
64  bool res = data.import(v); \
65  item = static_cast<_T_>(v); \
66  return res; \
67 }
71 #undef NET_DEFINE_INT_SERIALIZER
72 
73 template <>
74 inline bool NETserialize<int64>(UT_JSONWriter& writer, const int64& obj)
75 {
76  writer.jsonValue(obj);
77  return true;
78 }
79 
80 template <>
81 inline bool NETserialize<int64>(const UT_JSONValue& data, int64& obj)
82 {
83  return data.import(obj);
84 }
85 
86 template <>
87 inline bool NETserialize<uint32>(UT_JSONWriter& writer, const uint32& obj)
88 {
89  writer.jsonValue(static_cast<int32>(obj));
90  return true;
91 }
92 
93 template <>
94 inline bool NETserialize<uint32>(const UT_JSONValue& data, uint32& obj)
95 {
96  int64 tmp = 0;
97  bool res = data.import(tmp);
98  obj = static_cast<uint32>(tmp);
99  return res;
100 }
101 
102 // -----------------------------------------------------------------------------
103 // Serialize Bool
104 // -----------------------------------------------------------------------------
105 
106 template <>
107 inline bool NETserialize<bool>(UT_JSONWriter& writer, const bool& obj)
108 {
109  writer.jsonValue(obj);
110  return true;
111 }
112 
113 template <>
114 inline bool NETserialize<bool>(const UT_JSONValue& data, bool& item)
115 {
116  return data.import(item);
117 }
118 
119 // -----------------------------------------------------------------------------
120 // Serialize String Holder
121 // -----------------------------------------------------------------------------
122 
123 template <>
125 {
126  writer.jsonValue(obj);
127  return true;
128 }
129 
130 template <>
132 {
133  return data.import(obj);
134 }
135 
136 template <>
137 inline bool NETserialize<UT_StringRef>(UT_JSONWriter& writer, const UT_StringRef& obj)
138 {
139  writer.jsonValue(obj);
140  return true;
141 }
142 
143 template <>
145 {
146  return false;
147 }
148 
149 template <>
150 inline bool NETserialize<UT_String>(UT_JSONWriter& writer, const UT_String& obj)
151 {
152  writer.jsonValue(obj);
153  return true;
154 }
155 template <>
157 {
158  if (data.getType() != UT_JSONValue::JSON_STRING)
159  return false;
160  obj = data.getS();
161  return true;
162 }
163 
164 template <>
165 inline bool NETserialize<UT_StringLit>(UT_JSONWriter& writer, const UT_StringLit& obj)
166 {
167  writer.jsonValue(obj.asRef());
168  return true;
169 }
170 
171 template <>
172 inline bool NETserialize<UT_StringLit>(const UT_JSONValue& data, UT_StringLit&) = delete;
173 
174 // -----------------------------------------------------------------------------
175 // Serialize WorkBuffer
176 // -----------------------------------------------------------------------------
177 
178 template <>
180 {
181  writer.jsonValue(obj);
182  return true;
183 }
184 
185 template <>
187 {
188  return data.import(obj);
189 }
190 
191 // -----------------------------------------------------------------------------
192 // Serialize UT_SGuid
193 // -----------------------------------------------------------------------------
194 
195 template <>
196 inline bool NETserialize<UT_SGuid>(UT_JSONWriter& writer, const UT_SGuid& id)
197 {
198  writer.jsonValue(id.toString());
199  return true;
200 }
201 
202 template <>
204 {
205  UT_StringHolder str;
206  if (!data.import(str))
207  return false;
208 
209  return id.setString(str);
210 }
211 
212 // -----------------------------------------------------------------------------
213 // Serialize Arrays
214 // -----------------------------------------------------------------------------
215 
216 template <typename T, template <typename> class ARRAY>
217 inline bool NETserializeArray(UT_JSONWriter& writer, const ARRAY<T>& items)
218 {
219  writer.jsonBeginArray();
220  for (auto&& item : items)
221  NETserialize<T>(writer, item);
222  writer.jsonEndArray();
223  return true;
224 }
225 
226 template <typename T, template <typename> class ARRAY>
227 inline bool NETserializeArray(const UT_JSONValue& data, ARRAY<T>& items)
228 {
229  // To support some older clients that were sending empty strings in place
230  // of empty arrays.
231  if (data.getType() == UT_JSONValue::JSON_STRING)
232  {
233  const UT_StringHolder* str = data.getStringHolder();
234  if (str && str->isEmpty())
235  return true;
236  }
237  if (!data.isArray())
238  return false;
239  exint size = data.count();
240  items.setSize(size);
241  for (auto&& [index, value] : data.enumerate())
242  {
243  NETserialize<T>(value, items[index]);
244  }
245  return true;
246 }
247 
248 #define NET_DEFINE_ARRAY_SERIALIZER(_ARRAY_) \
249 template <typename T> \
250 inline bool NETserialize(UT_JSONWriter& writer, const _ARRAY_<typename T::value_type>& items) \
251 { \
252  return NETserializeArray<typename T::value_type, _ARRAY_>(writer, items); \
253 } \
254 template <typename T> \
255 inline bool NETserialize(const UT_JSONValue& data, _ARRAY_<typename T::value_type>& items) \
256 { \
257  return NETserializeArray<typename T::value_type, _ARRAY_>(data, items); \
258 }
261 #undef NET_DEFINE_ARRAY_SERIALIZER
262 
263 template <>
265 {
266  return writer.jsonStringArray(items);
267 }
268 
269 template <>
271 {
272  // To support some older clients that were sending empty strings in place
273  // of empty arrays.
274  if (data.getType() == UT_JSONValue::JSON_STRING)
275  {
276  const UT_StringHolder* str = data.getStringHolder();
277  if (str && str->isEmpty())
278  return true;
279  }
280  return data.import(items);
281 }
282 
283 // -----------------------------------------------------------------------------
284 // Serialize Sets
285 // -----------------------------------------------------------------------------
286 
287 template <typename SetT>
288 inline bool NETserializeSet(UT_JSONWriter& writer, const SetT& items)
289 {
290  using T = typename SetT::value_type;
291  writer.jsonBeginArray();
292  for (auto&& item : items)
293  NETserialize<T>(writer, item);
294  writer.jsonEndArray();
295  return true;
296 }
297 
298 template <typename SetT>
299 inline bool NETserializeSet(const UT_JSONValue& data, SetT& items)
300 {
301  using T = typename SetT::value_type;
302  static_assert(
303  std::is_default_constructible_v<T>,
304  "Serialize of a set requires the type to be default constructibe");
305  // To support some older clients that were sending empty strings in place
306  // of empty arrays.
307  if (data.getType() == UT_JSONValue::JSON_STRING)
308  {
309  UT_StringHolder str = data.getString();
310  if (str.isEmpty())
311  return true;
312  }
313  if (!data.isArray())
314  return false;
315  for (auto&& value : data)
316  {
317  T items_value;
318  NETserialize<T>(value, items_value);
319  items.emplace(items_value);
320  }
321  return true;
322 }
323 
324 #define NET_DEFINE_SET_SERIALIZER(_SET_) \
325 template <typename T> \
326 inline bool NETserialize(UT_JSONWriter& writer, const _SET_<typename T::value_type>& items) \
327 { \
328  return NETserializeSet<T>(writer, items); \
329 } \
330 template <typename T> \
331 inline bool NETserialize(const UT_JSONValue& data, _SET_<typename T::value_type>& items) \
332 { \
333  return NETserializeSet<T>(data, items); \
334 }
336 #undef NET_DEFINE_SET_SERIALIZER
337 
338 template <>
339 inline bool
341 {
342  return writer.jsonSetAsArray(items);
343 }
344 
345 template <>
346 inline bool
348 {
349  // To support some older clients that were sending empty strings in place
350  // of empty arrays.
351  if (data.getType() == UT_JSONValue::JSON_STRING)
352  {
353  const UT_StringHolder* str = data.getStringHolder();
354  if (str && str->isEmpty())
355  return true;
356  }
357 
358  return NETserializeSet<UT_StringSet>(data, items);
359 }
360 
361 // -----------------------------------------------------------------------------
362 // Serialize JSONValue
363 // -----------------------------------------------------------------------------
364 
365 template <>
367 {
368  writer.jsonValue(value);
369  return false;
370 }
371 
372 template <>
374 {
375  item = data;
376  return true;
377 }
378 
379 // -----------------------------------------------------------------------------
380 // Serialize UT_Options
381 // -----------------------------------------------------------------------------
382 
383 template <>
384 inline bool
386  UT_JSONWriter& writer,
387  const UT_OptionsHolder& opts)
388 {
389  return opts.options()->save(writer);
390 }
391 
392 template <>
393 inline bool
395 {
396  if (!value.isMap())
397  return false;
398  const UT_JSONValueMap* m = value.getMap();
399  UT_Options* o = opts.makeUnique();
400  return o->load(*m, false);
401 }
402 
403 // -----------------------------------------------------------------------------
404 // Serialize std::pair<>
405 // -----------------------------------------------------------------------------
406 template <typename T1, typename T2>
407 inline bool
409  UT_JSONWriter &writer,
410  const std::pair<T1, T2> &obj)
411 {
412  writer.jsonBeginArray();
413  NETserialize<T1>(writer, obj.first);
414  NETserialize<T2>(writer, obj.second);
415  writer.jsonEndArray();
416  return true;
417 }
418 
419 template <typename T1, typename T2>
420 inline bool
422  const UT_JSONValue &data,
423  std::pair<T1, T2> &obj)
424 {
425  if (data.isArray() && data.count() == 2)
426  {
427  return NETserialize<T1>(data[0], obj.first)
428  && NETserialize<T2>(data[1], obj.second);
429  }
430  return false;
431 }
432 
433 template <typename T>
434 inline bool
436  UT_JSONWriter& writer,
437  const std::pair<typename T::first_type, typename T::second_type>& p)
438 {
439  return NETserializePair(writer, p);
440 }
441 template <typename T>
442 inline bool
444  const UT_JSONValue& data,
445  std::pair<typename T::first_type, typename T::second_type>& p)
446 {
447  return NETserializePair(data, p);
448 }
449 
450 // -----------------------------------------------------------------------------
451 // UT_Url
452 // -----------------------------------------------------------------------------
453 
454 template <>
455 inline bool
457 {
458  return writer.jsonValue(url.toString());
459 }
460 
461 template <>
462 inline bool
464 {
465  if (data.getType() == UT_JSONValue::JSON_STRING)
466  {
467  url.parse(data.getString());
468  return true;
469  }
470  return false;
471 }
472 
473 // -----------------------------------------------------------------------------
474 // Helper for cases where you dont need to serialize something for whatever
475 // reason. Typically this would only ever be used when doing templated calls
476 // where theres little control over how to serialize something.
477 // For example, in some cases the parameter on an api function no longer means
478 // anything then it might make sense to just ignore it.
479 // -----------------------------------------------------------------------------
481 {
482 public:
483 };
484 
486 
487 template <>
488 inline bool
490  UT_JSONWriter& writer,
491  const NET_EmptySerializer&)
492 {
493  return true;
494 }
495 
496 template <>
497 inline bool
499  const UT_JSONValue& data,
501 {
502  return true;
503 }
504 
505 // =============================================================================
506 // Deprecated conversion type.
507 // =============================================================================
508 
509 namespace NET_ConvertToType
510 {
511 // Remove const reference from type
512 template <class T>
514 {
515  typedef std::remove_const_t<std::remove_reference_t<T>> type;
516 };
517 
518 template <class T>
520 
521 // C++ 17 will allow us to support more then just UT_StringHolder and combine
522 // some of this code as well.
523 template <typename Tto, typename Enable = void>
525 {
526 public:
527  static Tto cast(const UT_StringHolder& source)
528  {
529  UT_ASSERT(!"This code should never be entered. You have not setup a proper cast for this type.");
530  return Tto{};
531  }
532 };
533 
534 template <typename Tto>
535 class convertImpl<Tto,
536  std::enable_if_t<std::is_same<UT_StringHolder,
537  NET_remove_cref_t<Tto>>::value>>
538 {
539 public:
540  static Tto cast(const UT_StringHolder &source) { return source; }
541 };
542 
543 template <typename Tto>
544 class convertImpl<Tto,
545  std::enable_if_t<std::is_same<UT_StringArray,
546  NET_remove_cref_t<Tto>>::value>>
547 {
548 public:
549  static Tto cast(const UT_StringHolder &source)
550  {
551  // Try parsing it as a json string array first. If that fails then
552  // try parsing it as a custom array string.
554  if (value.parseValue(source))
555  {
557  if (NETserialize(value, values))
558  return values;
559  }
560 
561  UT_StringView view_source(source.buffer());
562  UT_StringViewArray values = view_source.split(",");
564  result.setCapacity(values.entries());
565  for (auto &&value : values)
566  {
567  result.emplace_back(value);
568  }
569 
570  return result;
571  }
572 };
573 
574 template <typename Tto>
576  Tto,
577  std::enable_if_t<std::is_same<UT_IntArray, NET_remove_cref_t<Tto>>::value>>
578 {
579 public:
580  static Tto cast(const UT_StringHolder &source)
581  {
582  UT_StringView view_source(source.buffer());
583  UT_StringViewArray values = view_source.split(",");
585  result.setCapacity(values.entries());
586  for (auto &&value : values)
587  {
588  UT_String str(value);
589  result.emplace_back(str.toInt());
590  }
591 
592  return result;
593  }
594 };
595 
596 template <typename Tto>
597 class convertImpl<Tto,
598  std::enable_if_t<std::is_integral<Tto>::value &&
599  !std::is_same<Tto, bool>::value>>
600 {
601 public:
602  // Return integer
603  static Tto cast(const UT_StringHolder &source)
604  {
605  UT_ASSERT(source.isInteger());
606  return source.toInt();
607  }
608 };
609 
610 template <typename Tto>
611 class convertImpl<Tto, std::enable_if_t<std::is_floating_point<Tto>::value>>
612 {
613 public:
614  // Return float
615  static Tto cast(const UT_StringHolder &source)
616  {
617  UT_ASSERT(source.isFloat());
618  return source.toFloat();
619  }
620 };
621 
622 template <typename Tto>
623 class convertImpl<Tto, std::enable_if_t<std::is_same<bool, Tto>::value>>
624 {
625 public:
626  // Return bool
627  static Tto cast(const UT_StringHolder &source)
628  {
629  if (source.isInteger())
630  return source.toInt();
631 
632  UT_StringRef low_source = source.toLower();
633  return low_source == "true";
634  }
635 };
636 
637 } // namespace NET_ConvertToType
638 
639 template <typename Tto, typename Tfrom>
640 Tto
641 convert(const Tfrom &source)
642 {
644 }
645 
646 #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
UT_JSONValueMap stores a map/dictionary of UT_JSONValue objects.
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:39
bool NETserialize< UT_SGuid >(UT_JSONWriter &writer, const UT_SGuid &id)
**But if you need a result
Definition: thread.h:622
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:40
bool NETserializePair(UT_JSONWriter &writer, const std::pair< T1, T2 > &obj)
exint emplace_back(S &&...s)
Definition: UT_ArrayImpl.h:781
bool load(const char *filename)
bool NETserialize< UT_Url >(UT_JSONWriter &writer, const UT_Url &url)
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
Definition: UT_Url.h:26
SYS_NO_DISCARD_RESULT indexed_proxy enumerate()
Definition: UT_JSONValue.h:849
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:188
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
A map of string to various well defined value types.
Definition: UT_Options.h:87
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
bool NETserialize< UT_OptionsHolder >(UT_JSONWriter &writer, const UT_OptionsHolder &opts)
#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:186
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:165
int toInt() const
SYS_NO_DISCARD_RESULT const UT_StringHolder & getString() const
Definition: UT_JSONValue.h:205
std::remove_const_t< std::remove_reference_t< T > > type
Definition: format.h:1821
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)