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)
277 template <
typename ALLOC>
286 template <
typename ALLOC>
292 if (elementIndex == WALKER_NOT_ELEMENT)
300 template <
typename ALLOC>
304 m_out.write(m_itemSeparator.data(),
static_cast<std::streamsize
>(m_itemSeparator.size()));
306 if (m_indent.hasValue())
312 template <
typename ALLOC>
313 void BasicJsonWriter<ALLOC>::endItem()
318 template <
typename ALLOC>
319 void BasicJsonWriter<ALLOC>::beginObject()
327 template <
typename ALLOC>
328 void BasicJsonWriter<ALLOC>::endObject()
330 if (m_indent.hasValue())
340 template <
typename ALLOC>
341 void BasicJsonWriter<ALLOC>::beginArray()
349 template <
typename ALLOC>
350 void BasicJsonWriter<ALLOC>::endArray()
352 if (m_indent.hasValue())
362 template <
typename ALLOC>
363 void BasicJsonWriter<ALLOC>::writeIndent()
365 if (m_indent.hasValue())
367 const auto& indent = m_indent.value();
370 for (
size_t i = 0; i < m_level; ++i)
371 m_out.write(indent.data(),
static_cast<std::streamsize
>(indent.size()));
376 template <
typename ALLOC>
377 void BasicJsonWriter<ALLOC>::writeKey(
StringView key)
380 m_out.write(m_keySeparator.data(),
static_cast<std::streamsize
>(m_keySeparator.size()));
384 template <
typename ALLOC>
385 void BasicJsonWriter<ALLOC>::writeValue(
const IBasicReflectableConstPtr<ALLOC>& reflectable)
393 const IBasicTypeInfo<ALLOC>& typeInfo = reflectable->getTypeInfo();
394 switch (typeInfo.getCppType())
418 writeBytes(reflectable->getBytes());
424 writeBitBuffer(reflectable->getBitBuffer());
427 if (m_enumerableFormat == EnumerableFormat::STRING)
428 writeStringifiedEnum(reflectable);
435 if (m_enumerableFormat == EnumerableFormat::STRING)
436 writeStringifiedBitmask(reflectable);
441 throw CppRuntimeException(
"JsonWriter: Unexpected not-null value of type '")
442 << typeInfo.getSchemaName() <<
"'!";
448 template <
typename ALLOC>
449 void BasicJsonWriter<ALLOC>::writeBitBuffer(
const BasicBitBuffer<ALLOC>& bitBuffer)
453 writeKey(
"buffer"_sv);
455 Span<const uint8_t> buffer = bitBuffer.getData();
456 for (uint8_t element : buffer)
465 writeKey(
"bitSize"_sv);
471 template <
typename ALLOC>
472 void BasicJsonWriter<ALLOC>::writeBytes(Span<const uint8_t> value)
476 writeKey(
"buffer"_sv);
478 for (uint8_t
byte : value)
489 template <
typename ALLOC>
490 void BasicJsonWriter<ALLOC>::writeStringifiedEnum(
const IBasicReflectableConstPtr<ALLOC>& reflectable)
492 const auto& typeInfo = reflectable->getTypeInfo();
494 ?
static_cast<uint64_t
>(reflectable->toInt())
495 : reflectable->toUInt();
496 for (
const auto& itemInfo : typeInfo.getEnumItems())
498 if (itemInfo.value == enumValue)
508 ?
toString(reflectable->toInt(), get_allocator())
509 :
toString(reflectable->toUInt(), get_allocator());
510 stringValue.append(
" /* no match */");
514 template <
typename ALLOC>
515 void BasicJsonWriter<ALLOC>::writeStringifiedBitmask(
const IBasicReflectableConstPtr<ALLOC>& reflectable)
517 string<ALLOC> stringValue(get_allocator());
518 const auto& typeInfo = reflectable->getTypeInfo();
519 const uint64_t bitmaskValue = reflectable->toUInt();
520 uint64_t valueCheck = 0;
521 for (
const auto& itemInfo : typeInfo.getBitmaskValues())
523 if ((itemInfo.value != 0 && (bitmaskValue & itemInfo.value) == itemInfo.value) ||
524 (itemInfo.value == 0 && bitmaskValue == 0))
526 valueCheck |= itemInfo.value;
527 if (!stringValue.empty())
528 stringValue +=
" | ";
529 stringValue +=
toString(itemInfo.schemaName, get_allocator());
533 if (stringValue.empty())
536 stringValue.append(
toString(bitmaskValue, get_allocator()));
537 stringValue.append(
" /* no match */");
539 else if (bitmaskValue != valueCheck)
543 toString(bitmaskValue, get_allocator())
544 .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)