From c36208016eefcdfdeff045f675f74fdb69dddb52 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 2 Dec 2022 17:25:53 +1100 Subject: better cbor handling --- src/audio/stream_info.cpp | 92 +++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 35 deletions(-) (limited to 'src/audio/stream_info.cpp') diff --git a/src/audio/stream_info.cpp b/src/audio/stream_info.cpp index a5f7bebf..8f217b79 100644 --- a/src/audio/stream_info.cpp +++ b/src/audio/stream_info.cpp @@ -5,8 +5,6 @@ #include "cbor.h" -#include "cbor_decoder.hpp" -#include "cbor_encoder.hpp" #include "stream_message.hpp" namespace audio { @@ -16,48 +14,72 @@ static const std::string kKeyChannels = "c"; static const std::string kKeyBitsPerSample = "b"; static const std::string kKeySampleRate = "r"; -auto StreamInfo::Create(const uint8_t* buffer, size_t length) - -> cpp::result { - CborParser parser; - CborValue value; +auto StreamInfo::Parse(CborValue& container) + -> cpp::result { + CborValue map; + cbor_value_enter_container(&container, &map); - cbor_parser_init(buffer, length, 0, &parser, &value); + CborValue entry; + StreamInfo ret; - int type = 0; - if (!cbor_value_is_integer(&value) || !cbor_value_get_int(&value, &type) || - type != TYPE_STREAM_INFO) { - return cpp::fail(WRONG_TYPE); + cbor_value_map_find_value(&map, kKeyPath.c_str(), &entry); + if (cbor_value_get_type(&entry) != CborInvalidType) { + char* val; + size_t len; + cbor_value_dup_text_string(&entry, &val, &len, NULL); + ret.path_ = std::string(val, len); + free(val); + } + cbor_value_map_find_value(&map, kKeyChannels.c_str(), &entry); + if (cbor_value_get_type(&entry) != CborInvalidType) { + uint64_t val; + cbor_value_get_uint64(&entry, &val); + ret.channels_ = val; + } + cbor_value_map_find_value(&map, kKeyBitsPerSample.c_str(), &entry); + if (cbor_value_get_type(&entry) != CborInvalidType) { + uint64_t val; + cbor_value_get_uint64(&entry, &val); + ret.bits_per_sample_ = val; + } + cbor_value_map_find_value(&map, kKeySampleRate.c_str(), &entry); + if (cbor_value_get_type(&entry) != CborInvalidType) { + uint64_t val; + cbor_value_get_uint64(&entry, &val); + ret.sample_rate_ = val; } - cbor_value_advance_fixed(&value); + return ret; +} - if (!cbor_value_is_map(&value)) { - return cpp::fail(MISSING_MAP); - } +auto StreamInfo::Encode(CborEncoder& enc) -> std::optional { + CborEncoder map; + size_t num_items = 0 + channels_.has_value() + bits_per_sample_.has_value() + + sample_rate_.has_value() + path_.has_value(); + cbor_encoder_create_map(&enc, &map, num_items); - auto map_decoder = cbor::MapDecoder::Create(value); - if (map_decoder.has_value()) { - return StreamInfo(map_decoder.value().get()); + if (channels_) { + cbor_encode_text_string(&map, kKeyChannels.c_str(), kKeyChannels.size()); + cbor_encode_uint(&map, channels_.value()); + } + if (bits_per_sample_) { + cbor_encode_text_string(&map, kKeyBitsPerSample.c_str(), + kKeyBitsPerSample.size()); + cbor_encode_uint(&map, bits_per_sample_.value()); + } + if (sample_rate_) { + cbor_encode_text_string(&map, kKeySampleRate.c_str(), + kKeySampleRate.size()); + cbor_encode_uint(&map, sample_rate_.value()); + } + if (path_) { + cbor_encode_text_string(&map, kKeyPath.c_str(), kKeyPath.size()); + cbor_encode_text_string(&map, path_.value().c_str(), path_.value().size()); } - return cpp::fail(CBOR_ERROR); -} -StreamInfo::StreamInfo(cbor::MapDecoder* decoder) { - // TODO: this method is n^2, which seems less than ideal. But you don't do it - // that frequently, so maybe it's okay? Needs investigation. - channels_ = decoder->FindValue(kKeyChannels); - bits_per_sample_ = decoder->FindValue(kKeyBitsPerSample); - sample_rate_ = decoder->FindValue(kKeySampleRate); - path_ = decoder->FindValue(kKeyPath); -} + cbor_encoder_close_container(&enc, &map); -auto StreamInfo::WriteToMap(cbor::Encoder& map_encoder) - -> cpp::result { - map_encoder.WriteKeyValue(kKeyChannels, channels_); - map_encoder.WriteKeyValue(kKeyBitsPerSample, bits_per_sample_); - map_encoder.WriteKeyValue(kKeySampleRate, sample_rate_); - map_encoder.WriteKeyValue(kKeyPath, path_); - return map_encoder.Finish(); + return std::nullopt; } } // namespace audio -- cgit v1.2.3