Fix test for bug #32625
[gnash.git] / libbase / BitsReader.h
blobfb01c06ed231d306460f2900badc859c72d46761
1 // BitsReader.h: bits reader, for Gnash.
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
4 // Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #ifndef BITSREADER_H
23 #define BITSREADER_H
25 #include "dsodefs.h"
26 #include "log.h"
28 #include <sstream>
29 #include <cassert>
30 #include <boost/cstdint.hpp> // for boost::uint32_t used in this file
32 namespace gnash {
34 /// BitsReader is used to encapsulate bit-packed buffer reads.
36 /// TODO: implement boundary checking, maybe by throwing an exception
37 /// when attempts are made to read past end of buffer
38 ///
39 class DSOEXPORT BitsReader
41 public:
42 typedef unsigned char byte;
44 /// Ownership of buffer left to caller
45 BitsReader(const byte* input, size_t len)
47 start(input),
48 ptr(start),
49 end(start+len),
50 usedBits(0)
54 /// Create a BitsReader reading a subset of another
56 /// The starting pointer will be taken from the parent
57 /// reader cursor, including used bits, use align() if
58 /// need to discard the left over ones.
59 ///
60 /// length will be given explicitly.
61 ///
62 BitsReader(const BitsReader& from, size_t len)
64 start(from.ptr),
65 ptr(start),
66 end(start+len),
67 usedBits(from.usedBits)
71 ~BitsReader() {}
73 size_t size() const
75 return end-start;
78 /// Set a new buffer to work with
79 void setBuffer(byte* input, size_t len)
81 start = ptr = input;
82 end = start+len;
83 usedBits = 0;
86 /// \brief
87 /// Reads a bit-packed unsigned integer from the stream
88 /// and returns it. The given bitcount determines the
89 /// number of bits to read.
90 unsigned read_uint(unsigned short bitcount);
92 /// \brief
93 /// Reads a single bit off the stream
94 /// and returns it.
95 bool read_bit();
97 /// \brief
98 /// Reads a bit-packed little-endian signed integer
99 /// from the stream. The given bitcount determines the
100 /// number of bits to read.
101 boost::int32_t read_sint(unsigned short bitcount);
103 /// Read a byte as an unsigned int (aligned)
104 boost::uint8_t read_u8()
106 align();
107 return *ptr++;
110 /// Read one bytes as a signed int (aligned)
111 boost::int8_t read_s8()
113 return static_cast<boost::int8_t>(read_u8());
116 /// Read two bytes as an unsigned int (aligned)
117 boost::uint16_t read_u16()
119 align();
120 assert(ptr+2 < end);
121 boost::uint16_t result = *ptr++;
122 result |= *ptr++ << 8;
123 return result ;
126 /// Read two bytes as a signed int (aligned)
127 boost::int16_t read_s16()
129 return static_cast<boost::int16_t>(read_u16());
132 /// Read four bytes as an unsigned int (aligned)
133 boost::uint32_t read_u32()
135 align();
136 assert(ptr+4 < end);
137 boost::uint32_t result = *ptr++;
138 result |= *ptr++ << 8;
139 result |= *ptr++ << 16;
140 result |= *ptr++ << 24;
141 return(result);
144 /// Read four bytes as an signed int (aligned)
145 boost::int32_t read_s32()
147 return static_cast<boost::int32_t>(read_u32());
150 /// \brief
151 /// Discard any unused bit in the current byte
152 /// and advance to next
153 void align()
155 if ( usedBits ) advanceToNextByte();
158 /// Checks if the stream contains X bits
159 bool gotBits(boost::uint32_t nbits)
161 boost::uint32_t gotbits = 8-usedBits +8*(end-ptr-1);
162 if (gotbits > nbits) return true;
163 else return false;
166 private:
168 void advanceToNextByte()
170 if ( ++ptr == end )
172 log_debug("Going round");
173 ptr=start;
175 usedBits=0;
178 /// Pointer to first byte
179 const byte* start;
181 /// Pointer to current byte
182 const byte* ptr;
184 /// Pointer to one past last byte
185 const byte* end;
187 /// Number of used bits in current byte
188 unsigned usedBits;
193 } // end namespace gnash
196 #endif // BITSREADER_H
199 // Local Variables:
200 // mode: C++
201 // c-basic-offset: 8
202 // tab-width: 8
203 // indent-tabs-mode: t
204 // End: