cmvr_head/packages/erpc-1.14.0/erpc_c/infra/erpc_basic_codec.cpp

387 lines
7.4 KiB
C++
Raw Normal View History

2025-12-30 15:44:41 +08:00
/*
* 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)
}