Skip to content

Commit 8edc716

Browse files
implementing decoder interface
1 parent f90494a commit 8edc716

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

src/cbor/CborDecoder.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
This file is part of the Arduino_CloudUtils library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
#include "CborDecoder.h"
11+
12+
Decoder::Status CBORMessageDecoderSingleton::decode(Message* msg, const uint8_t* const buf, size_t &len) { // TODO do we need to propagate the maximum length?
13+
// prepare cbor structure
14+
CborValue iter;
15+
CborTag tag;
16+
CborParser parser;
17+
18+
if (cbor_parser_init(buf, len, 0, &parser, &iter) != CborNoError) {
19+
return Decoder::Status::Error;
20+
}
21+
22+
if (iter.type != CborTagType) {
23+
return Decoder::Status::Error;
24+
}
25+
26+
if (cbor_value_get_tag(&iter, &tag) != CborNoError) {
27+
return Decoder::Status::Error;
28+
}
29+
30+
if (cbor_value_advance(&iter) != CborNoError) {
31+
return Decoder::Status::Error;
32+
}
33+
34+
auto decoder_it = decoders.find(tag);
35+
36+
// check if message.id exists on the decoders list or return error
37+
if(decoder_it == decoders.end()) {
38+
return Decoder::Status::Error;
39+
}
40+
41+
// encode the message
42+
if(decoder_it->second->_decode(&iter, msg) == Decoder::Status::Error) {
43+
return Decoder::Status::Error;
44+
}
45+
46+
return Decoder::Status::Complete;
47+
}
48+
49+
CBORMessageDecoderSingleton& CBORMessageDecoderSingleton::getInstance() {
50+
static CBORMessageDecoderSingleton singleton;
51+
52+
return singleton;
53+
}
54+
55+
CBORMessageDecoderInterface::CBORMessageDecoderInterface(const CBORTag tag, const MessageId id)
56+
: tag(tag), id(id) {
57+
// call singleton/global variable and insert this encoder
58+
CBORMessageDecoderSingleton::getInstance().append(tag, this);
59+
}
60+
61+
Decoder::Status CBORMessageDecoderInterface::_decode(CborValue* iter, Message *msg) {
62+
CborValue array_iter;
63+
msg->id = this->id;
64+
65+
if (cbor_value_get_type(iter) != CborArrayType) {
66+
return Decoder::Status::Error;
67+
}
68+
69+
if (cbor_value_enter_container(iter, &array_iter) != CborNoError) {
70+
return Decoder::Status::Error;
71+
}
72+
73+
return decode(&array_iter, msg);
74+
}

src/cbor/CborDecoder.h

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
This file is part of the Arduino_CloudUtils library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
#pragma once
11+
12+
#include <map>
13+
#include "../interfaces/Decoder.h"
14+
#include "CBOR.h"
15+
#include "../interfaces/message.h"
16+
#include "./tinycbor/cbor-lib.h"
17+
18+
class CBORMessageDecoderSingleton;
19+
20+
// TODO find a better name
21+
// TODO maybe a template<CBORTag tag, MessageId id> ?
22+
// TODO maybe template<resultStruct> that is also the parameter of encode
23+
// TODO in order to make this more extensible we should not pass Message* as a parameter, templated function may be better (or void*)
24+
class CBORMessageDecoderInterface {
25+
public:
26+
CBORMessageDecoderInterface(const CBORTag tag, const MessageId id);
27+
virtual ~CBORMessageDecoderInterface() {}
28+
29+
protected:
30+
virtual Decoder::Status decode(CborValue* iter, Message *msg) = 0;
31+
32+
private:
33+
const CBORTag tag;
34+
const MessageId id;
35+
36+
friend CBORMessageDecoderSingleton;
37+
38+
// wrapper for encode function that for the time being only writes the tag in the buffer
39+
Decoder::Status _decode(CborValue* iter, Message *msg);
40+
};
41+
42+
class CBORMessageDecoderSingleton: public Decoder {
43+
public:
44+
static CBORMessageDecoderSingleton& getInstance();
45+
46+
void append(CBORTag id, CBORMessageDecoderInterface* encoder) {
47+
decoders[id] = encoder;
48+
}
49+
50+
Decoder::Status decode(Message* msg, const uint8_t* const buf, size_t &len);
51+
private:
52+
CBORMessageDecoderSingleton() {}
53+
54+
static CBORMessageDecoderSingleton singleton;
55+
std::map<CBORTag, CBORMessageDecoderInterface*> decoders;
56+
};
57+
58+
class CBORMessageDecoder: public Decoder {
59+
public:
60+
inline Decoder::Status decode(Message* msg, const uint8_t* const buf, size_t &len) {
61+
return CBORMessageDecoderSingleton::getInstance().decode(msg, buf, len);
62+
}
63+
};

0 commit comments

Comments
 (0)