Skip to content

Commit 7e61169

Browse files
implementing encoder interface
1 parent 3861bc2 commit 7e61169

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

src/cbor/CborEncoder.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include "CborEncoder.h"
2+
3+
CBORMessageEncoderClass& CBORMessageEncoder = CBORMessageEncoderClass::getInstance();
4+
5+
Encoder::Status CBORMessageEncoderClass::encode(Message* message, uint8_t * data, size_t& len) { // TODO do we need to propagate the maximum length?
6+
// prepare cbor structure
7+
CborEncoder encoder;
8+
9+
cbor_encoder_init(&encoder, data, len, 0);
10+
11+
auto encoder_it = encoders.find(message->id);
12+
13+
// check if message.id exists on the encoders list or return error
14+
if(encoder_it == encoders.end()) {
15+
return Encoder::Status::Error;
16+
}
17+
18+
// encode the message
19+
if(encoder_it->second->_encode(&encoder, message) == Encoder::Status::Error) {
20+
return Encoder::Status::Error;
21+
}
22+
23+
len = cbor_encoder_get_buffer_size(&encoder, data);
24+
25+
return Encoder::Status::Complete;
26+
}
27+
28+
CBORMessageEncoderInterface::CBORMessageEncoderInterface(const CBORTag tag, const MessageId id)
29+
: tag(tag), id(id) {
30+
// call singleton/global variable and insert this encoder
31+
CBORMessageEncoderClass::getInstance().append(id, this);
32+
}
33+
34+
Encoder::Status CBORMessageEncoderInterface::_encode(CborEncoder* encoder, Message *msg) {
35+
// this must always be true, it could mean that there are issues in the map of encoders
36+
assert(msg->id == id);
37+
38+
if (tag == cbor::tag::CBORUnknownCmdTag16b ||
39+
tag == cbor::tag::CBORUnknownCmdTag32b ||
40+
tag == cbor::tag::CBORUnknownCmdTag64b ||
41+
cbor_encode_tag(encoder, tag) != CborNoError) {
42+
return Encoder::Status::Error;
43+
}
44+
45+
return this->encode(encoder, msg);
46+
}

src/cbor/CborEncoder.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#pragma once
2+
3+
#include <map>
4+
#include "../interfaces/Encoder.h"
5+
#include "CBOR.h"
6+
#include "../interfaces/message.h"
7+
#include "./tinycbor/cbor-lib.h"
8+
9+
class CBORMessageEncoderClass;
10+
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 CBORMessageEncoderInterface {
18+
public:
19+
CBORMessageEncoderInterface(const CBORTag tag, const MessageId id);
20+
virtual ~CBORMessageEncoderInterface() {}
21+
22+
protected:
23+
virtual Encoder::Status encode(CborEncoder* encoder, Message *msg) = 0;
24+
25+
private:
26+
const CBORTag tag;
27+
const MessageId id;
28+
29+
friend CBORMessageEncoderClass;
30+
31+
// wrapper for encode function that for the time being only writes the tag in the buffer
32+
Encoder::Status _encode(CborEncoder* encoder, Message *msg);
33+
};
34+
35+
// TODO make a private constructor?
36+
class CBORMessageEncoderClass: public Encoder {
37+
public:
38+
static CBORMessageEncoderClass& getInstance() {
39+
static CBORMessageEncoderClass singleton;
40+
41+
return singleton;
42+
}
43+
44+
void append(CBORTag id, CBORMessageEncoderInterface* encoder) {
45+
// auto pair = encoders.try_emplace(id, encoder);
46+
encoders[id] = encoder;
47+
}
48+
49+
Encoder::Status encode(Message* message, uint8_t * data, size_t& len);
50+
private:
51+
std::map<MessageId, CBORMessageEncoderInterface*> encoders;
52+
};
53+
54+
extern CBORMessageEncoderClass& CBORMessageEncoder;

0 commit comments

Comments
 (0)