From 222c810b07ffc635fc7908d121e97e4d65ccc5c8 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 2 Dec 2022 13:39:00 +1100 Subject: fix build errors --- src/cbor_wrapper/CMakeLists.txt | 6 ++ src/cbor_wrapper/cbor_decoder.cpp | 112 +++++++++++++++++++++++++++++ src/cbor_wrapper/cbor_encoder.cpp | 63 +++++++++++++++++ src/cbor_wrapper/include/cbor_decoder.hpp | 113 ++++++++++++++++++++++++++++++ src/cbor_wrapper/include/cbor_encoder.hpp | 52 ++++++++++++++ 5 files changed, 346 insertions(+) create mode 100644 src/cbor_wrapper/CMakeLists.txt create mode 100644 src/cbor_wrapper/cbor_decoder.cpp create mode 100644 src/cbor_wrapper/cbor_encoder.cpp create mode 100644 src/cbor_wrapper/include/cbor_decoder.hpp create mode 100644 src/cbor_wrapper/include/cbor_encoder.hpp (limited to 'src/cbor_wrapper') diff --git a/src/cbor_wrapper/CMakeLists.txt b/src/cbor_wrapper/CMakeLists.txt new file mode 100644 index 00000000..cd5186e0 --- /dev/null +++ b/src/cbor_wrapper/CMakeLists.txt @@ -0,0 +1,6 @@ +idf_component_register( + SRCS "cbor_decoder.cpp" "cbor_encoder.cpp" + INCLUDE_DIRS "include" + REQUIRES "cbor" "result") + +target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS}) diff --git a/src/cbor_wrapper/cbor_decoder.cpp b/src/cbor_wrapper/cbor_decoder.cpp new file mode 100644 index 00000000..a99cca02 --- /dev/null +++ b/src/cbor_wrapper/cbor_decoder.cpp @@ -0,0 +1,112 @@ +#include "cbor_decoder.hpp" + +#include +#include + +#include "cbor.h" +#include "result.hpp" + +static const int kDecoderFlags = 0; + +namespace cbor { + +auto parse_stdstring(const CborValue* val, std::string* out) -> CborError { + char* buf; + size_t len; + CborError err = cbor_value_dup_text_string(val, &buf, &len, NULL); + if (err != CborNoError) { + return err; + } + *out = std::string(buf, len); + free(buf); + return err; +} + +auto ArrayDecoder::Create(uint8_t* buffer, size_t buffer_len) + -> cpp::result, CborError> { + auto decoder = std::make_unique(); + cbor_parser_init(buffer, buffer_len, kDecoderFlags, &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::Create(CborValue& root) + -> cpp::result, CborError> { + auto decoder = std::make_unique(); + decoder->root_ = 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); +} + +template <> +auto ArrayDecoder::NextValue() -> cpp::result { + return NextValue(&cbor_value_is_integer, &cbor_value_get_int); +} +template <> +auto ArrayDecoder::NextValue() -> cpp::result { + return NextValue(&cbor_value_is_unsigned_integer, &cbor_value_get_uint64); +} +template <> +auto ArrayDecoder::NextValue() -> cpp::result { + return NextValue(&cbor_value_is_byte_string, &parse_stdstring); +} + +auto MapDecoder::Create(uint8_t* buffer, size_t buffer_len) + -> cpp::result, CborError> { + auto decoder = std::make_unique(); + cbor_parser_init(buffer, buffer_len, kDecoderFlags, &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::Create(CborValue& root) + -> cpp::result, CborError> { + auto decoder = std::make_unique(); + decoder->root_ = 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); +} + +template <> +auto MapDecoder::FindValue(const std::string& key) -> std::optional { + return FindValue(key, &cbor_value_is_integer, &cbor_value_get_int); +} +template <> +auto MapDecoder::FindValue(const std::string& key) -> std::optional { + return FindValue(key, &cbor_value_is_unsigned_integer, + &cbor_value_get_uint64); +} +template <> +auto MapDecoder::FindValue(const std::string& key) + -> std::optional { + return FindValue(key, &cbor_value_is_byte_string, &parse_stdstring); +} + +} // namespace cbor diff --git a/src/cbor_wrapper/cbor_encoder.cpp b/src/cbor_wrapper/cbor_encoder.cpp new file mode 100644 index 00000000..e4e8ee84 --- /dev/null +++ b/src/cbor_wrapper/cbor_encoder.cpp @@ -0,0 +1,63 @@ +#include "cbor_encoder.hpp" + +#include +#include + +#include "cbor.h" +#include "cbor_decoder.hpp" +#include "result.hpp" + +namespace cbor { + +static const int kEncoderFlags = 0; + +Encoder::Encoder(ContainerType type, + uint32_t container_len, + uint8_t* buffer, + size_t buffer_len) { + cbor_encoder_init(&root_encoder_, buffer, buffer_len, kEncoderFlags); + switch (type) { + case CONTAINER_ARRAY: + error_ = cbor_encoder_create_array(&root_encoder_, &container_encoder_, + container_len); + break; + case CONTAINER_MAP: + error_ = cbor_encoder_create_map(&root_encoder_, &container_encoder_, + container_len); + break; + } +} + +auto Encoder::WriteValue(const std::string& val) -> void { + if (error_ != CborNoError) { + return; + } + error_ = + cbor_encode_text_string(&container_encoder_, val.c_str(), val.size()); +} + +auto Encoder::WriteValue(uint32_t val) -> void { + if (error_ != CborNoError) { + return; + } + error_ = cbor_encode_uint(&container_encoder_, val); +} + +auto Encoder::WriteValue(int32_t val) -> void { + if (error_ != CborNoError) { + return; + } + error_ = cbor_encode_int(&container_encoder_, val); +} + +auto Encoder::Finish() -> cpp::result { + if (error_ == CborNoError) { + error_ = cbor_encoder_close_container(&root_encoder_, &container_encoder_); + } + if (error_ != CborNoError) { + return cpp::fail(error_); + } + return cbor_encoder_get_buffer_size(&root_encoder_, buffer_); +} + +} // namespace cbor diff --git a/src/cbor_wrapper/include/cbor_decoder.hpp b/src/cbor_wrapper/include/cbor_decoder.hpp new file mode 100644 index 00000000..193e7843 --- /dev/null +++ b/src/cbor_wrapper/include/cbor_decoder.hpp @@ -0,0 +1,113 @@ +#pragma once + +#include + +#include +#include + +#include "cbor.h" +#include "result.hpp" + +namespace cbor { + +class ArrayDecoder { + public: + static auto Create(uint8_t* buffer, size_t buffer_len) + -> cpp::result, CborError>; + + static auto Create(CborValue& root) + -> cpp::result, CborError>; + + ArrayDecoder() {} + + template + auto NextValue() -> cpp::result; + + template + auto NextValue(bool (*is_valid)(const CborValue*), + CborError (*parse)(const CborValue*, T*)) + -> cpp::result { + if (error_ != CborNoError) { + return cpp::fail(error_); + } + if (!is_valid(&it_)) { + error_ = CborErrorIllegalType; + return cpp::fail(error_); + } + T ret; + error_ = parse(&it_, &ret); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + error_ = cbor_value_advance(&it_); + if (error_ != CborNoError) { + return cpp::fail(error_); + } + return ret; + } + + auto Failed() -> CborError { return error_; } + + auto Iterator() -> CborValue& { return it_; } + + ArrayDecoder(const ArrayDecoder&) = delete; + ArrayDecoder& operator=(const ArrayDecoder&) = delete; + + private: + CborParser parser_; + CborValue root_; + + CborValue it_; + CborError error_ = CborNoError; +}; + +class MapDecoder { + public: + static auto Create(uint8_t* buffer, size_t buffer_len) + -> cpp::result, CborError>; + + static auto Create(CborValue& root) + -> cpp::result, CborError>; + + MapDecoder() {} + + template + auto FindValue(const std::string& key) -> std::optional; + + template + auto FindValue(const std::string& key, + bool (*is_valid)(const CborValue*), + CborError (*parse)(const CborValue*, T*)) -> std::optional { + if (error_ != CborNoError) { + return {}; + } + CborValue val; + if (cbor_value_map_find_value(&it_, key.c_str(), &val) != CborNoError) { + return {}; + } + if (!is_valid(&val)) { + error_ = CborErrorIllegalType; + return {}; + } + T ret; + error_ = parse(&val, &ret); + if (error_ != CborNoError) { + return {}; + } + return ret; + } + + auto Failed() -> CborError { return error_; } + + MapDecoder(const MapDecoder&) = delete; + MapDecoder& operator=(const MapDecoder&) = delete; + + private: + CborParser parser_; + CborValue root_; + + CborValue it_; + CborError error_ = CborNoError; +}; + +} // namespace cbor diff --git a/src/cbor_wrapper/include/cbor_encoder.hpp b/src/cbor_wrapper/include/cbor_encoder.hpp new file mode 100644 index 00000000..cc57e8a4 --- /dev/null +++ b/src/cbor_wrapper/include/cbor_encoder.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include + +#include "cbor.h" +#include "result.hpp" + +namespace cbor { + +enum ContainerType { CONTAINER_ARRAY, CONTAINER_MAP }; + +class Encoder { + public: + Encoder(ContainerType type, + uint32_t container_len, + uint8_t* buffer, + size_t buffer_len); + + auto WriteValue(const std::string& val) -> void; + auto WriteValue(uint32_t val) -> void; + auto WriteValue(int32_t val) -> void; + + template + auto WriteKeyValue(const std::string& key, const T&& val) -> void { + WriteValue(key); + WriteValue(val); + } + + template + auto WriteKeyValue(const std::string& key, const std::optional& val) + -> void { + if (val) { + WriteKeyValue(key, val.value()); + } + } + + auto Finish() -> cpp::result; + + Encoder(const Encoder&) = delete; + Encoder& operator=(const Encoder&) = delete; + + private: + uint8_t* buffer_; + CborEncoder root_encoder_; + CborEncoder container_encoder_; + + CborError error_ = CborNoError; +}; + +} // namespace cbor -- cgit v1.2.3