#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