1 #ifndef ZSERIO_JSON_WRITER_H_INC
2 #define ZSERIO_JSON_WRITER_H_INC
18 template <
typename ALLOC = std::allocator<u
int8_t>>
75 explicit BasicJsonWriter(std::ostream& out,
const ALLOC& allocator = ALLOC());
84 BasicJsonWriter(std::ostream& out, uint8_t indent,
const ALLOC& allocator = ALLOC());
147 size_t elementIndex)
override;
149 size_t elementIndex)
override;
152 size_t elementIndex)
override;
156 const ALLOC& allocator = ALLOC());
179 bool m_isFirst =
true;
188 template <
typename ALLOC>
193 template <
typename ALLOC>
198 template <
typename ALLOC>
200 std::ostream& out,
const string<ALLOC>& indent,
const ALLOC& allocator) :
204 template <
typename ALLOC>
209 m_indent(optionalIndent),
211 m_indent.hasValue() ? DEFAULT_ITEM_SEPARATOR_WITH_INDENT : DEFAULT_ITEM_SEPARATOR, allocator),
212 m_keySeparator(DEFAULT_KEY_SEPARATOR, allocator)
215 template <
typename ALLOC>
218 m_itemSeparator = itemSeparator;
221 template <
typename ALLOC>
224 m_keySeparator = keySeparator;
227 template <
typename ALLOC>
230 m_enumerableFormat = enumerableFormat;
233 template <
typename ALLOC>
239 template <
typename ALLOC>
246 template <
typename ALLOC>
257 template <
typename ALLOC>
265 template <
typename ALLOC>
271 if (elementIndex == WALKER_NOT_ELEMENT)
279 template <
typename ALLOC>
288 template <
typename ALLOC>
294 if (elementIndex == WALKER_NOT_ELEMENT)
304 template <
typename ALLOC>
309 m_out.write(m_itemSeparator.data(),
static_cast<std::streamsize
>(m_itemSeparator.size()));
312 if (m_indent.hasValue())
320 template <
typename ALLOC>
321 void BasicJsonWriter<ALLOC>::endItem()
326 template <
typename ALLOC>
327 void BasicJsonWriter<ALLOC>::beginObject()
335 template <
typename ALLOC>
336 void BasicJsonWriter<ALLOC>::endObject()
338 if (m_indent.hasValue())
350 template <
typename ALLOC>
351 void BasicJsonWriter<ALLOC>::beginArray()
359 template <
typename ALLOC>
360 void BasicJsonWriter<ALLOC>::endArray()
362 if (m_indent.hasValue())
374 template <
typename ALLOC>
375 void BasicJsonWriter<ALLOC>::writeIndent()
377 if (m_indent.hasValue())
379 const auto& indent = m_indent.value();
382 for (
size_t i = 0; i < m_level; ++i)
384 m_out.write(indent.data(),
static_cast<std::streamsize
>(indent.size()));
390 template <
typename ALLOC>
391 void BasicJsonWriter<ALLOC>::writeKey(
StringView key)
394 m_out.write(m_keySeparator.data(),
static_cast<std::streamsize
>(m_keySeparator.size()));
398 template <
typename ALLOC>
399 void BasicJsonWriter<ALLOC>::writeValue(
const IBasicReflectableConstPtr<ALLOC>& reflectable)
407 const IBasicTypeInfo<ALLOC>& typeInfo = reflectable->getTypeInfo();
408 switch (typeInfo.getCppType())
432 writeBytes(reflectable->getBytes());
438 writeBitBuffer(reflectable->getBitBuffer());
441 if (m_enumerableFormat == EnumerableFormat::STRING)
443 writeStringifiedEnum(reflectable);
455 if (m_enumerableFormat == EnumerableFormat::STRING)
457 writeStringifiedBitmask(reflectable);
465 throw CppRuntimeException(
"JsonWriter: Unexpected not-null value of type '")
466 << typeInfo.getSchemaName() <<
"'!";
472 template <
typename ALLOC>
473 void BasicJsonWriter<ALLOC>::writeBitBuffer(
const BasicBitBuffer<ALLOC>& bitBuffer)
477 writeKey(
"buffer"_sv);
479 Span<const uint8_t> buffer = bitBuffer.getData();
480 for (uint8_t element : buffer)
489 writeKey(
"bitSize"_sv);
495 template <
typename ALLOC>
496 void BasicJsonWriter<ALLOC>::writeBytes(Span<const uint8_t> value)
500 writeKey(
"buffer"_sv);
502 for (uint8_t
byte : value)
513 template <
typename ALLOC>
514 void BasicJsonWriter<ALLOC>::writeStringifiedEnum(
const IBasicReflectableConstPtr<ALLOC>& reflectable)
516 const auto& typeInfo = reflectable->getTypeInfo();
518 ?
static_cast<uint64_t
>(reflectable->toInt())
519 : reflectable->toUInt();
520 for (
const auto& itemInfo : typeInfo.getEnumItems())
522 if (itemInfo.value == enumValue)
532 ?
toString(reflectable->toInt(), get_allocator())
533 :
toString(reflectable->toUInt(), get_allocator());
534 stringValue.append(
" /* no match */");
538 template <
typename ALLOC>
539 void BasicJsonWriter<ALLOC>::writeStringifiedBitmask(
const IBasicReflectableConstPtr<ALLOC>& reflectable)
541 string<ALLOC> stringValue(get_allocator());
542 const auto& typeInfo = reflectable->getTypeInfo();
543 const uint64_t bitmaskValue = reflectable->toUInt();
544 uint64_t valueCheck = 0;
545 for (
const auto& itemInfo : typeInfo.getBitmaskValues())
547 if ((itemInfo.value != 0 && (bitmaskValue & itemInfo.value) == itemInfo.value) ||
548 (itemInfo.value == 0 && bitmaskValue == 0))
550 valueCheck |= itemInfo.value;
551 if (!stringValue.empty())
553 stringValue +=
" | ";
555 stringValue +=
toString(itemInfo.schemaName, get_allocator());
559 if (stringValue.empty())
562 stringValue.append(
toString(bitmaskValue, get_allocator()));
563 stringValue.append(
" /* no match */");
565 else if (bitmaskValue != valueCheck)
569 toString(bitmaskValue, get_allocator())
570 .append(
" /* partial match: ")
BasicJsonWriter(std::ostream &out, const ALLOC &allocator=ALLOC())
static constexpr const char * DEFAULT_ITEM_SEPARATOR_WITH_INDENT
void endRoot(const IBasicReflectableConstPtr< ALLOC > &compound) override
BasicJsonWriter & operator=(const BasicJsonWriter &other)=delete
void visitValue(const IBasicReflectableConstPtr< ALLOC > &value, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
void beginCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
static constexpr const char * DEFAULT_KEY_SEPARATOR
BasicJsonWriter(BasicJsonWriter &&other)=delete
void endArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
void setItemSeparator(const string< ALLOC > &itemSeparator)
~BasicJsonWriter() override=default
BasicJsonWriter(const BasicJsonWriter &other)=delete
void setEnumerableFormat(EnumerableFormat enumerableFormat)
BasicJsonWriter & operator=(BasicJsonWriter &&other)=delete
static constexpr const char * DEFAULT_ITEM_SEPARATOR
void setKeySeparator(const string< ALLOC > &keySeparator)
void endCompound(const IBasicReflectableConstPtr< ALLOC > &compound, const BasicFieldInfo< ALLOC > &fieldInfo, size_t elementIndex) override
static constexpr EnumerableFormat DEFAULT_ENUMERABLE_FORMAT
void beginRoot(const IBasicReflectableConstPtr< ALLOC > &compound) override
void beginArray(const IBasicReflectableConstPtr< ALLOC > &array, const BasicFieldInfo< ALLOC > &fieldInfo) override
static void encodeFloatingPoint(std::ostream &stream, double value)
static void encodeNull(std::ostream &stream)
static void encodeBool(std::ostream &stream, bool value)
static void encodeString(std::ostream &stream, StringView value)
static void encodeIntegral(std::ostream &stream, T value)
constexpr NullOptType NullOpt
BasicStringView< char, std::char_traits< char > > StringView
std::basic_string< char, std::char_traits< char >, RebindAlloc< ALLOC, char > > string
string< ALLOC > toString(T value, const ALLOC &allocator=ALLOC())
typename IBasicReflectable< ALLOC >::ConstPtr IBasicReflectableConstPtr
detail::inplace_optional_holder< T > InplaceOptionalHolder
static bool isSigned(SchemaType schemaType)