libuav original
Dependents: UAVCAN UAVCAN_Subscriber
bit_stream.hpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #ifndef UAVCAN_MARSHAL_BIT_STREAM_HPP_INCLUDED 00006 #define UAVCAN_MARSHAL_BIT_STREAM_HPP_INCLUDED 00007 00008 #include <cassert> 00009 #include <uavcan/std.hpp> 00010 #include <uavcan/util/templates.hpp> 00011 #include <uavcan/transport/abstract_transfer_buffer.hpp> 00012 #include <uavcan/build_config.hpp> 00013 00014 namespace uavcan 00015 { 00016 /** 00017 * This function implements fast copy of unaligned bit arrays. It isn't part of the library API, so it is not exported. 00018 * @param src_org Source array 00019 * @param src_offset Bit offset of the first source byte 00020 * @param src_len Number of bits to copy 00021 * @param dst_org Destination array 00022 * @param dst_offset Bit offset of the first destination byte 00023 */ 00024 void bitarrayCopy(const unsigned char* src_org, std::size_t src_offset, std::size_t src_len, 00025 unsigned char* dst_org, std::size_t dst_offset); 00026 00027 /** 00028 * This class treats a chunk of memory as an array of bits. 00029 * It is used by the bit codec for serialization/deserialization. 00030 */ 00031 class UAVCAN_EXPORT BitStream 00032 { 00033 static const unsigned MaxBytesPerRW = 16; 00034 00035 ITransferBuffer& buf_; 00036 unsigned bit_offset_; 00037 uint8_t byte_cache_; 00038 00039 static inline unsigned bitlenToBytelen(unsigned bits) { return (bits + 7) / 8; } 00040 00041 static inline void copyBitArrayAlignedToUnaligned(const uint8_t* src_org, unsigned src_len, 00042 uint8_t* dst_org, unsigned dst_offset) 00043 { 00044 bitarrayCopy(reinterpret_cast<const unsigned char*>(src_org), 0, src_len, 00045 reinterpret_cast<unsigned char*>(dst_org), dst_offset); 00046 } 00047 00048 static inline void copyBitArrayUnalignedToAligned(const uint8_t* src_org, unsigned src_offset, unsigned src_len, 00049 uint8_t* dst_org) 00050 { 00051 bitarrayCopy(reinterpret_cast<const unsigned char*>(src_org), src_offset, src_len, 00052 reinterpret_cast<unsigned char*>(dst_org), 0); 00053 } 00054 00055 public: 00056 static const unsigned MaxBitsPerRW = MaxBytesPerRW * 8; 00057 00058 enum 00059 { 00060 ResultOutOfBuffer = 0, 00061 ResultOk = 1 00062 }; 00063 00064 explicit BitStream(ITransferBuffer& buf) 00065 : buf_(buf) 00066 , bit_offset_(0) 00067 , byte_cache_(0) 00068 { 00069 StaticAssert<sizeof(uint8_t) == 1>::check(); 00070 } 00071 00072 /** 00073 * Write/read calls interpret bytes as bit arrays, 8 bits per byte, where the most 00074 * significant bits have lower index, i.e.: 00075 * Hex: 55 2d 00076 * Bits: 01010101 00101101 00077 * Indices: 0 .. 7 8 .. 15 00078 * Return values: 00079 * Negative - Error 00080 * Zero - Out of buffer space 00081 * Positive - OK 00082 */ 00083 int write(const uint8_t* bytes, const unsigned bitlen); 00084 int read(uint8_t* bytes, const unsigned bitlen); 00085 00086 #if UAVCAN_TOSTRING 00087 std::string toString() const; 00088 #endif 00089 }; 00090 00091 } 00092 00093 #endif // UAVCAN_MARSHAL_BIT_STREAM_HPP_INCLUDED
Generated on Tue Jul 12 2022 17:17:30 by 1.7.2