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