#pragma once #include #include #include #include "cbor.h" #include "result.hpp" #include "span.hpp" namespace audio { extern const int kEncoderFlags; extern const int kDecoderFlags; enum MessageType { TYPE_UNKNOWN, TYPE_CHUNK_HEADER, TYPE_STREAM_INFO, }; template auto WriteMessage(MessageType type, Writer&& writer, cpp::span data) -> cpp::result { CborEncoder root; CborEncoder container; uint8_t* cast_data = reinterpret_cast(data.data()); cbor_encoder_init(&root, cast_data, data.size(), kEncoderFlags); cbor_encoder_create_array(&root, &container, 2); cbor_encode_uint(&container, type); std::optional inner_err = std::invoke(writer, container); if (inner_err) { return cpp::fail(inner_err.value()); } cbor_encoder_close_container(&root, &container); return cbor_encoder_get_buffer_size(&root, cast_data); } template auto ReadMessage(Reader&& reader, cpp::span data) -> cpp::result { CborParser parser; CborValue root; CborValue container; cbor_parser_init(reinterpret_cast(data.data()), data.size(), kDecoderFlags, &parser, &root); cbor_value_enter_container(&root, &container); // Skip the type header cbor_value_advance_fixed(&container); return std::invoke(reader, container); } auto WriteTypeOnlyMessage(MessageType type, cpp::span data) -> cpp::result; auto ReadMessageType(cpp::span msg) -> MessageType; auto GetAdditionalData(cpp::span msg) -> cpp::span; } // namespace audio