libuav original

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bit_stream.hpp Source File

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