scalar_codec.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_MARSHAL_SCALAR_CODEC_HPP_INCLUDED
6 #define UAVCAN_MARSHAL_SCALAR_CODEC_HPP_INCLUDED
7 
8 #include <cassert>
9 #include <uavcan/std.hpp>
10 #include <uavcan/build_config.hpp>
13 
14 namespace uavcan
15 {
21 {
23 
24  static void swapByteOrder(uint8_t* bytes, unsigned len);
25 
26  template <unsigned BitLen, unsigned Size>
27  static typename EnableIf<(BitLen > 8)>::Type
28  convertByteOrder(uint8_t (&bytes)[Size])
29  {
30 #if defined(BYTE_ORDER) && defined(BIG_ENDIAN)
31  static const bool big_endian = BYTE_ORDER == BIG_ENDIAN;
32 #else
33  union { long int l; char c[sizeof(long int)]; } u;
34  u.l = 1;
35  const bool big_endian = u.c[sizeof(long int) - 1] == 1;
36 #endif
37  if (big_endian)
38  {
39  swapByteOrder(bytes, Size);
40  }
41  }
42 
43  template <unsigned BitLen, unsigned Size>
44  static typename EnableIf<(BitLen <= 8)>::Type
45  convertByteOrder(uint8_t (&)[Size]) { }
46 
47  template <unsigned BitLen, typename T>
48  static typename EnableIf<static_cast<bool>(NumericTraits<T>::IsSigned) && ((sizeof(T) * 8) > BitLen)>::Type
50  {
51  StaticAssert<NumericTraits<T>::IsInteger>::check(); // Not applicable to floating point types
52  if (value & (T(1) << (BitLen - 1))) // The most significant bit is set --> negative
53  {
54  value |= T(T(0xFFFFFFFFFFFFFFFFULL) & ~((T(1) << BitLen) - 1));
55  }
56  }
57 
58  template <unsigned BitLen, typename T>
59  static typename EnableIf<!static_cast<bool>(NumericTraits<T>::IsSigned) || ((sizeof(T) * 8) == BitLen)>::Type
61 
62  template <unsigned BitLen, typename T>
63  static typename EnableIf<((sizeof(T) * 8) > BitLen)>::Type
64  clearExtraBits(T& value)
65  {
66  value &= (T(1) << BitLen) - 1; // Signedness doesn't matter
67  }
68 
69  template <unsigned BitLen, typename T>
70  static typename EnableIf<((sizeof(T) * 8) == BitLen)>::Type
72 
73  template <unsigned BitLen, typename T>
74  void validate()
75  {
76  StaticAssert<((sizeof(T) * 8) >= BitLen)>::check();
77  StaticAssert<(BitLen <= BitStream::MaxBitsPerRW)>::check();
78  StaticAssert<static_cast<bool>(NumericTraits<T>::IsSigned) ? (BitLen > 1) : true>::check();
79  }
80 
81  int encodeBytesImpl(uint8_t* bytes, unsigned bitlen);
82  int decodeBytesImpl(uint8_t* bytes, unsigned bitlen);
83 
84 public:
86  : stream_(stream)
87  { }
88 
89  template <unsigned BitLen, typename T>
90  int encode(const T value);
91 
92  template <unsigned BitLen, typename T>
93  int decode(T& value);
94 };
95 
96 // ----------------------------------------------------------------------------
97 
98 template <unsigned BitLen, typename T>
99 int ScalarCodec::encode(const T value)
100 {
101  validate<BitLen, T>();
102  union ByteUnion
103  {
104  T value;
105  uint8_t bytes[sizeof(T)];
106  } byte_union;
107  byte_union.value = value;
108  clearExtraBits<BitLen, T>(byte_union.value);
109  convertByteOrder<BitLen>(byte_union.bytes);
110  return encodeBytesImpl(byte_union.bytes, BitLen);
111 }
112 
113 template <unsigned BitLen, typename T>
114 int ScalarCodec::decode(T& value)
115 {
116  validate<BitLen, T>();
117  union ByteUnion
118  {
119  T value;
120  uint8_t bytes[sizeof(T)];
121  } byte_union;
122  byte_union.value = T();
123  const int read_res = decodeBytesImpl(byte_union.bytes, BitLen);
124  if (read_res > 0)
125  {
126  convertByteOrder<BitLen>(byte_union.bytes);
127  fixTwosComplement<BitLen, T>(byte_union.value);
128  value = byte_union.value;
129  }
130  return read_res;
131 }
132 
133 }
134 
135 #endif // UAVCAN_MARSHAL_SCALAR_CODEC_HPP_INCLUDED
check
ROSCPP_DECL bool check()
uavcan::BitStream
Definition: bit_stream.hpp:31
templates.hpp
uavcan::ScalarCodec::encodeBytesImpl
int encodeBytesImpl(uint8_t *bytes, unsigned bitlen)
Definition: uc_scalar_codec.cpp:21
uavcan::ScalarCodec::clearExtraBits
static EnableIf<((sizeof(T) *8)==BitLen)>::Type clearExtraBits(T &)
Definition: scalar_codec.hpp:71
uavcan::ScalarCodec::decode
int decode(T &value)
Definition: scalar_codec.hpp:114
uavcan::ScalarCodec::clearExtraBits
static EnableIf<((sizeof(T) *8) > BitLen)>::Type clearExtraBits(T &value)
Definition: scalar_codec.hpp:64
uavcan::ScalarCodec::convertByteOrder
static EnableIf<(BitLen<=8)>::Type convertByteOrder(uint8_t(&)[Size])
Definition: scalar_codec.hpp:45
bit_stream.hpp
uavcan::StaticAssert
struct UAVCAN_EXPORT StaticAssert
Definition: templates.hpp:29
std.hpp
uavcan::ScalarCodec::fixTwosComplement
static EnableIf< static_cast< bool >NumericTraits< T >::IsSigned) &&((sizeof(T) *8) > BitLen)>::Type fixTwosComplement(T &value)
Definition: scalar_codec.hpp:49
uavcan::ScalarCodec::stream_
BitStream & stream_
Definition: scalar_codec.hpp:22
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
uavcan::ScalarCodec::decodeBytesImpl
int decodeBytesImpl(uint8_t *bytes, unsigned bitlen)
Definition: uc_scalar_codec.cpp:32
UAVCAN_EXPORT
#define UAVCAN_EXPORT
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:108
uavcan::EnableIf
Definition: templates.hpp:59
uavcan::ScalarCodec::convertByteOrder
static EnableIf<(BitLen > 8)>::Type convertByteOrder(uint8_t(&bytes)[Size])
Definition: scalar_codec.hpp:28
uavcan::ScalarCodec::validate
void validate()
Definition: scalar_codec.hpp:74
build_config.hpp
int
int
Definition: libstubs.cpp:120
uavcan::ScalarCodec::fixTwosComplement
static EnableIf<!static_cast< bool >NumericTraits< T >::IsSigned)||((sizeof(T) *8)==BitLen)>::Type fixTwosComplement(T &)
Definition: scalar_codec.hpp:60
test.stream
stream
Definition: dsdl/test.py:6
uavcan::ScalarCodec::encode
int encode(const T value)
Definition: scalar_codec.hpp:99
uavcan
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:204
uavcan::ScalarCodec::ScalarCodec
ScalarCodec(BitStream &stream)
Definition: scalar_codec.hpp:85
uavcan::ScalarCodec
Definition: scalar_codec.hpp:20


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:03