1 #ifndef ZSERIO_JSON_WRITER_H_INC
2 #define ZSERIO_JSON_WRITER_H_INC
16 using namespace std::literals::string_view_literals;
21 template <
typename ALLOC = std::allocator<u
int8_t>>
30 static constexpr
const char* DEFAULT_ITEM_SEPARATOR =
", ";
35 static constexpr
const char* DEFAULT_ITEM_SEPARATOR_WITH_INDENT =
",";
40 static constexpr
const char* DEFAULT_KEY_SEPARATOR =
": ";
70 static constexpr
EnumerableFormat DEFAULT_ENUMERABLE_FORMAT = EnumerableFormat::STRING;
78 explicit BasicJsonWriter(std::ostream& out,
const ALLOC& allocator = ALLOC());
87 BasicJsonWriter(std::ostream& out, uint8_t indent,
const ALLOC& allocator = ALLOC());
97 const ALLOC& allocator = ALLOC());
156 size_t elementIndex)
override;
160 const ALLOC& allocator = ALLOC());
170 void writeKey(std::string_view key);
183 bool m_isFirst =
true;
192 template <
typename ALLOC>
197 template <
typename ALLOC>
202 template <
typename ALLOC>
208 template <
typename ALLOC>
213 m_indent(optionalIndent),
215 m_indent.has_value() ? DEFAULT_ITEM_SEPARATOR_WITH_INDENT : DEFAULT_ITEM_SEPARATOR, allocator),
216 m_keySeparator(DEFAULT_KEY_SEPARATOR, allocator)
219 template <
typename ALLOC>
222 m_itemSeparator = itemSeparator;
225 template <
typename ALLOC>
228 m_keySeparator = keySeparator;
231 template <
typename ALLOC>
234 m_enumerableFormat = enumerableFormat;
237 template <
typename ALLOC>
243 template <
typename ALLOC>
250 template <
typename ALLOC>
261 template <
typename ALLOC>
269 template <
typename ALLOC>
275 if (elementIndex == WALKER_NOT_ELEMENT)
283 template <
typename ALLOC>
292 template <
typename ALLOC>
298 if (elementIndex == WALKER_NOT_ELEMENT)
308 template <
typename ALLOC>
313 m_out.write(m_itemSeparator.data(),
static_cast<std::streamsize
>(m_itemSeparator.size()));
316 if (m_indent.has_value())
324 template <
typename ALLOC>
325 void BasicJsonWriter<ALLOC>::endItem()
330 template <
typename ALLOC>
331 void BasicJsonWriter<ALLOC>::beginObject()
339 template <
typename ALLOC>
340 void BasicJsonWriter<ALLOC>::endObject()
342 if (m_indent.has_value())
354 template <
typename ALLOC>
355 void BasicJsonWriter<ALLOC>::beginArray()
363 template <
typename ALLOC>
364 void BasicJsonWriter<ALLOC>::endArray()
366 if (m_indent.has_value())
378 template <
typename ALLOC>
379 void BasicJsonWriter<ALLOC>::writeIndent()
381 if (m_indent.has_value())
383 const auto& indent = m_indent.value();
386 for (
size_t i = 0; i < m_level; ++i)
388 m_out.write(indent.data(),
static_cast<std::streamsize
>(indent.size()));
394 template <
typename ALLOC>
395 void BasicJsonWriter<ALLOC>::writeKey(std::string_view key)
398 m_out.write(m_keySeparator.data(),
static_cast<std::streamsize
>(m_keySeparator.size()));
402 template <
typename ALLOC>
403 void BasicJsonWriter<ALLOC>::writeValue(
const IBasicReflectableDataConstPtr<ALLOC>&
reflectable)
445 if (m_enumerableFormat == EnumerableFormat::STRING)
459 if (m_enumerableFormat == EnumerableFormat::STRING)
469 throw CppRuntimeException(
"JsonWriter: Unexpected not-null value of type '")
476 template <
typename ALLOC>
477 void BasicJsonWriter<ALLOC>::writeBitBuffer(
const BasicBitBuffer<ALLOC>& bitBuffer)
481 writeKey(
"buffer"sv);
483 Span<const uint8_t> buffer = bitBuffer.getData();
484 for (uint8_t element : buffer)
493 writeKey(
"bitSize"sv);
499 template <
typename ALLOC>
500 void BasicJsonWriter<ALLOC>::writeBytes(Span<const uint8_t> value)
504 writeKey(
"buffer"sv);
506 for (uint8_t
byte : value)
517 template <
typename ALLOC>
518 void BasicJsonWriter<ALLOC>::writeStringifiedEnum(
const IBasicReflectableDataConstPtr<ALLOC>&
reflectable)
526 if (itemInfo.value == enumValue)
535 BasicString<RebindAlloc<ALLOC, char>> stringValue =
539 stringValue.append(
" /* no match */");
543 template <
typename ALLOC>
544 void BasicJsonWriter<ALLOC>::writeStringifiedBitmask(
const IBasicReflectableDataConstPtr<ALLOC>&
reflectable)
546 BasicString<RebindAlloc<ALLOC, char>> stringValue(get_allocator());
548 const uint64_t bitmaskValue =
reflectable->toUInt();
549 uint64_t valueCheck = 0;
552 if ((itemInfo.value != 0 && (bitmaskValue & itemInfo.value) == itemInfo.value) ||
553 (itemInfo.value == 0 && bitmaskValue == 0))
555 valueCheck |= itemInfo.value;
556 if (!stringValue.empty())
558 stringValue +=
" | ";
560 stringValue +=
toString(itemInfo.schemaName, get_allocator());
564 if (stringValue.empty())
567 stringValue.append(
toString(bitmaskValue, get_allocator()));
568 stringValue.append(
" /* no match */");
570 else if (bitmaskValue != valueCheck)
574 toString(bitmaskValue, get_allocator())
575 .append(
" /* partial match: ")
BasicJsonWriter(std::ostream &out, const ALLOC &allocator=ALLOC())
BasicJsonWriter & operator=(const BasicJsonWriter &other)=delete
void endRoot(const IBasicReflectableDataConstPtr< ALLOC > &compound) override
void setKeySeparator(const BasicString< RebindAlloc< ALLOC, char >> &keySeparator)
BasicJsonWriter(BasicJsonWriter &&other)=delete
void visitValue(const IBasicReflectableDataConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
void endCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
~BasicJsonWriter() override=default
BasicJsonWriter(const BasicJsonWriter &other)=delete
void setItemSeparator(const BasicString< RebindAlloc< ALLOC, char >> &itemSeparator)
void setEnumerableFormat(EnumerableFormat enumerableFormat)
BasicJsonWriter & operator=(BasicJsonWriter &&other)=delete
void beginCompound(const IBasicReflectableDataConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
void beginRoot(const IBasicReflectableDataConstPtr< ALLOC > &compound) override
virtual const IBasicTypeInfo< ALLOC > & getUnderlyingType() const =0
virtual CppType getCppType() const =0
virtual Span< const ItemInfo > getEnumItems() const =0
virtual Span< const ItemInfo > getBitmaskValues() const =0
virtual std::string_view getSchemaName() const =0
static void encodeFloatingPoint(std::ostream &stream, double value)
static void encodeNull(std::ostream &stream)
static void encodeBool(std::ostream &stream, bool value)
static void encodeIntegral(std::ostream &stream, T value)
static void encodeString(std::ostream &stream, std::string_view value)
typename IBasicReflectableData< ALLOC >::ConstPtr IBasicReflectableDataConstPtr
std::basic_string< char, std::char_traits< char >, ALLOC > BasicString
IBasicReflectableDataConstPtr< ALLOC > reflectable(const T &value, const ALLOC &allocator=ALLOC())
typename std::allocator_traits< ALLOC >::template rebind_alloc< T > RebindAlloc
const IBasicTypeInfo< ALLOC > & typeInfo()
BasicString< RebindAlloc< ALLOC, char > > toString(T value, const ALLOC &allocator=ALLOC())
std::string_view schemaName
static bool isSigned(SchemaType schemaType)