387 lines
7.4 KiB
C++
387 lines
7.4 KiB
C++
/*
|
|
* Copyright (c) 2014, Freescale Semiconductor, Inc.
|
|
* Copyright 2016-2021 NXP
|
|
* Copyright 2021 ACRIOS Systems s.r.o.
|
|
* All rights reserved.
|
|
*
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "erpc_basic_codec.hpp"
|
|
|
|
#include "erpc_config_internal.h"
|
|
#include ENDIANNESS_HEADER
|
|
#include "erpc_manually_constructed.hpp"
|
|
|
|
#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
|
|
#include <new>
|
|
#endif
|
|
#include <cassert>
|
|
|
|
using namespace erpc;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Code
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
const uint32_t BasicCodec::kBasicCodecVersion = 1UL;
|
|
|
|
BasicCodec::BasicCodec(void) : Codec() {}
|
|
|
|
BasicCodec::~BasicCodec(void) {}
|
|
|
|
void BasicCodec::startWriteMessage(message_type_t type, uint32_t service, uint32_t request, uint32_t sequence)
|
|
{
|
|
uint32_t header =
|
|
(kBasicCodecVersion << 24u) | ((service & 0xffu) << 16u) | ((request & 0xffu) << 8u) | ((uint32_t)type & 0xffu);
|
|
|
|
write(header);
|
|
|
|
write(sequence);
|
|
}
|
|
|
|
void BasicCodec::writeData(uint32_t length, const void *value)
|
|
{
|
|
if (isStatusOk())
|
|
{
|
|
m_status = m_cursor.write(value, length);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::write(bool value)
|
|
{
|
|
// Make sure the bool is a single byte.
|
|
uint8_t v = (uint8_t)value;
|
|
|
|
writeData(sizeof(v), &v);
|
|
}
|
|
|
|
void BasicCodec::write(int8_t value)
|
|
{
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::write(int16_t value)
|
|
{
|
|
ERPC_WRITE_AGNOSTIC_16(value);
|
|
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::write(int32_t value)
|
|
{
|
|
ERPC_WRITE_AGNOSTIC_32(value);
|
|
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::write(int64_t value)
|
|
{
|
|
ERPC_WRITE_AGNOSTIC_64(value);
|
|
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::write(uint8_t value)
|
|
{
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::write(uint16_t value)
|
|
{
|
|
ERPC_WRITE_AGNOSTIC_16(value);
|
|
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::write(uint32_t value)
|
|
{
|
|
ERPC_WRITE_AGNOSTIC_32(value);
|
|
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::write(uint64_t value)
|
|
{
|
|
ERPC_WRITE_AGNOSTIC_64(value);
|
|
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::write(float value)
|
|
{
|
|
ERPC_WRITE_AGNOSTIC_FLOAT(value);
|
|
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::write(double value)
|
|
{
|
|
ERPC_WRITE_AGNOSTIC_DOUBLE(value);
|
|
|
|
writeData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::writePtr(uintptr_t value)
|
|
{
|
|
uint8_t ptrSize = (uint8_t)sizeof(value);
|
|
|
|
write(ptrSize);
|
|
|
|
ERPC_WRITE_AGNOSTIC_PTR(value);
|
|
|
|
writeData(ptrSize, &value);
|
|
}
|
|
|
|
void BasicCodec::writeString(uint32_t length, const char *value)
|
|
{
|
|
// Just treat the string as binary.
|
|
writeBinary(length, reinterpret_cast<const uint8_t *>(value));
|
|
}
|
|
|
|
void BasicCodec::writeBinary(uint32_t length, const uint8_t *value)
|
|
{
|
|
// Write the blob length as a u32.
|
|
write(length);
|
|
|
|
writeData(length, value);
|
|
}
|
|
|
|
void BasicCodec::startWriteList(uint32_t length)
|
|
{
|
|
// Write the list length as a u32.
|
|
write(length);
|
|
}
|
|
|
|
void BasicCodec::startWriteUnion(int32_t discriminator)
|
|
{
|
|
// Write the union discriminator as a u32.
|
|
write(discriminator);
|
|
}
|
|
|
|
void BasicCodec::writeNullFlag(bool isNull)
|
|
{
|
|
write(static_cast<uint8_t>(isNull ? null_flag_t::kIsNull : null_flag_t::kNotNull));
|
|
}
|
|
|
|
void BasicCodec::startReadMessage(message_type_t &type, uint32_t &service, uint32_t &request, uint32_t &sequence)
|
|
{
|
|
uint32_t header;
|
|
|
|
read(header);
|
|
|
|
if (((header >> 24) & 0xffU) != kBasicCodecVersion)
|
|
{
|
|
updateStatus(kErpcStatus_InvalidMessageVersion);
|
|
}
|
|
|
|
if (isStatusOk())
|
|
{
|
|
service = ((header >> 16) & 0xffU);
|
|
request = ((header >> 8) & 0xffU);
|
|
type = static_cast<message_type_t>(header & 0xffU);
|
|
|
|
read(sequence);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::readData(uint32_t length, void *value)
|
|
{
|
|
if (isStatusOk())
|
|
{
|
|
m_status = m_cursor.read(value, length);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::read(bool &value)
|
|
{
|
|
uint8_t v = 0;
|
|
|
|
readData(sizeof(v), &v);
|
|
if (isStatusOk())
|
|
{
|
|
value = (bool)v;
|
|
}
|
|
}
|
|
|
|
void BasicCodec::read(int8_t &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::read(int16_t &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
if (isStatusOk())
|
|
{
|
|
ERPC_READ_AGNOSTIC_16(*value);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::read(int32_t &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
if (isStatusOk())
|
|
{
|
|
ERPC_READ_AGNOSTIC_32(*value);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::read(int64_t &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
if (isStatusOk())
|
|
{
|
|
ERPC_READ_AGNOSTIC_64(*value);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::read(uint8_t &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
}
|
|
|
|
void BasicCodec::read(uint16_t &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
if (isStatusOk())
|
|
{
|
|
ERPC_READ_AGNOSTIC_16(*value);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::read(uint32_t &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
if (isStatusOk())
|
|
{
|
|
ERPC_READ_AGNOSTIC_32(*value);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::read(uint64_t &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
if (isStatusOk())
|
|
{
|
|
ERPC_READ_AGNOSTIC_64(*value);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::read(float &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
if (isStatusOk())
|
|
{
|
|
ERPC_READ_AGNOSTIC_FLOAT(*value);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::read(double &value)
|
|
{
|
|
readData(sizeof(value), &value);
|
|
if (isStatusOk())
|
|
{
|
|
ERPC_READ_AGNOSTIC_DOUBLE(*value);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::readPtr(uintptr_t &value)
|
|
{
|
|
uint8_t ptrSize;
|
|
|
|
read(ptrSize);
|
|
|
|
if (ptrSize > sizeof(value))
|
|
{
|
|
updateStatus(kErpcStatus_BadAddressScale);
|
|
}
|
|
|
|
readData(ptrSize, &value);
|
|
if (isStatusOk())
|
|
{
|
|
ERPC_READ_AGNOSTIC_PTR(*value);
|
|
}
|
|
}
|
|
|
|
void BasicCodec::readString(uint32_t &length, char **value)
|
|
{
|
|
readBinary(length, reinterpret_cast<uint8_t **>(value));
|
|
}
|
|
|
|
void BasicCodec::readBinary(uint32_t &length, uint8_t **value)
|
|
{
|
|
// Read length first as u32.
|
|
read(length);
|
|
|
|
if (isStatusOk())
|
|
{
|
|
if (m_cursor.getRemainingUsed() < length)
|
|
{
|
|
m_status = kErpcStatus_Fail;
|
|
}
|
|
else if (m_cursor.getRemaining() < length)
|
|
{
|
|
m_status = kErpcStatus_BufferOverrun;
|
|
}
|
|
else
|
|
{
|
|
// Return current pointer into buffer.
|
|
*value = m_cursor.get();
|
|
|
|
// Skip over data.
|
|
m_cursor += (uint16_t)length;
|
|
}
|
|
}
|
|
if (!isStatusOk())
|
|
{
|
|
length = 0;
|
|
*value = NULL;
|
|
}
|
|
}
|
|
|
|
void BasicCodec::startReadList(uint32_t &length)
|
|
{
|
|
// Read list length as u32.
|
|
read(length);
|
|
|
|
if (!isStatusOk())
|
|
{
|
|
length = 0;
|
|
}
|
|
}
|
|
|
|
void BasicCodec::startReadUnion(int32_t &discriminator)
|
|
{
|
|
// Read union discriminator as u32.
|
|
read(discriminator);
|
|
}
|
|
|
|
void BasicCodec::readNullFlag(bool &isNull)
|
|
{
|
|
uint8_t flag;
|
|
|
|
read(flag);
|
|
if (isStatusOk())
|
|
{
|
|
isNull = (flag == static_cast<uint8_t>(null_flag_t::kIsNull));
|
|
}
|
|
}
|
|
|
|
ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(BasicCodec, s_basicCodecManual, ERPC_CODEC_COUNT);
|
|
|
|
BasicCodecFactory::BasicCodecFactory(void) : CodecFactory() {}
|
|
|
|
BasicCodecFactory::~BasicCodecFactory(void) {}
|
|
|
|
Codec *BasicCodecFactory::create(void)
|
|
{
|
|
ERPC_CREATE_NEW_OBJECT(BasicCodec, s_basicCodecManual, ERPC_CODEC_COUNT)
|
|
}
|
|
|
|
void BasicCodecFactory::dispose(Codec *codec)
|
|
{
|
|
ERPC_DESTROY_OBJECT(codec, s_basicCodecManual, ERPC_CODEC_COUNT)
|
|
}
|