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_JSONValueArray.h>
19 #include <UT/UT_JSONValueMap.h>
20 #include <UT/UT_JSONWriter.h>
21 #include <UT/UT_String.h>
22 #include <UT/UT_StringArray.h>
23 #include <UT/UT_StringHolder.h>
24 #include <UT/UT_StringView.h>
25 #include <UT/UT_Variant.h>
26 #include <UT/UT_WorkBuffer.h>
27 
28 #include <type_traits>
29 
30 #define NET_REQUIRE(_cond_) std::enable_if_t<_cond_>
31 
32 // -----------------------------------------------------------------------------
33 // Serialize Object
34 // -----------------------------------------------------------------------------
35 
36 template <typename T>
38 {
39  return obj.serialize(writer);
40 }
41 
42 template <typename T>
44 {
45  return obj.serialize(data);
46 }
47 
48 // -----------------------------------------------------------------------------
49 // Serialize Integers
50 // -----------------------------------------------------------------------------
51 
52 #define NET_DEFINE_INT_SERIALIZER(_T_) \
53  template <> \
54  inline bool NETserialize<_T_>(UT_JSONWriter& writer, const _T_& obj) \
55 { \
56  writer.jsonValue(obj); \
57  return true; \
58 } \
59  template <> \
60  inline bool NETserialize<_T_>(const UT_JSONValue& data, _T_& item) \
61 { \
62  int64 v = 0; \
63  bool res = data.import(v); \
64  item = static_cast<_T_>(v); \
65  return res; \
66 }
70 #undef NET_DEFINE_INT_SERIALIZER
71 
72 template <>
74 {
75  writer.jsonValue(obj);
76  return true;
77 }
78 
79 template <>
81 {
82  return data.import(obj);
83 }
84 
85 template <>
87 {
88  writer.jsonValue(static_cast<int32>(obj));
89  return true;
90 }
91 
92 template <>
94 {
95  int64 tmp = 0;
96  bool res = data.import(tmp);
97  obj = static_cast<uint32>(tmp);
98  return res;
99 }
100 
101 // -----------------------------------------------------------------------------
102 // Serialize Bool
103 // -----------------------------------------------------------------------------
104 
105 template <>
106 inline bool NETserialize<bool>(UT_JSONWriter& writer, const bool& obj)
107 {
108  writer.jsonValue(obj);
109  return true;
110 }
111 
112 template <>
113 inline bool NETserialize<bool>(const UT_JSONValue& data, bool& item)
114 {
115  return data.import(item);
116 }
117 
118 // -----------------------------------------------------------------------------
119 // Serialize String Holder
120 // -----------------------------------------------------------------------------
121 
122 template <>
124 {
125  writer.jsonValue(obj);
126  return true;
127 }
128 
129 template <>
131 {
132  return data.import(obj);
133 }
134 
135 template <>
137 {
138  writer.jsonValue(obj);
139  return true;
140 }
141 template <>
143 {
144  if (data.getType() != UT_JSONValue::JSON_STRING)
145  return false;
146  obj = data.getS();
147  return true;
148 }
149 
150 template <>
152 {
153  writer.jsonValue(obj);
154  return true;
155 }
156 
157 template <>
158 inline bool NETserialize<UT_StringLit>(const UT_JSONValue& data, UT_StringLit&) = delete;
159 
160 // -----------------------------------------------------------------------------
161 // Serialize WorkBuffer
162 // -----------------------------------------------------------------------------
163 
164 template <>
166 {
167  writer.jsonValue(obj);
168  return true;
169 }
170 
171 template <>
173 {
174  return data.import(obj);
175 }
176 
177 // -----------------------------------------------------------------------------
178 // Serialize Arrays
179 // -----------------------------------------------------------------------------
180 
181 template <typename T, template <typename> class ARRAY>
182 inline bool NETserializeArray(UT_JSONWriter& writer, const ARRAY<T>& items)
183 {
184  writer.jsonBeginArray();
185  for (auto&& item : items)
186  NETserialize<T>(writer, item);
187  writer.jsonEndArray();
188  return true;
189 }
190 
191 template <typename T, template <typename> class ARRAY>
192 inline bool NETserializeArray(const UT_JSONValue& data, ARRAY<T>& items)
193 {
194  if (data.getType() != UT_JSONValue::JSON_ARRAY)
195  return false;
197  if (values == nullptr)
198  return false;
199  exint size = values->entries();
200  items.setSize(size);
201  for (exint i = 0; i < size; ++i)
202  {
203  UT_JSONValue* value = values->get(i);
204  if (value == nullptr)
205  continue;
206  NETserialize<T>(*value, items[i]);
207  }
208  return true;
209 }
210 
211 #define NET_DEFINE_ARRAY_SERIALIZER(_ARRAY_) \
212 template <typename T> \
213 inline bool NETserialize(UT_JSONWriter& writer, const _ARRAY_<typename T::value_type>& items) \
214 { \
215  return NETserializeArray<typename T::value_type, _ARRAY_>(writer, items); \
216 } \
217 template <typename T> \
218 inline bool NETserialize(const UT_JSONValue& data, _ARRAY_<typename T::value_type>& items) \
219 { \
220  return NETserializeArray<typename T::value_type, _ARRAY_>(data, items); \
221 }
224 #undef NET_DEFINE_ARRAY_SERIALIZER
225 
226 template <>
228 {
229  return writer.jsonStringArray(items);
230 }
231 
232 template <>
234 {
235  return data.import(items);
236 }
237 
238 // -----------------------------------------------------------------------------
239 // Serialize JSONValue
240 // -----------------------------------------------------------------------------
241 
242 template <>
244 {
245  writer.jsonValue(value);
246  return false;
247 }
248 
249 template <>
251 {
252  item = data;
253  return true;
254 }
255 
256 // -----------------------------------------------------------------------------
257 // Serialize UT_Variant
258 // -----------------------------------------------------------------------------
259 
260 // Forward declare so UT_VariantArray and UT_Variant can use each others serialize
261 // functions
262 template <>
264 template <>
266 template <>
268 template <>
270 
271 template <>
273 {
274  if (v.type() == UT_Variant::Type::Int)
275  writer.jsonValue(v.get<int64>());
276  else if (v.type() == UT_Variant::Type::Float)
277  writer.jsonValue(v.get<float>());
278  else if (v.type() == UT_Variant::Type::String)
279  writer.jsonValue(v.get<UT_StringHolder>());
280  else if (v.type() == UT_Variant::Type::Bool)
281  writer.jsonValue(v.get<bool>());
282  else if (v.type() == UT_Variant::Type::Array)
283  {
285  return NETserialize(writer, values);
286  }
287  else if (v.type() == UT_Variant::Type::Map)
288  {
290  return NETserialize(writer, values);
291  }
292  else
293  {
294  return false;
295  }
296 
297  return true;
298 }
299 
300 template <>
302 {
303  if (data.getType() == UT_JSONValue::JSON_INT)
304  v = data.getI();
305  else if (data.getType() == UT_JSONValue::JSON_REAL)
306  v = data.getF();
307  else if (data.getType() == UT_JSONValue::JSON_BOOL)
308  v = data.getB();
309  else if (data.getType() == UT_JSONValue::JSON_STRING)
310  v = data.getStringHolder();
311  else if (data.getType() == UT_JSONValue::JSON_ARRAY)
312  {
313  UT_VariantArray variants;
314  if (!NETserialize(data, variants))
315  return false;
316 
317  v = variants;
318  }
319  else if (data.getType() == UT_JSONValue::JSON_MAP)
320  {
321  UT_VariantMap variants;
322  if (!NETserialize(data, variants))
323  return false;
324 
325  v = variants;
326  }
327  else
328  {
329  return false;
330  }
331 
332  return true;
333 }
334 
335 // -----------------------------------------------------------------------------
336 // Serialize UT_VariantArray
337 // -----------------------------------------------------------------------------
338 
339 template <>
341 {
342  writer.jsonBeginArray();
343 
344  for (auto&& k : variants)
345  {
346  if (!NETserialize(writer, k))
347  return false;
348  }
349 
350  writer.jsonEndArray();
351 
352  return true;
353 }
354 
355 template <>
357 {
358  UT_JSONValueArray* arr = data.getArray();
359  if (arr == nullptr)
360  return false;
361 
362  for (int i = 0; i < arr->entries(); i++)
363  {
364  UT_JSONValue* json = arr->get(i);
365  if (json == nullptr)
366  return false;
367 
369  if (!NETserialize(*json, value))
370  return false;
371 
372  variants.append(value);
373  }
374 
375  return true;
376 }
377 
378 // -----------------------------------------------------------------------------
379 // Serialize a UT_VariantMap
380 // -----------------------------------------------------------------------------
381 
382 template <>
384 {
385  writer.jsonBeginMap();
386 
387  for (auto&& v : variants)
388  {
389  if (v.second.type() == UT_Variant::Type::Null)
390  continue;
391 
392  writer.jsonKeyToken(v.first);
393  if (!NETserialize(writer, v.second))
394  return false;
395  }
396 
397  writer.jsonEndMap();
398  return true;
399 }
400 
401 template <>
403 {
404  UT_JSONValueMap* json = data.getMap();
405  if (json == nullptr)
406  return false;
407 
408  for (auto&& v : *json)
409  {
410  if (v.second == nullptr)
411  return false;
412 
414  if (!NETserialize(*v.second, value))
415  return false;
416 
417  variants[v.first] = value;
418  }
419 
420  return false;
421 }
422 
423 // =============================================================================
424 // Deprecated conversion type.
425 // =============================================================================
426 
427 namespace NET_ConvertToType
428 {
429 // Remove const reference from type
430 template <class T>
431 struct NET_API NET_remove_cref
432 {
433  typedef std::remove_const_t<std::remove_reference_t<T>> type;
434 };
435 
436 template <class T>
438 
439 // C++ 17 will allow us to support more then just UT_StringHolder and combine
440 // some of this code as well.
441 template <typename Tto, typename Enable = void>
443 {
444 public:
445  static Tto cast(const UT_StringHolder& source)
446  {
447  UT_ASSERT(!"This code should never be entered. You have not setup a proper cast for this type.");
448  return Tto{};
449  }
450 };
451 
452 template <typename Tto>
453 class convertImpl<Tto,
454  std::enable_if_t<std::is_same<UT_StringHolder,
455  NET_remove_cref_t<Tto>>::value>>
456 {
457 public:
458  static Tto cast(const UT_StringHolder &source) { return source; }
459 };
460 
461 template <typename Tto>
462 class convertImpl<Tto,
463  std::enable_if_t<std::is_same<UT_StringArray,
464  NET_remove_cref_t<Tto>>::value>>
465 {
466 public:
467  static Tto cast(const UT_StringHolder &source)
468  {
469  // Try parsing it as a json string array first. If that fails then
470  // try parsing it as a custom array string.
472  if (value.parseValue(source))
473  {
475  if (NETserialize(value, values))
476  return values;
477  }
478 
479  UT_StringView view_source(source.buffer());
480  UT_StringViewArray values = view_source.split(",");
482  result.setCapacity(values.entries());
483  for (auto &&value : values)
484  {
485  result.emplace_back(value);
486  }
487 
488  return result;
489  }
490 };
491 
492 template <typename Tto>
494  Tto,
495  std::enable_if_t<std::is_same<UT_IntArray, NET_remove_cref_t<Tto>>::value>>
496 {
497 public:
498  static Tto cast(const UT_StringHolder &source)
499  {
500  UT_StringView view_source(source.buffer());
501  UT_StringViewArray values = view_source.split(",");
503  result.setCapacity(values.entries());
504  for (auto &&value : values)
505  {
506  UT_String str(value);
507  result.emplace_back(str.toInt());
508  }
509 
510  return result;
511  }
512 };
513 
514 template <typename Tto>
515 class convertImpl<Tto,
516  std::enable_if_t<std::is_integral<Tto>::value &&
517  !std::is_same<Tto, bool>::value>>
518 {
519 public:
520  // Return integer
521  static Tto cast(const UT_StringHolder &source)
522  {
523  UT_ASSERT(source.isInteger());
524  return source.toInt();
525  }
526 };
527 
528 template <typename Tto>
529 class convertImpl<Tto, std::enable_if_t<std::is_floating_point<Tto>::value>>
530 {
531 public:
532  // Return float
533  static Tto cast(const UT_StringHolder &source)
534  {
535  UT_ASSERT(source.isFloat());
536  return source.toFloat();
537  }
538 };
539 
540 template <typename Tto>
541 class convertImpl<Tto, std::enable_if_t<std::is_same<bool, Tto>::value>>
542 {
543 public:
544  // Return bool
545  static Tto cast(const UT_StringHolder &source)
546  {
547  if (source.isInteger())
548  return source.toInt();
549 
550  UT_StringRef low_source = source.toLower();
551  return low_source == "true";
552  }
553 };
554 
555 } // namespace NET_ConvertToType
556 
557 template <typename Tto, typename Tfrom>
558 Tto
559 convert(const Tfrom &source)
560 {
562 }
563 
564 #endif // __NET_ConvertToType_H__
static Tto cast(const UT_StringHolder &source)
bool NETserialize< UT_String >(UT_JSONWriter &writer, const UT_String &obj)
bool NETserialize< UT_WorkBuffer >(UT_JSONWriter &writer, const UT_WorkBuffer &obj)
GLsizeiptr size
Definition: glew.h:1681
UT_JSONValueMap stores a map/dictionary of UT_JSONValue objects.
int int32
Definition: SYS_Types.h:39
SYS_NO_DISCARD_RESULT UT_JSONValueArray * getArray() const
Get the array value (may return a NULL pointer)
bool parseValue(UT_JSONParser &parser, UT_IStream *is=0, bool record_source_offsets=false)
int toInt() const
UT_JSONValueArray stores a list of UT_JSONValue objects.
GLint GLsizei const GLuint64 * values
Definition: glew.h:3612
typename NET_remove_cref< T >::type NET_remove_cref_t
int64 exint
Definition: SYS_Types.h:125
GLsizei GLsizei GLchar * source
Definition: glew.h:1832
bool NETserialize< UT_VariantMap >(UT_JSONWriter &writer, const UT_VariantMap &value)
bool NETserialize< bool >(UT_JSONWriter &writer, const bool &obj)
basic_writer< back_insert_range< internal::buffer > > writer
Definition: format.h:361
Tto convert(const Tfrom &source)
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:34
const GLdouble * v
Definition: glew.h:1391
GLhandleARB obj
Definition: glew.h:6236
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
A 64-bit float value.
A utility class to do read-only operations on a subset of an existing string.
Definition: UT_StringView.h:40
A 64-bit signed integer.
void setCapacity(exint newcapacity)
Definition: UT_ArrayImpl.h:777
bool NETserialize< UT_Variant >(UT_JSONWriter &writer, const UT_Variant &v)
exint emplace_back(S &&...s)
Definition: UT_ArrayImpl.h:172
SYS_FORCE_INLINE const char * buffer() const
A shared string.
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
bool NETserialize< int64 >(UT_JSONWriter &writer, const int64 &obj)
bool NETserialize(UT_JSONWriter &writer, const T &obj)
long long int64
Definition: SYS_Types.h:116
signed char int8
Definition: SYS_Types.h:35
#define NET_DEFINE_INT_SERIALIZER(_T_)
A null variant. A null variant holds no value.
SYS_FORCE_INLINE int64 entries() const
Return the number of entries in the array.
bool NETserialize< UT_JSONValue >(UT_JSONWriter &writer, const UT_JSONValue &value)
short int16
Definition: SYS_Types.h:37
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:134
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:77
unsigned int uint32
Definition: SYS_Types.h:40
GLuint64EXT * result
Definition: glew.h:14007
unsigned isInteger(int skip_spaces=0) const
Determine if string can be seen as a single integer number.
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:135
int toInt() const
A UT_VariantMap value.
GLsizei const GLfloat * value
Definition: glew.h:1849
unsigned isFloat(int skip_spaces=0, int loose=0) const
Determine if string can be seen as a single floating point number.
std::remove_const_t< std::remove_reference_t< T > > type
SYS_FORCE_INLINE const UT_JSONValue * get(int64 i) const
Access a const entry by index.
A UT_VariantArray value.
bool NETserialize< UT_StringHolder >(UT_JSONWriter &writer, const UT_StringHolder &obj)
GLuint res
Definition: glew.h:11507
bool NETserialize< UT_VariantArray >(UT_JSONWriter &writer, const UT_VariantArray &value)
bool NETserialize< uint32 >(UT_JSONWriter &writer, const uint32 &obj)
bool NETserializeArray(UT_JSONWriter &writer, const ARRAY< T > &items)