Zserio C++17 runtime library  0.5.0
Built for Zserio 2.17.0
DebugStringUtil.h
Go to the documentation of this file.
1 
13 #ifndef ZSERIO_DEBUG_STRING_UTIL_H_INC
14 #define ZSERIO_DEBUG_STRING_UTIL_H_INC
15 
16 #include <fstream>
17 #include <sstream>
18 #include <utility>
19 
20 #include "zserio/JsonReader.h"
21 #include "zserio/JsonWriter.h"
22 #include "zserio/ReflectableUtil.h"
23 #include "zserio/Traits.h"
24 #include "zserio/Walker.h"
25 
26 namespace zserio
27 {
28 
29 namespace detail
30 {
31 
32 // Implementations needs to be in detail because old MSVC compiler 2015 has problems with calling overload.
33 
34 template <typename T, typename WALK_FILTER, typename ALLOC>
35 void toJsonStream(
36  const T& object, std::ostream& stream, uint8_t indent, WALK_FILTER&& walkFilter, const ALLOC& allocator)
37 {
38  // static_assert(has_reflectable<T>::value,
39  // "DebugStringUtil.toJsonStream: "
40  // "Zserio object must have reflections enabled (see zserio option -withReflectionCode)!");
41 
42  BasicJsonWriter<ALLOC> jsonWriter(stream, indent);
43  BasicWalker<ALLOC> walker(jsonWriter, walkFilter);
44  walker.walk(reflectable(object, allocator));
45 }
46 
47 template <typename T, typename WALK_FILTER, typename ALLOC>
48 BasicString<RebindAlloc<ALLOC, char>> toJsonString(
49  const T& object, uint8_t indent, WALK_FILTER&& walkFilter, const ALLOC& allocator)
50 {
51  auto stream = std::basic_ostringstream<char, std::char_traits<char>, RebindAlloc<ALLOC, char>>(
52  BasicString<RebindAlloc<ALLOC, char>>(allocator));
53  detail::toJsonStream(object, stream, indent, walkFilter, allocator);
54  return stream.str();
55 }
56 
57 template <typename T, typename WALK_FILTER, typename ALLOC>
58 void toJsonFile(const T& object, std::string_view fileName, uint8_t indent, WALK_FILTER&& walkFilter,
59  const ALLOC& allocator)
60 {
61  std::ofstream stream = std::ofstream(fileName.data(), std::ios::out | std::ios::trunc);
62  if (!stream)
63  {
64  throw CppRuntimeException("DebugStringUtil.toJsonFile: Failed to open '") << fileName << "'!";
65  }
66 
67  detail::toJsonStream(object, stream, indent, walkFilter, allocator);
68 
69  if (!stream)
70  {
71  throw CppRuntimeException("DebugStringUtil.toJsonFile: Failed to write '") << fileName << "'!";
72  }
73 }
74 
75 // needed due to GCC compilation problems, GCC tries to instantiate return type even though the
76 // particular function template has different number of arguments, this prevents the return type instantiation
77 // in case that the ALLOC is not an allocator
78 template <typename ALLOC, typename std::enable_if<is_allocator<ALLOC>::value, int>::type = 0>
79 struct DebugStringTraits
80 {
81  using ReflectableDataPtr = IBasicReflectableDataPtr<ALLOC>;
82 };
83 
84 } // namespace detail
85 
103 template <typename T, typename ALLOC = typename T::allocator_type,
104  typename std::enable_if<is_allocator<ALLOC>::value, int>::type = 0>
105 void toJsonStream(const T& object, std::ostream& stream, const ALLOC& allocator = ALLOC())
106 {
107  detail::toJsonStream(object, stream, 4, BasicDefaultWalkFilter<ALLOC>(), allocator);
108 }
109 
131 template <typename T, typename ALLOC = typename T::allocator_type,
132  typename std::enable_if<is_allocator<ALLOC>::value, int>::type = 0>
133 void toJsonStream(const T& object, std::ostream& stream, uint8_t indent, const ALLOC& allocator = ALLOC())
134 {
135  detail::toJsonStream(object, stream, indent, BasicDefaultWalkFilter<ALLOC>(), allocator);
136 }
137 
160 template <typename T, typename WALK_FILTER, typename ALLOC = typename T::allocator_type,
161  typename std::enable_if<
162  std::is_base_of<IBasicWalkFilter<ALLOC>, typename std::decay<WALK_FILTER>::type>::value,
163  int>::type = 0>
165  const T& object, std::ostream& stream, WALK_FILTER&& walkFilter, const ALLOC& allocator = ALLOC())
166 {
167  detail::toJsonStream(object, stream, 4, walkFilter, allocator);
168 }
169 
194 template <typename T, typename WALK_FILTER, typename ALLOC = typename T::allocator_type,
195  typename std::enable_if<
196  std::is_base_of<IBasicWalkFilter<ALLOC>, typename std::decay<WALK_FILTER>::type>::value,
197  int>::type = 0>
198 void toJsonStream(const T& object, std::ostream& stream, uint8_t indent, WALK_FILTER&& walkFilter,
199  const ALLOC& allocator = ALLOC())
200 {
201  detail::toJsonStream(object, stream, indent, walkFilter, allocator);
202 }
203 
221 template <typename T, typename ALLOC = typename T::allocator_type,
222  typename std::enable_if<is_allocator<ALLOC>::value, int>::type = 0>
223 BasicString<RebindAlloc<ALLOC, char>> toJsonString(const T& object, const ALLOC& allocator = ALLOC())
224 {
225  return detail::toJsonString(object, 4, BasicDefaultWalkFilter<ALLOC>(), allocator);
226 }
227 
249 template <typename T, typename ALLOC = typename T::allocator_type,
250  typename std::enable_if<is_allocator<ALLOC>::value, int>::type = 0>
252  const T& object, uint8_t indent, const ALLOC& allocator = ALLOC())
253 {
254  return detail::toJsonString(object, indent, BasicDefaultWalkFilter<ALLOC>(), allocator);
255 }
256 
278 template <typename T, typename WALK_FILTER, typename ALLOC = typename T::allocator_type,
279  typename std::enable_if<
280  std::is_base_of<IBasicWalkFilter<ALLOC>, typename std::decay<WALK_FILTER>::type>::value,
281  int>::type = 0>
283  const T& object, WALK_FILTER&& walkFilter, const ALLOC& allocator = ALLOC())
284 {
285  return detail::toJsonString(object, 4, walkFilter, allocator);
286 }
287 
311 template <typename T, typename WALK_FILTER, typename ALLOC = typename T::allocator_type,
312  typename std::enable_if<
313  std::is_base_of<IBasicWalkFilter<ALLOC>, typename std::decay<WALK_FILTER>::type>::value,
314  int>::type = 0>
316  const T& object, uint8_t indent, WALK_FILTER&& walkFilter, const ALLOC& allocator = ALLOC())
317 {
318  return detail::toJsonString(object, indent, walkFilter, allocator);
319 }
320 
336 template <typename T, typename ALLOC = typename T::allocator_type,
337  typename std::enable_if<is_allocator<ALLOC>::value, int>::type = 0>
338 void toJsonFile(const T& object, std::string_view fileName, const ALLOC& allocator = ALLOC())
339 {
340  return detail::toJsonFile(object, fileName, 4, BasicDefaultWalkFilter<ALLOC>(), allocator);
341 }
342 
364 template <typename T, typename ALLOC = typename T::allocator_type,
365  typename std::enable_if<is_allocator<ALLOC>::value, int>::type = 0>
366 void toJsonFile(const T& object, std::string_view fileName, uint8_t indent, const ALLOC& allocator = ALLOC())
367 {
368  return detail::toJsonFile(object, fileName, indent, BasicDefaultWalkFilter<ALLOC>(), allocator);
369 }
370 
392 template <typename T, typename WALK_FILTER, typename ALLOC = typename T::allocator_type,
393  typename std::enable_if<
394  std::is_base_of<IBasicWalkFilter<ALLOC>, typename std::decay<WALK_FILTER>::type>::value,
395  int>::type = 0>
397  const T& object, std::string_view fileName, WALK_FILTER&& walkFilter, const ALLOC& allocator = ALLOC())
398 {
399  return detail::toJsonFile(object, fileName, 4, walkFilter, allocator);
400 }
401 
423 template <typename T, typename WALK_FILTER, typename ALLOC = typename T::allocator_type,
424  typename std::enable_if<
425  std::is_base_of<IBasicWalkFilter<ALLOC>, typename std::decay<WALK_FILTER>::type>::value,
426  int>::type = 0>
427 void toJsonFile(const T& object, const BasicString<RebindAlloc<ALLOC, char>>& fileName, uint8_t indent,
428  WALK_FILTER&& walkFilter, const ALLOC& allocator = ALLOC())
429 {
430  return detail::toJsonFile(object, fileName, indent, walkFilter, allocator);
431 }
432 
457 template <typename ALLOC = std::allocator<uint8_t>>
458 typename detail::DebugStringTraits<ALLOC>::ReflectableDataPtr fromJsonStream(
459  const IBasicTypeInfo<ALLOC>& typeInfo, std::istream& is, const ALLOC& allocator = ALLOC())
460 {
461  BasicJsonReader<ALLOC> jsonReader(is, allocator);
462  return jsonReader.read(typeInfo);
463 }
464 
489 template <typename T, typename ALLOC = typename T::allocator_type>
490 T fromJsonStream(std::istream& is, const ALLOC& allocator = ALLOC())
491 {
492  return std::move(ReflectableUtil::getValue<T, ALLOC>(fromJsonStream(typeInfo<T>(), is, allocator)));
493 }
494 
519 template <typename ALLOC = std::allocator<uint8_t>>
520 typename detail::DebugStringTraits<ALLOC>::ReflectableDataPtr fromJsonString(
522  const ALLOC& allocator = ALLOC())
523 {
524  std::basic_istringstream<char, std::char_traits<char>, RebindAlloc<ALLOC, char>> stream(json);
525  return fromJsonStream(typeInfo, stream, allocator);
526 }
527 
552 template <typename T, typename ALLOC = typename T::allocator_type>
553 T fromJsonString(const BasicString<RebindAlloc<ALLOC, char>>& json, const ALLOC& allocator = ALLOC())
554 {
555  return std::move(ReflectableUtil::getValue<T, ALLOC>(fromJsonString(typeInfo<T>(), json, allocator)));
556 }
557 
581 template <typename ALLOC = std::allocator<uint8_t>>
582 typename detail::DebugStringTraits<ALLOC>::ReflectableDataPtr fromJsonFile(
583  const IBasicTypeInfo<ALLOC>& typeInfo, std::string_view fileName, const ALLOC& allocator = ALLOC())
584 {
585  std::ifstream is = std::ifstream(fileName.data());
586  if (!is)
587  {
588  throw CppRuntimeException("DebugStringUtil.fromJsonFile: Failed to open '") << fileName << "'!";
589  }
590 
591  return fromJsonStream(typeInfo, is, allocator);
592 }
593 
617 template <typename T, typename ALLOC = typename T::allocator_type>
618 T fromJsonFile(std::string_view fileName, const ALLOC& allocator = ALLOC())
619 {
620  return std::move(ReflectableUtil::getValue<T, ALLOC>(fromJsonFile(typeInfo<T>(), fileName, allocator)));
621 }
622 
623 } // namespace zserio
624 
625 #endif // ZSERIO_DEBUG_STRING_UTIL_H_INC
IBasicReflectableDataPtr< ALLOC > read(const IBasicTypeInfo< ALLOC > &typeInfo)
Definition: JsonReader.h:217
detail::DebugStringTraits< ALLOC >::ReflectableDataPtr fromJsonStream(const IBasicTypeInfo< ALLOC > &typeInfo, std::istream &is, const ALLOC &allocator=ALLOC())
std::basic_string< char, std::char_traits< char >, ALLOC > BasicString
Definition: String.h:17
BasicString< RebindAlloc< ALLOC, char > > toJsonString(const T &object, uint8_t indent, WALK_FILTER &&walkFilter, const ALLOC &allocator=ALLOC())
BasicString< RebindAlloc< ALLOC, char > > toJsonString(const T &object, const ALLOC &allocator=ALLOC())
IBasicReflectableDataConstPtr< ALLOC > reflectable(const T &value, const ALLOC &allocator=ALLOC())
void toJsonStream(const T &object, std::ostream &stream, uint8_t indent, WALK_FILTER &&walkFilter, const ALLOC &allocator=ALLOC())
typename std::allocator_traits< ALLOC >::template rebind_alloc< T > RebindAlloc
Definition: RebindAlloc.h:10
const IBasicTypeInfo< ALLOC > & typeInfo()
Definition: ITypeInfo.h:668
void toJsonFile(const T &object, const BasicString< RebindAlloc< ALLOC, char >> &fileName, uint8_t indent, WALK_FILTER &&walkFilter, const ALLOC &allocator=ALLOC())
void toJsonStream(const T &object, std::ostream &stream, const ALLOC &allocator=ALLOC())
void toJsonFile(const T &object, std::string_view fileName, const ALLOC &allocator=ALLOC())
detail::DebugStringTraits< ALLOC >::ReflectableDataPtr fromJsonString(const IBasicTypeInfo< ALLOC > &typeInfo, const BasicString< RebindAlloc< ALLOC, char >> &json, const ALLOC &allocator=ALLOC())
detail::DebugStringTraits< ALLOC >::ReflectableDataPtr fromJsonFile(const IBasicTypeInfo< ALLOC > &typeInfo, std::string_view fileName, const ALLOC &allocator=ALLOC())