Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef WEBRTC_BASE_BITBUFFER_H_
     12 #define WEBRTC_BASE_BITBUFFER_H_
     13 
     14 #include <stdint.h>  // For integer types.
     15 #include <stddef.h>  // For size_t.
     16 
     17 #include "webrtc/base/constructormagic.h"
     18 
     19 namespace rtc {
     20 
     21 // A class, similar to ByteBuffer, that can parse bit-sized data out of a set of
     22 // bytes. Has a similar API to ByteBuffer, plus methods for reading bit-sized
     23 // and exponential golomb encoded data. For a writable version, use
     24 // BitBufferWriter. Unlike ByteBuffer, this class doesn't make a copy of the
     25 // source bytes, so it can be used on read-only data.
     26 // Sizes/counts specify bits/bytes, for clarity.
     27 // Byte order is assumed big-endian/network.
     28 class BitBuffer {
     29  public:
     30   BitBuffer(const uint8_t* bytes, size_t byte_count);
     31 
     32   // Gets the current offset, in bytes/bits, from the start of the buffer. The
     33   // bit offset is the offset into the current byte, in the range [0,7].
     34   void GetCurrentOffset(size_t* out_byte_offset, size_t* out_bit_offset);
     35 
     36   // The remaining bits in the byte buffer.
     37   uint64_t RemainingBitCount() const;
     38 
     39   // Reads byte-sized values from the buffer. Returns false if there isn't
     40   // enough data left for the specified type.
     41   bool ReadUInt8(uint8_t* val);
     42   bool ReadUInt16(uint16_t* val);
     43   bool ReadUInt32(uint32_t* val);
     44 
     45   // Reads bit-sized values from the buffer. Returns false if there isn't enough
     46   // data left for the specified bit count..
     47   bool ReadBits(uint32_t* val, size_t bit_count);
     48 
     49   // Peeks bit-sized values from the buffer. Returns false if there isn't enough
     50   // data left for the specified number of bits. Doesn't move the current
     51   // offset.
     52   bool PeekBits(uint32_t* val, size_t bit_count);
     53 
     54   // Reads the exponential golomb encoded value at the current offset.
     55   // Exponential golomb values are encoded as:
     56   // 1) x = source val + 1
     57   // 2) In binary, write [countbits(x) - 1] 0s, then x
     58   // To decode, we count the number of leading 0 bits, read that many + 1 bits,
     59   // and increment the result by 1.
     60   // Returns false if there isn't enough data left for the specified type, or if
     61   // the value wouldn't fit in a uint32_t.
     62   bool ReadExponentialGolomb(uint32_t* val);
     63   // Reads signed exponential golomb values at the current offset. Signed
     64   // exponential golomb values are just the unsigned values mapped to the
     65   // sequence 0, 1, -1, 2, -2, etc. in order.
     66   bool ReadSignedExponentialGolomb(int32_t* val);
     67 
     68   // Moves current position |byte_count| bytes forward. Returns false if
     69   // there aren't enough bytes left in the buffer.
     70   bool ConsumeBytes(size_t byte_count);
     71   // Moves current position |bit_count| bits forward. Returns false if
     72   // there aren't enough bits left in the buffer.
     73   bool ConsumeBits(size_t bit_count);
     74 
     75   // Sets the current offset to the provied byte/bit offsets. The bit
     76   // offset is from the given byte, in the range [0,7].
     77   bool Seek(size_t byte_offset, size_t bit_offset);
     78 
     79  protected:
     80   const uint8_t* const bytes_;
     81   // The total size of |bytes_|.
     82   size_t byte_count_;
     83   // The current offset, in bytes, from the start of |bytes_|.
     84   size_t byte_offset_;
     85   // The current offset, in bits, into the current byte.
     86   size_t bit_offset_;
     87 
     88   RTC_DISALLOW_COPY_AND_ASSIGN(BitBuffer);
     89 };
     90 
     91 // A BitBuffer API for write operations. Supports symmetric write APIs to the
     92 // reading APIs of BitBuffer. Note that the read/write offset is shared with the
     93 // BitBuffer API, so both reading and writing will consume bytes/bits.
     94 class BitBufferWriter : public BitBuffer {
     95  public:
     96   // Constructs a bit buffer for the writable buffer of |bytes|.
     97   BitBufferWriter(uint8_t* bytes, size_t byte_count);
     98 
     99   // Writes byte-sized values from the buffer. Returns false if there isn't
    100   // enough data left for the specified type.
    101   bool WriteUInt8(uint8_t val);
    102   bool WriteUInt16(uint16_t val);
    103   bool WriteUInt32(uint32_t val);
    104 
    105   // Writes bit-sized values to the buffer. Returns false if there isn't enough
    106   // room left for the specified number of bits.
    107   bool WriteBits(uint64_t val, size_t bit_count);
    108 
    109   // Writes the exponential golomb encoded version of the supplied value.
    110   // Returns false if there isn't enough room left for the value.
    111   bool WriteExponentialGolomb(uint32_t val);
    112 
    113  private:
    114   // The buffer, as a writable array.
    115   uint8_t* const writable_bytes_;
    116 
    117   RTC_DISALLOW_COPY_AND_ASSIGN(BitBufferWriter);
    118 };
    119 
    120 }  // namespace rtc
    121 
    122 #endif  // WEBRTC_BASE_BITBUFFER_H_
    123