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