From 9176ef187227ffb56c249c5f321cd1bf50d4cfcc Mon Sep 17 00:00:00 2001 From: jacqueline Date: Tue, 22 Nov 2022 17:05:02 +1100 Subject: Add cbor wrapper, and chunk streaming util --- src/cbor/cbor_decoder.cpp | 158 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 src/cbor/cbor_decoder.cpp (limited to 'src/cbor/cbor_decoder.cpp') diff --git a/src/cbor/cbor_decoder.cpp b/src/cbor/cbor_decoder.cpp new file mode 100644 index 00000000..eb43e163 --- /dev/null +++ b/src/cbor/cbor_decoder.cpp @@ -0,0 +1,158 @@ +#include "cbor_decoder.hpp" +#include +#include "esp-idf/components/cbor/tinycbor/src/cbor.h" +#include "include/cbor_decoder.hpp" + +namespace cbor { + +static auto ArrayDecoder::Create(uint8_t *buffer, size_t buffer_len) -> cpp::result, CborError> { + auto decoder = std::make_unique(); + cbor_parser_init(buffer, buffer_len, &decoder->parser_, &decoder->root_); + if (!cbor_value_is_array(&decoder->root_)) { + return cpp::fail(CborErrorIllegalType); + } + CborError err = cbor_value_enter_container(&decoder->root_, &decoder->it_); + if (err != CborNoError) { + return cpp::fail(err); + } + return std::move(decoder); +} + + +auto ArrayDecoder::ParseString() -> cpp::result { + if (error_ != CborNoError) { + return cpp::fail(error_); + } + + if (!cbor_value_is_byte_string(&it_)) { + error_ = CborErrorIllegalType; + return cpp::fail(error_); + } + uint8_t *buf; size_t len; CborValue new_val; + error_ = cbor_value_dup_byte_string(&it_, &buf, &len, &new_val); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + std::string ret(buf, len); + free(buf); + val_ = new_val; + return ret; +} + +auto ArrayDecoder::ParseUnsigned() -> cpp::result { + if (error_ != CborNoError) { + return cpp::fail(error_); + } + + if (!cbor_value_is_unsigned_integer(&it_)) { + error_ = CborErrorIllegalType; + return cpp::fail(error_); + } + uint64_t ret; + error_ = cbor_value_get_uint64(&it_, &ret); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + error_ = cbor_value_advance(&it_); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + return ret; +} + +auto ArrayDecoder::ParseSigned() -> cpp::result { + if (error_ != CborNoError) { + return cpp::fail(error_); + } + if (!cbor_value_is_unsigned_integer(&it_)) { + error_ = CborErrorIllegalType; + return cpp::fail(error_); + } + uint64_t ret; + error_ = cbor_value_get_uint64(&it_, &ret); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + error_ = cbor_value_advance(&it_); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + return ret; +} + +static auto MapDecoder::Create(uint8_t *buffer, size_t buffer_len) -> cpp::result, CborError> { + auto decoder = std::make_unique(); + cbor_parser_init(buffer, buffer_len, &decoder->parser_, &decoder->root_); + if (!cbor_value_is_map(&decoder->root_)) { + return cpp::fail(CborErrorIllegalType); + } + CborError err = cbor_value_enter_container(&decoder->root_, &decoder->it_); + if (err != CborNoError) { + return cpp::fail(err); + } + return std::move(decoder); +} + +auto MapDecoder::FindString(const std::string &key) -> std::optional { + CborValue val; + if (error_ != CborNoError) { + return {}; + } + if (cbor_value_map_find_value(&it_, key.c_str(), &val) != CborNoError) { + return {}; + } + if (!cbor_value_is_byte_string(&val)) { + error_ = CborErrorIllegalType; + return {}; + } + uint8_t *buf; size_t len; + error_ = cbor_value_dup_byte_string(&val, &buf, &len, NULL); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + std::string ret(buf, len); + free(buf); + return ret; +} + +auto MapDecoder::FindUnsigned(const std::string &key) -> std::optional { + CborValue val; + if (error_ != CborNoError) { + return {}; + } + if (cbor_value_map_find_value(&it_, key.c_str(), &val) != CborNoError) { + return {}; + } + if (!cbor_value_is_unsigned_integer(&val)) { + error_ = CborErrorIllegalType; + return {}; + } + uint64_t ret; + error_ = cbor_value_get_uint64(&val, &ret); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + return ret; +} + +auto MapDecoder::FindSigned(const std::string &key) -> std::optional { + CborValue val; + if (error_ != CborNoError) { + return {}; + } + if (cbor_value_map_find_value(&it_, key.c_str(), &val) != CborNoError) { + return {}; + } + if (!cbor_value_is_integer(&val)) { + error_ = CborErrorIllegalType; + return {}; + } + int32_t ret; + error_ = cbor_value_get_int(&val, &ret); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + return ret; +} + +} // namespace cbor -- cgit v1.2.3