summaryrefslogtreecommitdiff
path: root/src/cbor/cbor_decoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cbor/cbor_decoder.cpp')
-rw-r--r--src/cbor/cbor_decoder.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/cbor/cbor_decoder.cpp b/src/cbor/cbor_decoder.cpp
new file mode 100644
index 00000000..eb43e163
--- /dev/null
+++ b/src/cbor/cbor_decoder.cpp
@@ -0,0 +1,158 @@
+#include "cbor_decoder.hpp"
+#include <cstdint>
+#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<std::unique_ptr<ArrayDecoder>, CborError> {
+ auto decoder = std::make_unique<ArrayDecoder>();
+ 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<std::string, CborError> {
+ 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<uint32_t, CborError> {
+ 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<int32_t, CborError> {
+ 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<std::unique_ptr<MapDecoder>, CborError> {
+ auto decoder = std::make_unique<MapDecoder>();
+ 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<std::string> {
+ 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<uint32_t> {
+ 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<int32_t> {
+ 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