summaryrefslogtreecommitdiff
path: root/src/cbor/include/cbor_decoder.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cbor/include/cbor_decoder.hpp')
-rw-r--r--src/cbor/include/cbor_decoder.hpp92
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_; }