1 #include <ail/memory.hpp>
2 #include <ail/string.hpp>
4 #include <boost/foreach.hpp>
8 std::size_t const bits_per_byte
= 8;
10 bit_reader::bit_reader(std::string
const & data
, bool high_to_low_order
):
21 initial_value
= bits_per_byte
- 1;
28 limit
= bits_per_byte
;
32 BOOST_FOREACH(char i
, data
)
34 for(std::size_t bit
= initial_value
; bit
!= limit
; bit
+= direction
)
35 bit_stream
.push_back(static_cast<char>((i
>> bit
) & 1));
39 ulong
bit_reader::read(std::size_t bit_count
)
41 std::size_t new_offset
= offset
+ bit_count
;
42 if(new_offset
> bit_stream
.size())
43 throw exception("Reading bit stream data out of bounds");
44 std::string binary_string
= bit_stream
.substr(offset
, bit_count
);
45 ulong output
= binary_string_to_number(binary_string
);
50 ulong
bit_reader::read_bytes(std::size_t byte_count
)
52 return read(bits_per_byte
* byte_count
);
55 bool bit_reader::read_bool()
60 std::size_t bit_reader::get_offset() const
65 void bit_reader::set_offset(std::size_t new_offset
)
67 if(new_offset
> bit_stream
.size())
68 throw exception("New bit stream offset is out of bounds");
72 std::string
bit_reader::string(std::size_t length
, std::size_t character_size
)
75 for(std::size_t i
= 0; i
< length
; i
++)
76 output
.push_back(static_cast<char>(read(character_size
)));
80 ulong
read_big_endian(char const * input
, std::size_t size
, std::size_t offset
)
82 unsigned char const * unsigned_input
= reinterpret_cast<unsigned char const *>(input
+ offset
);
86 for(unsigned char const * i
= unsigned_input
, * end
= unsigned_input
+ size
; i
< end
; ++i
)
88 output
<<= bits_per_byte
;
95 ulong
read_little_endian(char const * input
, std::size_t size
, std::size_t offset
)
97 unsigned char const * unsigned_input
= reinterpret_cast<unsigned char const *>(input
+ offset
);
101 for(unsigned char const * i
= unsigned_input
+ size
- 1, * end
= unsigned_input
; i
>= end
; --i
)
103 output
<<= bits_per_byte
;
104 output
|= static_cast<ulong
>(*i
);
110 ulong
read_big_endian_bits(char const * data
, std::size_t bit_count
, std::size_t offset
)
113 for(std::size_t i
= 0; i
< bit_count
; i
++)
116 output
|= get_bit(data
, offset
+ i
);
121 ulong
read_little_endian_bits(char const * data
, std::size_t bit_count
, std::size_t offset
)
124 for(std::size_t i
= 0; i
< bit_count
; i
++)
125 output
|= get_bit(data
, offset
+ i
) << i
;
129 void write_big_endian(ulong input
, char * output
, std::size_t size
)
133 for(char * i
= output
+ size
- 1; i
>= output
; --i
)
136 input
>>= bits_per_byte
;
141 void write_little_endian(ulong input
, char * output
, std::size_t size
)
145 for(char * i
= output
, * end
= output
+ size
; i
< end
; ++i
)
148 input
>>= bits_per_byte
;
153 std::string
big_endian_string(ulong input
, std::size_t size
)
155 char * buffer
= new char[size
];
156 write_big_endian(input
, buffer
, size
);
157 std::string output
= std::string(buffer
, size
);
162 std::string
little_endian_string(ulong input
, std::size_t size
)
164 char * buffer
= new char[size
];
165 write_little_endian(input
, buffer
, size
);
166 std::string output
= std::string(buffer
, size
);
171 ulong
get_bit(char const * data
, std::size_t offset
)
173 std::size_t byte
= offset
/ bits_per_byte
;
174 std::size_t bit
= offset
% bits_per_byte
;
175 return (data
[byte
] >> bit
) & 1;