mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-03 07:01:35 +08:00
Slightly optiimzed for size ScalarCodec
This commit is contained in:
@@ -19,18 +19,9 @@ class UAVCAN_EXPORT ScalarCodec
|
|||||||
{
|
{
|
||||||
BitStream& stream_;
|
BitStream& stream_;
|
||||||
|
|
||||||
template <int Size>
|
static void swapByteOrder(uint8_t* bytes, unsigned len);
|
||||||
static void swapByteOrder(uint8_t (&bytes)[Size])
|
|
||||||
{
|
|
||||||
for (int i = 0, j = Size - 1; i < j; i++, j--)
|
|
||||||
{
|
|
||||||
const uint8_t c = bytes[i];
|
|
||||||
bytes[i] = bytes[j];
|
|
||||||
bytes[j] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int BitLen, int Size>
|
template <unsigned BitLen, unsigned Size>
|
||||||
static typename EnableIf<(BitLen > 8)>::Type
|
static typename EnableIf<(BitLen > 8)>::Type
|
||||||
convertByteOrder(uint8_t (&bytes)[Size])
|
convertByteOrder(uint8_t (&bytes)[Size])
|
||||||
{
|
{
|
||||||
@@ -48,18 +39,15 @@ class UAVCAN_EXPORT ScalarCodec
|
|||||||
assert(big_endian == false);
|
assert(big_endian == false);
|
||||||
if (big_endian)
|
if (big_endian)
|
||||||
{
|
{
|
||||||
swapByteOrder(bytes);
|
swapByteOrder(bytes, Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int BitLen, int Size>
|
template <unsigned BitLen, unsigned Size>
|
||||||
static typename EnableIf<(BitLen <= 8)>::Type
|
static typename EnableIf<(BitLen <= 8)>::Type
|
||||||
convertByteOrder(uint8_t (&bytes)[Size])
|
convertByteOrder(uint8_t (&)[Size]) { }
|
||||||
{
|
|
||||||
(void)bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int BitLen, typename T>
|
template <unsigned BitLen, typename T>
|
||||||
static typename EnableIf<std::numeric_limits<T>::is_signed && ((sizeof(T) * 8) > BitLen)>::Type
|
static typename EnableIf<std::numeric_limits<T>::is_signed && ((sizeof(T) * 8) > BitLen)>::Type
|
||||||
fixTwosComplement(T& value)
|
fixTwosComplement(T& value)
|
||||||
{
|
{
|
||||||
@@ -70,28 +58,22 @@ class UAVCAN_EXPORT ScalarCodec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int BitLen, typename T>
|
template <unsigned BitLen, typename T>
|
||||||
static typename EnableIf<!std::numeric_limits<T>::is_signed || ((sizeof(T) * 8) == BitLen)>::Type
|
static typename EnableIf<!std::numeric_limits<T>::is_signed || ((sizeof(T) * 8) == BitLen)>::Type
|
||||||
fixTwosComplement(T& value)
|
fixTwosComplement(T&) { }
|
||||||
{
|
|
||||||
(void)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int BitLen, typename T>
|
template <unsigned BitLen, typename T>
|
||||||
static typename EnableIf<((sizeof(T) * 8) > BitLen)>::Type
|
static typename EnableIf<((sizeof(T) * 8) > BitLen)>::Type
|
||||||
clearExtraBits(T& value)
|
clearExtraBits(T& value)
|
||||||
{
|
{
|
||||||
value &= (T(1) << BitLen) - 1; // Signedness doesn't matter
|
value &= (T(1) << BitLen) - 1; // Signedness doesn't matter
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int BitLen, typename T>
|
template <unsigned BitLen, typename T>
|
||||||
static typename EnableIf<((sizeof(T) * 8) == BitLen)>::Type
|
static typename EnableIf<((sizeof(T) * 8) == BitLen)>::Type
|
||||||
clearExtraBits(T& value)
|
clearExtraBits(T&) { }
|
||||||
{
|
|
||||||
(void)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int BitLen, typename T>
|
template <unsigned BitLen, typename T>
|
||||||
void validate()
|
void validate()
|
||||||
{
|
{
|
||||||
StaticAssert<((sizeof(T) * 8) >= BitLen)>::check();
|
StaticAssert<((sizeof(T) * 8) >= BitLen)>::check();
|
||||||
@@ -99,12 +81,15 @@ class UAVCAN_EXPORT ScalarCodec
|
|||||||
StaticAssert<std::numeric_limits<T>::is_signed ? (BitLen > 1) : 1>::check();
|
StaticAssert<std::numeric_limits<T>::is_signed ? (BitLen > 1) : 1>::check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int encodeBytesImpl(uint8_t* bytes, unsigned bitlen);
|
||||||
|
int decodeBytesImpl(uint8_t* bytes, unsigned bitlen);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScalarCodec(BitStream& stream)
|
ScalarCodec(BitStream& stream)
|
||||||
: stream_(stream)
|
: stream_(stream)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <int BitLen, typename T>
|
template <unsigned BitLen, typename T>
|
||||||
int encode(const T value)
|
int encode(const T value)
|
||||||
{
|
{
|
||||||
validate<BitLen, T>();
|
validate<BitLen, T>();
|
||||||
@@ -116,15 +101,10 @@ public:
|
|||||||
byte_union.value = value;
|
byte_union.value = value;
|
||||||
clearExtraBits<BitLen>(byte_union.value);
|
clearExtraBits<BitLen>(byte_union.value);
|
||||||
convertByteOrder<BitLen>(byte_union.bytes);
|
convertByteOrder<BitLen>(byte_union.bytes);
|
||||||
// Underlying stream class assumes that more significant bits have lower index, so we need to shift some.
|
return encodeBytesImpl(byte_union.bytes, BitLen);
|
||||||
if (BitLen % 8)
|
|
||||||
{
|
|
||||||
byte_union.bytes[BitLen / 8] <<= (8 - (BitLen % 8)) & 7;
|
|
||||||
}
|
|
||||||
return stream_.write(byte_union.bytes, BitLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int BitLen, typename T>
|
template <unsigned BitLen, typename T>
|
||||||
int decode(T& value)
|
int decode(T& value)
|
||||||
{
|
{
|
||||||
validate<BitLen, T>();
|
validate<BitLen, T>();
|
||||||
@@ -133,20 +113,14 @@ public:
|
|||||||
T value;
|
T value;
|
||||||
uint8_t bytes[sizeof(T)];
|
uint8_t bytes[sizeof(T)];
|
||||||
} byte_union;
|
} byte_union;
|
||||||
std::fill(byte_union.bytes, byte_union.bytes + sizeof(T), 0);
|
byte_union.value = T();
|
||||||
|
const int read_res = decodeBytesImpl(byte_union.bytes, BitLen);
|
||||||
const int read_res = stream_.read(byte_union.bytes, BitLen);
|
if (read_res > 0)
|
||||||
if (read_res <= 0)
|
|
||||||
{
|
{
|
||||||
return read_res;
|
convertByteOrder<BitLen>(byte_union.bytes);
|
||||||
|
fixTwosComplement<BitLen>(byte_union.value);
|
||||||
|
value = byte_union.value;
|
||||||
}
|
}
|
||||||
if (BitLen % 8)
|
|
||||||
{
|
|
||||||
byte_union.bytes[BitLen / 8] >>= (8 - (BitLen % 8)) & 7; // As in encode(), vice versa
|
|
||||||
}
|
|
||||||
convertByteOrder<BitLen>(byte_union.bytes);
|
|
||||||
fixTwosComplement<BitLen>(byte_union.value);
|
|
||||||
value = byte_union.value;
|
|
||||||
return read_res;
|
return read_res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <uavcan/marshal/scalar_codec.hpp>
|
||||||
|
|
||||||
|
namespace uavcan
|
||||||
|
{
|
||||||
|
|
||||||
|
void ScalarCodec::swapByteOrder(uint8_t* const bytes, const unsigned len)
|
||||||
|
{
|
||||||
|
for (int i = 0, j = len - 1; i < j; i++, j--)
|
||||||
|
{
|
||||||
|
const uint8_t c = bytes[i];
|
||||||
|
bytes[i] = bytes[j];
|
||||||
|
bytes[j] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScalarCodec::encodeBytesImpl(uint8_t* const bytes, const unsigned bitlen)
|
||||||
|
{
|
||||||
|
// Underlying stream class assumes that more significant bits have lower index, so we need to shift some.
|
||||||
|
if (bitlen % 8)
|
||||||
|
{
|
||||||
|
bytes[bitlen / 8] <<= (8 - (bitlen % 8)) & 7;
|
||||||
|
}
|
||||||
|
return stream_.write(bytes, bitlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScalarCodec::decodeBytesImpl(uint8_t* const bytes, const unsigned bitlen)
|
||||||
|
{
|
||||||
|
const int read_res = stream_.read(bytes, bitlen);
|
||||||
|
if (read_res > 0)
|
||||||
|
{
|
||||||
|
if (bitlen % 8)
|
||||||
|
{
|
||||||
|
bytes[bitlen / 8] >>= (8 - (bitlen % 8)) & 7; // As in encode(), vice versa
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return read_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user