1 #ifndef BYTES_H
2 #define BYTES_H
3 
4 #include <string.h>
5 
6 class ByteReader;
7 class ByteWriter;
8 
9 class Bytes
10 {
11 public:
12     Bytes();
13     Bytes(unsigned size);
14     Bytes(const uint8_t* ptr, size_t len);
15     Bytes(const std::string& data);
16     Bytes(std::initializer_list<uint8_t> data);
17     Bytes(std::shared_ptr<std::vector<uint8_t>> data);
18     Bytes(std::shared_ptr<std::vector<uint8_t>> data, unsigned start, unsigned end);
19 
20     Bytes* operator = (const Bytes& other);
21 
22 public:
23     /* General purpose methods */
24 
25     unsigned size() const        { return _high - _low; }
arrowhead()26     bool empty() const           { return _high == _low; }
27 
28     bool operator == (const Bytes& other) const
29     { return std::equal(cbegin(), cend(), other.cbegin(), other.cend()); }
30 
31     bool operator != (const Bytes& other) const
32     { return !(*this == other); }
33 
34     const uint8_t& operator [] (unsigned offset) const;
35     const uint8_t* cbegin() const { return &(*_data)[_low]; }
36     const uint8_t* cend() const   { return &(*_data)[_high]; }
37     const uint8_t* begin() const  { return &(*_data)[_low]; }
38     const uint8_t* end() const    { return &(*_data)[_high]; }
39 
40     uint8_t& operator [] (unsigned offset);
41     uint8_t* begin()              { checkWritable(); return &(*_data)[_low]; }
42     uint8_t* end()                { checkWritable(); return &(*_data)[_high]; }
43 
44 	operator const std::string () const { return std::string(cbegin(), cend()); }
rewind(unsigned path_id)45 
46     void boundsCheck(unsigned pos) const;
47     void checkWritable();
48     void adjustBounds(unsigned pos);
49     Bytes& resize(unsigned size);
50 
51     Bytes& clear()
52     { resize(0); return *this; }
53 
54     Bytes slice(unsigned start, unsigned len) const;
55     Bytes slice(unsigned start) const;
56     Bytes swab() const;
57     Bytes compress() const;
58     Bytes decompress() const;
59 	std::vector<bool> toBits() const;
60 
61     ByteReader reader() const;
62     ByteWriter writer();
63 
64     void writeToFile(const std::string& filename) const;
65 	void writeTo(std::ostream& stream) const;
66 
67 private:
68     std::shared_ptr<std::vector<uint8_t>> _data;
69     unsigned _low;
70     unsigned _high;
71 };
72 
73 class ByteReader
74 {
75 public:
76     ByteReader(const Bytes& bytes):
77         _bytes(bytes)
78     {}
79 
80     ByteReader(const Bytes&&) = delete;
81 
82     unsigned pos = 0;
83     bool eof() const
84     { return pos >= _bytes.size(); }
85 
86     ByteReader& seek(unsigned pos)
87     {
88         this->pos = pos;
89         return *this;
90     }
91 
92     ByteReader& skip(int delta)
93     {
94         this->pos += delta;
95         return *this;
96     }
97 
vertex(double * x,double * y)98     const Bytes read(unsigned len)
99     {
100         const Bytes bytes = _bytes.slice(pos, len);
101         pos += len;
102         return bytes;
103     }
104 
105     uint8_t read_8()
106     {
107         return _bytes[pos++];
108     }
109 
110     uint16_t read_be16()
111     {
112         uint8_t b1 = _bytes[pos++];
113         uint8_t b2 = _bytes[pos++];
114         return (b1<<8) | b2;
115     }
116 
117     uint32_t read_be24()
118     {
119         uint8_t b1 = _bytes[pos++];
120         uint8_t b2 = _bytes[pos++];
121         uint8_t b3 = _bytes[pos++];
122         return (b1<<16) | (b2<<8) | b3;
123     }
124 
125     uint32_t read_be32()
126     {
127         uint8_t b1 = _bytes[pos++];
128         uint8_t b2 = _bytes[pos++];
129         uint8_t b3 = _bytes[pos++];
130         uint8_t b4 = _bytes[pos++];
131         return (b1<<24) | (b2<<16) | (b3<<8) | b4;
132     }
133 
134     uint16_t read_le16()
135     {
136         uint8_t b1 = _bytes[pos++];
137         uint8_t b2 = _bytes[pos++];
138         return (b2<<8) | b1;
139     }
140 
141     uint32_t read_le24()
142     {
143         uint8_t b1 = _bytes[pos++];
144         uint8_t b2 = _bytes[pos++];
145         uint8_t b3 = _bytes[pos++];
146         return (b3<<16) | (b2<<8) | b1;
147     }
148 
149     uint32_t read_le32()
150     {
151         uint8_t b1 = _bytes[pos++];
152         uint8_t b2 = _bytes[pos++];
153         uint8_t b3 = _bytes[pos++];
154         uint8_t b4 = _bytes[pos++];
155         return (b4<<24) | (b3<<16) | (b2<<8) | b1;
156     }
157 
158 private:
159     const Bytes& _bytes;
160 };
161 
162 class ByteWriter
163 {
164 public:
165     ByteWriter(Bytes& bytes):
166         _bytes(bytes)
167     {}
168 
169     ByteWriter(const Bytes&&) = delete;
170 
171     unsigned pos = 0;
172 
173     ByteWriter& seek(unsigned pos)
174     {
175         this->pos = pos;
176         return *this;
177     }
178 
179     ByteWriter& seekToEnd()
180     {
181         pos = _bytes.size();
182         return *this;
183     }
184 
185     ByteWriter& write_8(uint8_t value)
186     {
187         _bytes.adjustBounds(pos);
188         uint8_t* p = _bytes.begin();
189         p[pos++] = value;
190         return *this;
191     }
192 
193     ByteWriter& write_be16(uint16_t value)
194     {
195         _bytes.adjustBounds(pos+1);
196         uint8_t* p = _bytes.begin();
197         p[pos++] = value >> 8;
198         p[pos++] = value;
199         return *this;
200     }
201 
202     ByteWriter& write_be24(uint32_t value)
203     {
204         _bytes.adjustBounds(pos+2);
205         uint8_t* p = _bytes.begin();
206         p[pos++] = value >> 16;
207         p[pos++] = value >> 8;
208         p[pos++] = value;
209         return *this;
210     }
211 
212     ByteWriter& write_be32(uint32_t value)
213     {
214         _bytes.adjustBounds(pos+3);
215         uint8_t* p = _bytes.begin();
216         p[pos++] = value >> 24;
217         p[pos++] = value >> 16;
218         p[pos++] = value >> 8;
219         p[pos++] = value;
220         return *this;
221     }
222 
223     ByteWriter& write_le16(uint16_t value)
224     {
225         _bytes.adjustBounds(pos+1);
226         uint8_t* p = _bytes.begin();
227         p[pos++] = value;
228         p[pos++] = value >> 8;
229         return *this;
230     }
231 
232     ByteWriter& write_le24(uint32_t value)
233     {
234         _bytes.adjustBounds(pos+2);
235         uint8_t* p = _bytes.begin();
236         p[pos++] = value;
237         p[pos++] = value >> 8;
238         p[pos++] = value >> 16;
239         return *this;
240     }
241 
242     ByteWriter& write_le32(uint32_t value)
243     {
244         _bytes.adjustBounds(pos+3);
245         uint8_t* p = _bytes.begin();
246         p[pos++] = value;
247         p[pos++] = value >> 8;
248         p[pos++] = value >> 16;
249         p[pos++] = value >> 24;
250         return *this;
251     }
252 
253     ByteWriter& operator += (std::initializer_list<uint8_t> data)
254     {
255         _bytes.adjustBounds(pos + data.size() - 1);
256         std::copy(data.begin(), data.end(), _bytes.begin() + pos);
257         pos += data.size();
258         return *this;
259     }
260 
261     ByteWriter& operator += (const std::vector<uint8_t>& data)
262     {
263         _bytes.adjustBounds(pos + data.size() - 1);
264         std::copy(data.begin(), data.end(), _bytes.begin() + pos);
265         pos += data.size();
266         return *this;
267     }
268 
269     ByteWriter& operator += (const Bytes data)
270     {
271         _bytes.adjustBounds(pos + data.size() - 1);
272         std::copy(data.begin(), data.end(), _bytes.begin() + pos);
273         pos += data.size();
274         return *this;
275     }
276 
277     ByteWriter& operator += (std::istream& stream);
278 
279 	ByteWriter& append(const char* data)
280 	{
281 		return *this += Bytes((const uint8_t*)data, strlen(data));
282 	}
283 
284 	ByteWriter& append(const std::string& data)
285 	{
286 		return *this += Bytes(data);
287 	}
288 
289     ByteWriter& append(const Bytes data)
290     {
291         return *this += data;
292     }
293 
294     ByteWriter& append(std::istream& stream)
295     {
296         return *this += stream;
297     }
298 
299 private:
300     Bytes& _bytes;
301 };
302 
303 class BitWriter
304 {
305 public:
306     BitWriter(ByteWriter& bw):
307         _bw(bw)
308     {}
309 
310     BitWriter(ByteWriter&&) = delete;
311 
312     void push(uint32_t bits, size_t size);
313     void flush();
314 
315 private:
316     uint8_t _fifo = 0;
317     size_t _bitcount = 0;
318     ByteWriter& _bw;
319 };
320 
321 static inline uint8_t reverse_bits(uint8_t b)
322 {
323     b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
324     b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
325     b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
326     return b;
327 }
328 
329 extern uint8_t toByte(
330     std::vector<bool>::const_iterator start,
331     std::vector<bool>::const_iterator end);
332 
333 extern Bytes toBytes(
334     std::vector<bool>::const_iterator start,
335     std::vector<bool>::const_iterator end);
336 
337 inline Bytes toBytes(const std::vector<bool>& bits)
338 { return toBytes(bits.begin(), bits.end()); }
339 
340 extern std::vector<bool> reverseBits(const std::vector<bool>& bits);
341 
342 #endif
343