Skip to content

Commit f90494a

Browse files
implementing encoder interface
1 parent 6dd1bd7 commit f90494a

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

src/cbor/CborEncoder.cpp

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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 "CborEncoder.h"
11+
12+
// static CBORMessageEncoderSingleton* singleton = nullptr;
13+
14+
Encoder::Status CBORMessageEncoderSingleton::encode(Message* message, uint8_t * data, size_t& len) { // TODO do we need to propagate the maximum length?
15+
// prepare cbor structure
16+
CborEncoder encoder;
17+
18+
cbor_encoder_init(&encoder, data, len, 0);
19+
20+
auto encoder_it = encoders.find(message->id);
21+
22+
// check if message.id exists on the encoders list or return error
23+
if(encoder_it == encoders.end()) {
24+
return Encoder::Status::Error;
25+
}
26+
27+
// encode the message
28+
if(encoder_it->second->_encode(&encoder, message) == Encoder::Status::Error) {
29+
return Encoder::Status::Error;
30+
}
31+
32+
len = cbor_encoder_get_buffer_size(&encoder, data);
33+
34+
return Encoder::Status::Complete;
35+
}
36+
37+
CBORMessageEncoderSingleton& CBORMessageEncoderSingleton::getInstance() {
38+
static CBORMessageEncoderSingleton singleton;
39+
40+
return singleton;
41+
}
42+
43+
CBORMessageEncoderInterface::CBORMessageEncoderInterface(const CBORTag tag, const MessageId id)
44+
: tag(tag), id(id) {
45+
// call singleton/global variable and insert this encoder
46+
CBORMessageEncoderSingleton::getInstance().append(id, this);
47+
}
48+
49+
Encoder::Status CBORMessageEncoderInterface::_encode(CborEncoder* encoder, Message *msg) {
50+
// this must always be true, it could mean that there are issues in the map of encoders
51+
assert(msg->id == id);
52+
53+
if (tag == cbor::tag::CBORUnknownCmdTag16b ||
54+
tag == cbor::tag::CBORUnknownCmdTag32b ||
55+
tag == cbor::tag::CBORUnknownCmdTag64b ||
56+
cbor_encode_tag(encoder, tag) != CborNoError) {
57+
return Encoder::Status::Error;
58+
}
59+
60+
return this->encode(encoder, msg);
61+
}

src/cbor/CborEncoder.h

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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/Encoder.h"
14+
#include "CBOR.h"
15+
#include "../interfaces/message.h"
16+
#include "./tinycbor/cbor-lib.h"
17+
18+
class CBORMessageEncoderSingleton;
19+
20+
21+
// TODO find a better name
22+
// TODO maybe a template<CBORTag tag, MessageId id> ?
23+
// TODO maybe template<resultStruct> that is also the parameter of encode
24+
// TODO in order to make this more extensible we should not pass Message* as a parameter, templated function may be better (or void*)
25+
class CBORMessageEncoderInterface {
26+
public:
27+
CBORMessageEncoderInterface(const CBORTag tag, const MessageId id);
28+
virtual ~CBORMessageEncoderInterface() {}
29+
30+
protected:
31+
virtual Encoder::Status encode(CborEncoder* encoder, Message *msg) = 0;
32+
33+
private:
34+
const CBORTag tag;
35+
const MessageId id;
36+
37+
friend CBORMessageEncoderSingleton;
38+
39+
// wrapper for encode function that for the time being only writes the tag in the buffer
40+
Encoder::Status _encode(CborEncoder* encoder, Message *msg);
41+
};
42+
43+
class CBORMessageEncoderSingleton: public Encoder {
44+
public:
45+
static CBORMessageEncoderSingleton& getInstance();
46+
47+
void append(CBORTag id, CBORMessageEncoderInterface* encoder) {
48+
encoders[id] = encoder;
49+
}
50+
51+
Encoder::Status encode(Message* message, uint8_t * data, size_t& len);
52+
private:
53+
CBORMessageEncoderSingleton() {}
54+
55+
static CBORMessageEncoderSingleton singleton;
56+
std::map<MessageId, CBORMessageEncoderInterface*> encoders;
57+
};
58+
59+
class CBORMessageEncoder: public Encoder {
60+
public:
61+
inline Encoder::Status encode(Message* msg, uint8_t* buf, size_t &len) {
62+
return CBORMessageEncoderSingleton::getInstance().encode(msg, buf, len);
63+
}
64+
};

0 commit comments

Comments
 (0)