uc_bit_stream.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
7 #include <cassert>
8 
9 namespace uavcan
10 {
11 
12 const unsigned BitStream::MaxBytesPerRW;
13 const unsigned BitStream::MaxBitsPerRW;
14 
15 int BitStream::write(const uint8_t* bytes, const unsigned bitlen)
16 {
17  // Temporary buffer is needed to merge new bits with cached unaligned bits from the last write() (see byte_cache_)
18  uint8_t tmp[MaxBytesPerRW + 1];
19 
20  // Tmp space must be large enough to accomodate new bits AND unaligned bits from the last write()
21  const unsigned bytelen = bitlenToBytelen(bitlen + (bit_offset_ % 8));
22  UAVCAN_ASSERT(MaxBytesPerRW >= bytelen);
23  tmp[0] = tmp[bytelen - 1] = 0;
24 
25  fill(tmp, tmp + bytelen, uint8_t(0));
26  copyBitArrayAlignedToUnaligned(bytes, bitlen, tmp, bit_offset_ % 8);
27 
28  const unsigned new_bit_offset = bit_offset_ + bitlen;
29 
30  // Bitcopy algorithm resets skipped bits in the first byte. Restore them back.
31  tmp[0] |= byte_cache_;
32 
33  // (new_bit_offset % 8 == 0) means that this write was perfectly aligned.
34  byte_cache_ = uint8_t((new_bit_offset % 8) ? tmp[bytelen - 1] : 0);
35 
36  /*
37  * Dump the data into the destination buffer.
38  * Note that if this write was unaligned, last written byte in the buffer will be rewritten with updated value
39  * within the next write() operation.
40  */
41  const int write_res = buf_.write(bit_offset_ / 8, tmp, bytelen);
42  if (write_res < 0)
43  {
44  return write_res;
45  }
46  if (static_cast<unsigned>(write_res) < bytelen)
47  {
48  return ResultOutOfBuffer;
49  }
50 
51  bit_offset_ = new_bit_offset;
52  return ResultOk;
53 }
54 
55 int BitStream::read(uint8_t* bytes, const unsigned bitlen)
56 {
57  uint8_t tmp[MaxBytesPerRW + 1];
58 
59  const unsigned bytelen = bitlenToBytelen(bitlen + (bit_offset_ % 8));
60  UAVCAN_ASSERT(MaxBytesPerRW >= bytelen);
61 
62  const int read_res = buf_.read(bit_offset_ / 8, tmp, bytelen);
63  if (read_res < 0)
64  {
65  return read_res;
66  }
67  if (static_cast<unsigned>(read_res) < bytelen)
68  {
69  return ResultOutOfBuffer;
70  }
71 
72  fill(bytes, bytes + bitlenToBytelen(bitlen), uint8_t(0));
73  copyBitArrayUnalignedToAligned(tmp, bit_offset_ % 8, bitlen, bytes);
74  bit_offset_ += bitlen;
75  return ResultOk;
76 }
77 
78 #if UAVCAN_TOSTRING
79 std::string BitStream::toString() const
80 {
81  std::string out;
82  out.reserve(128);
83 
84  for (unsigned offset = 0; true; offset++)
85  {
86  uint8_t byte = 0;
87  if (1 != buf_.read(offset, &byte, 1U))
88  {
89  break;
90  }
91  for (int i = 7; i >= 0; i--) // Most significant goes first
92  {
93  out += (byte & (1 << i)) ? '1' : '0';
94  }
95  out += ' ';
96  }
97  if (out.length() > 0)
98  {
99  (void)out.erase(out.length() - 1, 1);
100  }
101  return out;
102 }
103 #endif
104 
105 }
uavcan::BitStream::byte_cache_
uint8_t byte_cache_
Definition: bit_stream.hpp:37
bit_stream.hpp
uavcan::BitStream::buf_
ITransferBuffer & buf_
Definition: bit_stream.hpp:35
uavcan::BitStream::ResultOutOfBuffer
@ ResultOutOfBuffer
Definition: bit_stream.hpp:60
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
uavcan::BitStream::MaxBitsPerRW
static const unsigned MaxBitsPerRW
Definition: bit_stream.hpp:56
uavcan::ITransferBuffer::write
virtual int write(unsigned offset, const uint8_t *data, unsigned len)=0
toString
static std::string toString(long x)
Definition: multiset.cpp:16
uavcan::BitStream::ResultOk
@ ResultOk
Definition: bit_stream.hpp:61
uavcan::BitStream::bitlenToBytelen
static unsigned bitlenToBytelen(unsigned bits)
Definition: bit_stream.hpp:39
uavcan::BitStream::read
int read(uint8_t *bytes, const unsigned bitlen)
Definition: uc_bit_stream.cpp:55
uavcan::ITransferBuffer::read
virtual int read(unsigned offset, uint8_t *data, unsigned len) const =0
uavcan::BitStream::copyBitArrayUnalignedToAligned
static void copyBitArrayUnalignedToAligned(const uint8_t *src_org, unsigned src_offset, unsigned src_len, uint8_t *dst_org)
Definition: bit_stream.hpp:48
uavcan::BitStream::MaxBytesPerRW
static const unsigned MaxBytesPerRW
Definition: bit_stream.hpp:33
uavcan::BitStream::bit_offset_
unsigned bit_offset_
Definition: bit_stream.hpp:36
uavcan::fill
UAVCAN_EXPORT void fill(ForwardIt first, ForwardIt last, const T &value)
Definition: templates.hpp:254
uavcan::BitStream::copyBitArrayAlignedToUnaligned
static void copyBitArrayAlignedToUnaligned(const uint8_t *src_org, unsigned src_len, uint8_t *dst_org, unsigned dst_offset)
Definition: bit_stream.hpp:41
uavcan
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:204
transfer_buffer.hpp
uavcan::BitStream::write
int write(const uint8_t *bytes, const unsigned bitlen)
Definition: uc_bit_stream.cpp:15
UAVCAN_ASSERT
#define UAVCAN_ASSERT(x)
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:184


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