Skip to content

Commit acfbed2

Browse files
implementing decoder interface
1 parent 7e61169 commit acfbed2

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

src/cbor/CborDecoder.cpp

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include "CborDecoder.h"
2+
3+
CBORMessageDecoderClass& CBORMessageDecoder = CBORMessageDecoderClass::getInstance();
4+
5+
Decoder::Status CBORMessageDecoderClass::decode(Message* msg, const uint8_t* const buf, size_t &len) { // TODO do we need to propagate the maximum length?
6+
// prepare cbor structure
7+
CborValue iter;
8+
CborTag tag;
9+
CborParser parser;
10+
11+
if (cbor_parser_init(buf, len, 0, &parser, &iter) != CborNoError) {
12+
return Decoder::Status::Error;
13+
}
14+
15+
if (iter.type != CborTagType) {
16+
return Decoder::Status::Error;
17+
}
18+
19+
if (cbor_value_get_tag(&iter, &tag) != CborNoError) {
20+
return Decoder::Status::Error;
21+
}
22+
23+
if (cbor_value_advance(&iter) != CborNoError) {
24+
return Decoder::Status::Error;
25+
}
26+
27+
auto decoder_it = decoders.find(tag);
28+
29+
// check if message.id exists on the decoders list or return error
30+
if(decoder_it == decoders.end()) {
31+
return Decoder::Status::Error;
32+
}
33+
34+
// encode the message
35+
if(decoder_it->second->_decode(&iter, msg) == Decoder::Status::Error) {
36+
return Decoder::Status::Error;
37+
}
38+
39+
return Decoder::Status::Complete;
40+
}
41+
42+
CBORMessageDecoderInterface::CBORMessageDecoderInterface(const CBORTag tag, const MessageId id)
43+
: tag(tag), id(id) {
44+
// call singleton/global variable and insert this encoder
45+
CBORMessageDecoderClass::getInstance().append(tag, this);
46+
}
47+
48+
Decoder::Status CBORMessageDecoderInterface::_decode(CborValue* iter, Message *msg) {
49+
CborValue array_iter;
50+
msg->id = this->id;
51+
52+
if (cbor_value_get_type(iter) != CborArrayType) {
53+
return Decoder::Status::Error;
54+
}
55+
56+
if (cbor_value_enter_container(iter, &array_iter) != CborNoError) {
57+
return Decoder::Status::Error;
58+
}
59+
60+
return decode(&array_iter, msg);
61+
}

src/cbor/CborDecoder.h

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#pragma once
2+
#pragma once
3+
4+
#include <map>
5+
#include "../interfaces/Decoder.h"
6+
#include "CBOR.h"
7+
#include "../interfaces/message.h"
8+
#include "./tinycbor/cbor-lib.h"
9+
10+
class CBORMessageDecoderClass;
11+
12+
// TODO find a better name
13+
// TODO maybe a template<CBORTag tag, MessageId id> ?
14+
// TODO maybe template<resultStruct> that is also the parameter of encode
15+
// TODO in order to make this more extensible we should not pass Message* as a parameter, templated function may be better (or void*)
16+
// providing both id and tag gives the ability to convert and avoid using a conversion function
17+
class CBORMessageDecoderInterface {
18+
public:
19+
CBORMessageDecoderInterface(const CBORTag tag, const MessageId id);
20+
virtual ~CBORMessageDecoderInterface() {}
21+
22+
protected:
23+
virtual Decoder::Status decode(CborValue* iter, Message *msg) = 0;
24+
25+
private:
26+
const CBORTag tag;
27+
const MessageId id;
28+
29+
friend CBORMessageDecoderClass;
30+
31+
// wrapper for encode function that for the time being only writes the tag in the buffer
32+
Decoder::Status _decode(CborValue* iter, Message *msg);
33+
};
34+
35+
// TODO make a private constructor?
36+
class CBORMessageDecoderClass: public Decoder {
37+
public:
38+
static CBORMessageDecoderClass& getInstance() {
39+
static CBORMessageDecoderClass singleton;
40+
41+
return singleton;
42+
}
43+
44+
45+
void append(CBORTag id, CBORMessageDecoderInterface* encoder) {
46+
decoders[id] = encoder;
47+
}
48+
49+
Decoder::Status decode(Message* msg, const uint8_t* const buf, size_t &len);
50+
private:
51+
std::map<CBORTag, CBORMessageDecoderInterface*> decoders;
52+
};
53+
54+
extern CBORMessageDecoderClass& CBORMessageDecoder;

0 commit comments

Comments
 (0)