diff options
| author | jacqueline <me@jacqueline.id.au> | 2022-12-02 13:39:00 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2022-12-02 13:39:00 +1100 |
| commit | 222c810b07ffc635fc7908d121e97e4d65ccc5c8 (patch) | |
| tree | 91c7b5c72a11770ebf3695bf0c234597b2bc419d /src/cbor_wrapper/cbor_decoder.cpp | |
| parent | 71a4f5166f5491dc0982a18d62c63e28b3a52faa (diff) | |
| download | tangara-fw-222c810b07ffc635fc7908d121e97e4d65ccc5c8.tar.gz | |
fix build errors
Diffstat (limited to 'src/cbor_wrapper/cbor_decoder.cpp')
| -rw-r--r-- | src/cbor_wrapper/cbor_decoder.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
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 <cstdint> +#include <string> + +#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<std::unique_ptr<ArrayDecoder>, CborError> { + auto decoder = std::make_unique<ArrayDecoder>(); + 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<std::unique_ptr<ArrayDecoder>, CborError> { + auto decoder = std::make_unique<ArrayDecoder>(); + 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<int64_t, CborError> { + return NextValue(&cbor_value_is_integer, &cbor_value_get_int); +} +template <> +auto ArrayDecoder::NextValue() -> cpp::result<uint64_t, CborError> { + return NextValue(&cbor_value_is_unsigned_integer, &cbor_value_get_uint64); +} +template <> +auto ArrayDecoder::NextValue() -> cpp::result<std::string, CborError> { + return NextValue(&cbor_value_is_byte_string, &parse_stdstring); +} + +auto MapDecoder::Create(uint8_t* buffer, size_t buffer_len) + -> cpp::result<std::unique_ptr<MapDecoder>, CborError> { + auto decoder = std::make_unique<MapDecoder>(); + 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<std::unique_ptr<MapDecoder>, CborError> { + auto decoder = std::make_unique<MapDecoder>(); + 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<int64_t> { + return FindValue(key, &cbor_value_is_integer, &cbor_value_get_int); +} +template <> +auto MapDecoder::FindValue(const std::string& key) -> std::optional<uint64_t> { + return FindValue(key, &cbor_value_is_unsigned_integer, + &cbor_value_get_uint64); +} +template <> +auto MapDecoder::FindValue(const std::string& key) + -> std::optional<std::string> { + return FindValue(key, &cbor_value_is_byte_string, &parse_stdstring); +} + +} // namespace cbor |
