1 #ifndef ZSERIO_JSON_WRITER_H_INC
2 #define ZSERIO_JSON_WRITER_H_INC
19 template <
typename ALLOC = std::allocator<u
int8_t>>
76 explicit BasicJsonWriter(std::ostream& out,
const ALLOC& allocator = ALLOC());
85 BasicJsonWriter(std::ostream& out, uint8_t indent,
const ALLOC& allocator = ALLOC());
148 size_t elementIndex)
override;
150 size_t elementIndex)
override;
153 size_t elementIndex)
override;
157 const ALLOC& allocator = ALLOC());
180 bool m_isFirst =
true;
189 template <
typename ALLOC>
194 template <
typename ALLOC>
199 template <
typename ALLOC>
201 std::ostream& out,
const string<ALLOC>& indent,
const ALLOC& allocator) :
205 template <
typename ALLOC>
210 m_indent(optionalIndent),
212 m_indent.hasValue() ? DEFAULT_ITEM_SEPARATOR_WITH_INDENT : DEFAULT_ITEM_SEPARATOR, allocator),
213 m_keySeparator(DEFAULT_KEY_SEPARATOR, allocator)
216 template <
typename ALLOC>
219 m_itemSeparator = itemSeparator;
222 template <
typename ALLOC>
225 m_keySeparator = keySeparator;
228 template <
typename ALLOC>
231 m_enumerableFormat = enumerableFormat;
234 template <
typename ALLOC>
240 template <
typename ALLOC>
247 template <
typename ALLOC>
258 template <
typename ALLOC>
266 template <
typename ALLOC>
272 if (elementIndex == WALKER_NOT_ELEMENT)
280 template <
typename ALLOC>
289 template <
typename ALLOC>
295 if (elementIndex == WALKER_NOT_ELEMENT)
305 template <
typename ALLOC>
310 m_out.write(m_itemSeparator.data(),
static_cast<std::streamsize
>(m_itemSeparator.size()));
313 if (m_indent.hasValue())
321 template <
typename ALLOC>
322 void BasicJsonWriter<ALLOC>::endItem()
327 template <
typename ALLOC>
328 void BasicJsonWriter<ALLOC>::beginObject()
336 template <
typename ALLOC>
337 void BasicJsonWriter<ALLOC>::endObject()
339 if (m_indent.hasValue())
351 template <
typename ALLOC>
352 void BasicJsonWriter<ALLOC>::beginArray()
360 template <
typename ALLOC>
361 void BasicJsonWriter<ALLOC>::endArray()
363 if (m_indent.hasValue())
375 template <
typename ALLOC>
376 void BasicJsonWriter<ALLOC>::writeIndent()
378 if (m_indent.hasValue())
380 const auto& indent = m_indent.value();
383 for (
size_t i = 0; i < m_level; ++i)
385 m_out.write(indent.data(),
static_cast<std::streamsize
>(indent.size()));
391 template <
typename ALLOC>
392 void BasicJsonWriter<ALLOC>::writeKey(
StringView key)
395 m_out.write(m_keySeparator.data(),
static_cast<std::streamsize
>(m_keySeparator.size()));
399 template <
typename ALLOC>
400 void BasicJsonWriter<ALLOC>::writeValue(
const IBasicReflectableConstPtr<ALLOC>& reflectable)
408 const IBasicTypeInfo<ALLOC>& typeInfo = reflectable->getTypeInfo();
409 switch (typeInfo.getCppType())
433 writeBytes(reflectable->getBytes());
439 writeBitBuffer(reflectable->getBitBuffer());
442 if (m_enumerableFormat == EnumerableFormat::STRING)
444 writeStringifiedEnum(reflectable);
456 if (m_enumerableFormat == EnumerableFormat::STRING)
458 writeStringifiedBitmask(reflectable);
473 throw CppRuntimeException(
"JsonWriter: Unexpected not-null value of type '")
474 << typeInfo.getSchemaName() <<
"'!";
480 template <
typename ALLOC>
481 void BasicJsonWriter<ALLOC>::writeBitBuffer(
const BasicBitBuffer<ALLOC>& bitBuffer)
485 writeKey(
"buffer"_sv);
487 Span<const uint8_t> buffer = bitBuffer.getData();
488 for (uint8_t element : buffer)
497 writeKey(
"bitSize"_sv);
503 template <
typename ALLOC>
504 void BasicJsonWriter<ALLOC>::writeBytes(Span<const uint8_t> value)
508 writeKey(
"buffer"_sv);
510 for (uint8_t
byte : value)
521 template <
typename ALLOC>
522 void BasicJsonWriter<ALLOC>::writeStringifiedEnum(
const IBasicReflectableConstPtr<ALLOC>& reflectable)
524 const auto& typeInfo = reflectable->getTypeInfo();
526 ?
static_cast<uint64_t
>(reflectable->toInt())
527 : reflectable->toUInt();
528 for (
const auto& itemInfo : typeInfo.getEnumItems())
530 if (itemInfo.value == enumValue)
540 ?
toString(reflectable->toInt(), get_allocator())
541 :
toString(reflectable->toUInt(), get_allocator());
542 stringValue.append(
" /* no match */");
546 template <
typename ALLOC>
547 void BasicJsonWriter<ALLOC>::writeStringifiedBitmask(
const IBasicReflectableConstPtr<ALLOC>& reflectable)
549 string<ALLOC> stringValue(get_allocator());
550 const auto& typeInfo = reflectable->getTypeInfo();
551 const uint64_t bitmaskValue = reflectable->toUInt();
552 uint64_t valueCheck = 0;
553 for (
const auto& itemInfo : typeInfo.getBitmaskValues())
555 if ((itemInfo.value != 0 && (bitmaskValue & itemInfo.value) == itemInfo.value) ||
556 (itemInfo.value == 0 && bitmaskValue == 0))
558 valueCheck |= itemInfo.value;
559 if (!stringValue.empty())
561 stringValue +=
" | ";
563 stringValue +=
toString(itemInfo.schemaName, get_allocator());
567 if (stringValue.empty())
570 stringValue.append(
toString(bitmaskValue, get_allocator()));
571 stringValue.append(
" /* no match */");
573 else if (bitmaskValue != valueCheck)
577 toString(bitmaskValue, get_allocator())
578 .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)