diff options
| author | jacqueline <me@jacqueline.id.au> | 2022-11-22 23:10:42 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2022-11-22 23:10:42 +1100 |
| commit | dfa9ab6e04689b99267092e016a91d9254f94cd8 (patch) | |
| tree | 6f33f8d0d099fb85efa746e041e836f4505371ee /src/cbor/include/cbor_decoder.hpp | |
| parent | 9176ef187227ffb56c249c5f321cd1bf50d4cfcc (diff) | |
| download | tangara-fw-dfa9ab6e04689b99267092e016a91d9254f94cd8.tar.gz | |
template-ify the cbor stuff
Diffstat (limited to 'src/cbor/include/cbor_decoder.hpp')
| -rw-r--r-- | src/cbor/include/cbor_decoder.hpp | 92 |
1 files changed, 85 insertions, 7 deletions
diff --git a/src/cbor/include/cbor_decoder.hpp b/src/cbor/include/cbor_decoder.hpp index 249db9cc..39151ca8 100644 --- a/src/cbor/include/cbor_decoder.hpp +++ b/src/cbor/include/cbor_decoder.hpp @@ -1,15 +1,61 @@ #pragma once +#include <stdint.h> #include <cstdint> + namespace cbor { + static auto parse_stdstring(CborValue *val, std::string *out) -> CborError { + uint8_t *buf; size_t len; + CborError err = cbor_value_dup_byte_string(val, &buf, &len, NULL); + if (err != CborNoError) { + return err; + } + *out = std::move(std::string(buf, len)); + free(buf); + return err + } + class ArrayDecoder { public: - static auto Create(uint8_t *buffer, size_t buffer_len) -> cpp::result<std::unique_ptr<ArrayDecoder>, CborError>; + static auto Create(uint8_t *buffer, size_t buffer_len) + -> cpp::result<std::unique_ptr<ArrayDecoder>, CborError>; + + template<typename T> + auto NextValue() -> cpp::result<T, CborError>; - auto ParseString() -> cpp::result<std::string, CborError>; - auto ParseUnsigned() -> cpp::result<uint32_t, CborError>; - auto ParseSigned() -> cpp::result<int32_t, CborError>; + template<> auto NextValue() -> cpp::result<int64_t, CborError> { + return NextValue(&cbor_value_is_integer, &cbor_value_get_int); + } + template<> auto NextValue() -> cpp::result<uint64_t, CborError> { + return NextValue(&cbor_value_is_unsigned_integer, &cbor_value_get_uint64); + } + template<> auto NextValue() -> cpp::result<std::string, CborError> { + return NextValue(&cbor_value_is_byte_string, &parse_stdstring); + } + + template <typename T> + auto NextValue( + bool(*is_valid)(CborValue*), + CborError(*parse)(CborValue*, T*)) -> cpp::result<T, CborError> { + 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_; } @@ -27,9 +73,41 @@ namespace cbor { public: static auto Create(uint8_t *buffer, size_t buffer_len) -> cpp::result<std::unique_ptr<MapDecoder>, CborError>; - auto FindString(const std::string &key) -> std::optional<std::string>; - auto FindUnsigned(const std::string &key) -> std::optional<uint32_t>; - auto FindSigned(const std::string &key) -> std::optional<int32_t>; + template<typename T> + auto FindValue(const std::string &key) -> std::optional<T>; + + template<> auto FindValue(const std::string &key) -> std::optional<int64_t> { + return FindValue(key, &cbor_value_is_integer, &cbor_value_get_int); + } + template<> auto FindValue(const std::string &key) -> std::optional<uint64_t> { + return FindValue(key, &cbor_value_is_unsigned_integer, &cbor_value_get_uint64); + } + template<> auto FindValue(const std::string &key) -> std::optional<std::string> { + return FindValue(key, &cbor_value_is_byte_string, &parse_stdstring); + } + + template <typename T> + auto FindValue( + const std::string &key, + bool(*is_valid)(CborValue*), + CborError(*parse)(CborValue*, T*)) -> std::optional<T> { + if (error_ != CborNoError) { + return {}; + } + 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 cpp::fail(error_); + } + return ret; + } auto Failed() -> CborError { return error_; } |
