Buffer.hh

Go to the documentation of this file.
00001 #ifndef BIT_BUFFER_HH
00002 #define BIT_BUFFER_HH
00003 
00004 #include "bit/base.hh"
00005 
00006 namespace bit {
00007 
00012   class Buffer {
00013 
00014   public:
00016     typedef std::vector<unsigned char> DataVector;
00017 
00018   public:
00019 
00023     Buffer(u64 size = 0)
00024     {
00025       m_data.resize(size);
00026     }
00027 
00031     void swap(Buffer &buffer)
00032     {
00033       m_data.swap(buffer.m_data);
00034     }
00035     
00036 
00039     u64 size() const
00040     {
00041       return m_data.size();
00042     }
00043     
00049     void resize(u64 size)
00050     {
00051       m_data.resize(size);
00052     }
00053 
00062     u32 read_pos(u64 byte_pos, unsigned int bit_offset, 
00063                  unsigned int bits) const
00064     {
00065       if (bit_offset >= max_bits_per_value)
00066         throw bit::invalid_argument(
00067           "bit::Buffer::read_pos(): invalid bit_offset");
00068       if (bits > max_bits_per_value)
00069         throw bit::invalid_argument(
00070           "bit::Buffer::read_pos(): tried to read too many bits");
00071       if (bits == 0)
00072         return 0;
00073 
00074       // Ensure that read does not exceed the buffer
00075       //
00076       u64 last_byte_required = byte_pos + (bit_offset + bits - 1) / 8;
00077       if (last_byte_required >= m_data.size())
00078         throw bit::out_of_range("bit::Buffer::read_pos(): out_of_range");
00079 
00080       u64 value = 0;
00081       int num_bytes = (bits + bit_offset + 7) / 8;
00082       for (int i = 0; i < num_bytes; i++)
00083         value += (u64)m_data[byte_pos + i] << shift[i];
00084       value >>= bit_offset;
00085       value &= one_masks[bits];
00086       return (u32)value;
00087     }
00088 
00095     u32 read_elem(u64 elem, unsigned int bits_per_elem) const
00096     {
00097       u64 bit_pos = elem * bits_per_elem;
00098       return read_pos(bit_pos / 8, bit_pos % 8, bits_per_elem);
00099     }
00100 
00101 
00110     void write_pos(u64 byte_pos, unsigned int bit_offset, u32 value, 
00111                    unsigned int bits)
00112     {
00113       if (bit_offset >= max_bits_per_value)
00114         throw bit::invalid_argument(
00115           "bit::Buffer::write_pos(): invalid bit_offset");
00116       if (bits > max_bits_per_value)
00117         throw bit::invalid_argument(
00118           "bit::Buffer::write_pos(): tried to write too many bits");
00119       if (bit::highest_bit(value) > bits)
00120         throw bit::invalid_argument(
00121           "bit::Buffer::write_pos(): value greater than given bits");
00122       if (bits == 0)
00123         return;
00124 
00125       // Ensure that write does not exceed the buffer
00126       //
00127       u64 last_byte_required = byte_pos + (bit_offset + bits - 1) / 8;
00128       if (last_byte_required >= m_data.size())
00129         throw bit::out_of_range("bit::Buffer::write_pos(): out_of_range");
00130 
00131       u64 zero_mask = one_masks[bits];
00132       zero_mask <<= bit_offset;
00133       zero_mask = ~zero_mask;
00134       u64 value_mask = value;
00135       value_mask <<= bit_offset;
00136 
00137       int num_bytes = (bits + bit_offset + 7) / 8;
00138       for (int i = 0; i < num_bytes; i++) {
00139         m_data[byte_pos + i] &= (unsigned char)(zero_mask & 0xff);
00140         m_data[byte_pos + i] |= (unsigned char)(value_mask & 0xff);
00141         zero_mask >>= 8;
00142         value_mask >>= 8;
00143       }
00144     }
00145 
00153     void write_elem(u64 elem, unsigned int bits_per_elem, u32 value)
00154     {
00155       u64 bit_pos = elem * bits_per_elem;
00156       write_pos(bit_pos / 8, bit_pos % 8, value, bits_per_elem);
00157     }
00158 
00162     const unsigned char *data() const
00163     {
00164       return &m_data[0];
00165     }
00166 
00170     unsigned char *data() 
00171     {
00172       return &m_data[0];
00173     }
00174 
00175   private:
00176 
00178     DataVector m_data;
00179 
00180   };
00181 
00182 
00183 };
00184 
00185 #endif /* BIT_BUFFER_HH */

Generated on Mon Jan 8 15:51:03 2007 for bit by  doxygen 1.4.6