1 /* -*- mode: c++; c-file-style: raknet; tab-always-indent: nil; -*- */ 2 /** 3 * @file 4 * @brief RakNet::BitStream: packet encoding and decoding 5 * 6 * Copyright (c) 2003, Rakkarsoft LLC and Kevin Jenkins 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * * Neither the name of the <organization> nor the 17 * names of its contributors may be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef __BITSTREAM_H 33 #define __BITSTREAM_H 34 35 #include "../BlobbyDebug.h" 36 // Arbitrary size, just picking something likely to be larger than most packets 37 #define BITSTREAM_STACK_ALLOCATION_SIZE 256 38 39 /** 40 * @brief This namespace only contains a few utility class used in 41 * RakNet. 42 * 43 * RakNet namespace is the not really in use currently. 44 */ 45 46 /** \note If you want the default network byte stream to be 47 in Network Byte Order (Big Endian) then #define __BITSTREAM_BIG_END 48 otherwise the default is 'Little Endian'. If your CPU has the same 49 Byte Order as your network stream, you can cut out some overheads 50 using #define __BITSTREAM_NATIVE_END --- if this is defined, 51 the __BITSTREAM_BIG_END flag becomes ineffective. 52 */ 53 54 namespace RakNet 55 { 56 /** 57 * This macro transform a bit in byte 58 * @param x Transform a bit to a byte 59 */ 60 #define BITS_TO_BYTES(x) (((x)+7)>>3) 61 62 /** 63 * @brief Packets encoding and decoding facilities 64 * 65 * Helper class to encode and decode packets. 66 * 67 */ 68 69 class BitStream : public ObjectCounter<BitStream> 70 { 71 72 public: 73 /** 74 * Default Constructor 75 */ 76 BitStream(); 77 /** 78 * Preallocate some memory for the construction of the packet 79 * @param initialBytesToAllocate the amount of byte to pre-allocate. 80 */ 81 BitStream( int initialBytesToAllocate ); 82 83 /** 84 * Initialize the BitStream object using data from the network. 85 * Set _copyData to true if you want to make an internal copy of 86 * the data you are passing. You can then Write and do all other 87 * operations Set it to false if you want to just use a pointer to 88 * the data you are passing, in order to save memory and speed. 89 * You should only then do read operations. 90 * @param _data An array of bytes. 91 * @param lengthInBytes Size of the @em _data. 92 * @param _copyData Does a copy of the input data. 93 */ 94 BitStream( char* _data, unsigned int lengthInBytes, bool _copyData ); 95 /** 96 * Destructor 97 */ 98 ~BitStream(); 99 /** 100 * Reset the bitstream for reuse 101 */ 102 void Reset( void ); 103 /** 104 * Write the native types to the end of the buffer 105 * without any compression mecanism. 106 * @param input The data 107 */ 108 void Write( const bool input ); 109 /** 110 * Write the native types to the end of the buffer 111 * without any compression mecanism. 112 * @param input The data 113 */ 114 void Write( const unsigned char input ); 115 /** 116 * Write the native types to the end of the buffer 117 * without any compression mecanism. 118 * @param input The data 119 */ 120 void Write( const char input ); 121 /** 122 * Write the native types to the end of the buffer 123 * without any compression mecanism. 124 * @param input The data 125 */ 126 void Write( const unsigned short input ); 127 /** 128 * Write the native types to the end of the buffer 129 * without any compression mecanism. 130 * @param input The data 131 */ 132 void Write( const short input ); 133 /** 134 * Write the native types to the end of the buffer 135 * without any compression mecanism. 136 * @param input The data 137 */ 138 void Write( const unsigned int input ); 139 /** 140 * Write the native types to the end of the buffer 141 * without any compression mecanism. 142 * @param input The data 143 */ 144 void Write( const int input ); 145 146 /** 147 * Write the native types to the end of the buffer 148 * without any compression mecanism. 149 * @param input The data 150 */ 151 void Write( const float input ); 152 /** 153 * Write the native types to the end of the buffer 154 * without any compression mecanism. 155 * @param input The data 156 */ 157 void Write( const double input ); 158 /** 159 * Write an array or casted stream. It is supossed to 160 * be raw data. It is also not possible to deal with endian problem 161 * @param input a byte buffer 162 * @param numberOfBytes the size of the byte buffer 163 */ 164 void Write( const char* input, const int numberOfBytes ); 165 /** 166 * Write the native types with simple compression. 167 * Best used with negatives and positives close to 0 168 * @param input The data. 169 */ 170 void WriteCompressed( const unsigned char input ); 171 /** 172 * Write the native types with simple compression. 173 * Best used with negatives and positives close to 0 174 * @param input The data. 175 */ 176 void WriteCompressed( const char input ); 177 /** 178 * Write the native types with simple compression. 179 * Best used with negatives and positives close to 0 180 * @param input The data. 181 */ 182 void WriteCompressed( const unsigned short input ); 183 /** 184 * Write the native types with simple compression. 185 * Best used with negatives and positives close to 0 186 * @param input The data. 187 */ 188 void WriteCompressed( const short input ); 189 /** 190 * Write the native types with simple compression. 191 * Best used with negatives and positives close to 0 192 * @param input The data. 193 */ 194 void WriteCompressed( const unsigned int input ); 195 /** 196 * Write the native types with simple compression. 197 * Best used with negatives and positives close to 0 198 * @param input The data. 199 */ 200 void WriteCompressed( const int input ); 201 202 /** 203 * Read the native types from the front of the buffer 204 * @param output The readed value. 205 * @return true on success false otherwise. The result of a reading 206 * can only be wrong in the case we reach the end of the BitStream 207 * with some missing bits. 208 */ 209 bool Read( bool &output ); 210 /** 211 * Read the native types from the front of the buffer 212 * @param output The readed value. 213 * @return true on success false otherwise. The result of a reading 214 * can only be wrong in the case we reach the end of the BitStream 215 * with some missing bits. 216 */ 217 bool Read( unsigned char &output ); 218 /** 219 * Read the native types from the front of the buffer 220 * @param output The readed value. 221 * @return true on success false otherwise. The result of a reading 222 * can only be wrong in the case we reach the end of the BitStream 223 * with some missing bits. 224 */ 225 bool Read( char &output ); 226 /** 227 * Read the native types from the front of the buffer 228 * @param output The readed value. 229 * @return true on success false otherwise. The result of a reading 230 * can only be wrong in the case we reach the end of the BitStream 231 * with some missing bits. 232 */ 233 bool Read( unsigned short &output ); 234 /** 235 * Read the native types from the front of the buffer 236 * @param output The readed value. 237 * @return true on success false otherwise. The result of a reading 238 * can only be wrong in the case we reach the end of the BitStream 239 * with some missing bits. 240 */ 241 bool Read( short &output ); 242 /** 243 * Read the native types from the front of the buffer 244 * @param output The readed value. 245 * @return true on success false otherwise. The result of a reading 246 * can only be wrong in the case we reach the end of the BitStream 247 * with some missing bits. 248 */ 249 bool Read( unsigned int &output ); 250 /** 251 * Read the native types from the front of the buffer 252 * @param output The readed value. 253 * @return true on success false otherwise. The result of a reading 254 * can only be wrong in the case we reach the end of the BitStream 255 * with some missing bits. 256 */ 257 bool Read( int &output ); 258 259 /** 260 * Read the native types from the front of the buffer 261 * @param output The readed value. 262 * @return true on success false otherwise. The result of a reading 263 * can only be wrong in the case we reach the end of the BitStream 264 * with some missing bits. 265 */ 266 bool Read( float &output ); 267 /** 268 * Read the native types from the front of the buffer 269 * @param output The readed value. 270 * @return true on success false otherwise. The result of a reading 271 * can only be wrong in the case we reach the end of the BitStream 272 * with some missing bits. 273 */ 274 bool Read( double &output ); 275 /** 276 * Read an array or casted stream of byte. The array 277 * is raw data. There is no automatic conversion on 278 * big endian arch 279 * @param output The result byte array. It should be larger than @em numberOfBytes. 280 * @param numberOfBytes The number of byte to read 281 * @return true on success false if there is some missing bytes. 282 */ 283 bool Read( char* output, const int numberOfBytes ); 284 /** 285 * Read the types you wrote with WriteCompressed 286 * @param output The read value 287 * @return true on success, false on not enough data to read 288 */ 289 bool ReadCompressed( unsigned char & output ); 290 /** 291 * Read the types you wrote with WriteCompressed 292 * @param output The read value 293 * @return true on success, false on not enough data to read 294 */ 295 bool ReadCompressed( char &output ); 296 /** 297 * Read the types you wrote with WriteCompressed 298 * @param output The read value 299 * @return true on success, false on not enough data to read 300 */ 301 bool ReadCompressed( unsigned short &output ); 302 /** 303 * Read the types you wrote with WriteCompressed 304 * @param output The read value 305 * @return true on success, false on not enough data to read 306 */ 307 bool ReadCompressed( short &output ); 308 /** 309 * Read the types you wrote with WriteCompressed 310 * @param output The read value 311 * @return true on success, false on not enough data to read 312 */ 313 bool ReadCompressed( unsigned int &output ); 314 /** 315 * Read the types you wrote with WriteCompressed 316 * @param output The read value 317 * @return true on success, false on not enough data to read 318 */ 319 bool ReadCompressed( int &output ); 320 321 /** 322 * Sets the read pointer back to the beginning of your data. 323 */ 324 void ResetReadPointer( void ); 325 /** 326 * Sets the write pointer back to the beginning of your data. 327 */ 328 void ResetWritePointer( void ); 329 /** 330 * This is good to call when you are done with the stream to make 331 * sure you didn't leave any data left over void 332 */ 333 void AssertStreamEmpty( void ); 334 /** 335 * print to the standard output the state of the stream bit by bit 336 */ 337 void PrintBits( void ) const; 338 339 /** 340 * Ignore data we don't intend to read 341 * @param numberOfBits The number of bits to ignore 342 */ 343 void IgnoreBits( const int numberOfBits ); 344 345 /** 346 * Ignore data we don't intend to read 347 * @param numberOfBytes The number of bytes to ignore 348 */ 349 void IgnoreBytes( const int numberOfBytes ); 350 351 /** 352 * Move the write pointer to a position on the array. 353 * @param offset the offset from the start of the array. 354 * @attention 355 * Dangerous if you don't know what you are doing! 356 * 357 */ 358 void SetWriteOffset( const int offset ); 359 /** 360 * Returns the length in bits of the stream 361 */ 362 int GetNumberOfBitsUsed( void ) const; 363 /** 364 * Returns the length in bytes of the stream 365 */ 366 int GetNumberOfBytesUsed( void ) const; 367 /** 368 * Returns the number of bits into the stream that we have read 369 */ 370 int GetReadOffset( void ) const; 371 /** 372 * Returns the number of bits left in the stream that haven't been read 373 */ 374 int GetNumberOfUnreadBits( void ) const; 375 /** 376 * Makes a copy of the internal data for you Data will point to 377 * the stream. Returns the length in bits of the stream. Partial 378 * bytes are left aligned 379 * @param _data the resulting byte copy of the internal state. 380 */ 381 int CopyData( unsigned char** _data ) const; 382 /** 383 * Set the stream to some initial data. For internal use 384 * Partial bytes are left aligned 385 * @param input The data 386 * @param numberOfBits the number of bits set in the data buffer 387 */ 388 void SetData( const unsigned char* input, const int numberOfBits ); 389 /** 390 * Exposes the internal data. 391 * Partial bytes are left aligned. 392 * @return A pointer to the internal state 393 */ 394 unsigned char* GetData( void ) const; 395 /** 396 * Write numberToWrite bits from the input source Right aligned 397 * data means in the case of a partial byte, the bits are aligned 398 * from the right (bit 0) rather than the left (as in the normal 399 * internal representation) You would set this to true when 400 * writing user data, and false when copying bitstream data, such 401 * as writing one bitstream to another 402 * @param input The data 403 * @param numberOfBitsToWrite The number of bits to write 404 * @param rightAlignedBits if true data will be right aligned 405 */ 406 void WriteBits( const unsigned char* input, 407 int numberOfBitsToWrite, const bool rightAlignedBits = true ); 408 /** 409 * Align the bitstream to the byte boundary and then write the 410 * specified number of bits. This is faster than WriteBits but 411 * wastes the bits to do the alignment and requires you to call 412 * ReadAlignedBits at the corresponding read position. 413 * @param input The data 414 * @param numberOfBytesToWrite The size of data. 415 */ 416 void WriteAlignedBytes( const unsigned char* input, 417 const int numberOfBytesToWrite ); 418 /** 419 * Read bits, starting at the next aligned bits. Note that the 420 * modulus 8 starting offset of the sequence must be the same as 421 * was used with WriteBits. This will be a problem with packet 422 * coalescence unless you byte align the coalesced packets. 423 * @param output The byte array larger than @em numberOfBytesToRead 424 * @param numberOfBytesToRead The number of byte to read from the internal state 425 * @return true if there is enough byte. 426 */ 427 bool ReadAlignedBytes( unsigned char* output, 428 const int numberOfBytesToRead ); 429 /** 430 * Align the next write and/or read to a byte boundary. This can 431 * be used to 'waste' bits to byte align for efficiency reasons It 432 * can also be used to force coalesced bitstreams to start on byte 433 * boundaries so so WriteAlignedBits and ReadAlignedBits both 434 * calculate the same offset when aligning. 435 */ 436 void AlignWriteToByteBoundary( void ); 437 /** 438 * Align the next write and/or read to a byte boundary. This can 439 * be used to 'waste' bits to byte align for efficiency reasons It 440 * can also be used to force coalesced bitstreams to start on byte 441 * boundaries so so WriteAlignedBits and ReadAlignedBits both 442 * calculate the same offset when aligning. 443 */ 444 void AlignReadToByteBoundary( void ); 445 446 /** 447 * Read numberOfBitsToRead bits to the output source 448 * alignBitsToRight should be set to true to convert internal 449 * bitstream data to userdata It should be false if you used 450 * WriteBits with rightAlignedBits false 451 * @param output The resulting bits array 452 * @param numberOfBitsToRead The number of bits to read 453 * @param alignsBitsToRight if true bits will be right aligned. 454 * @return true if there is enough bits to read 455 */ 456 bool ReadBits( unsigned char* output, int numberOfBitsToRead, 457 const bool alignBitsToRight = true ); 458 459 /** 460 * --- Low level functions --- 461 * These are for when you want to deal 462 * with bits and don't care about type checking 463 * Write a 0 464 */ 465 void Write0( void ); 466 /** 467 * --- Low level functions --- 468 * These are for when you want to deal 469 * with bits and don't care about type checking 470 * Write a 1 471 */ 472 void Write1( void ); 473 /** 474 * --- Low level functions --- 475 * These are for when you want to deal 476 * with bits and don't care about type checking 477 * Reads 1 bit and returns true if that bit is 1 and false if it is 0 478 */ 479 bool ReadBit( void ); 480 /** 481 * If we used the constructor version with copy data off, this 482 * makes sure it is set to on and the data pointed to is copied. 483 */ 484 void AssertCopyData( void ); 485 /** 486 * Use this if you pass a pointer copy to the constructor 487 * (_copyData==false) and want to overallocate to prevent 488 * reallocation 489 */ 490 void SetNumberOfBitsAllocated( const unsigned int lengthInBits ); 491 492 private: 493 /** 494 * Assume the input source points to a native type, compress and write it. 495 */ 496 void WriteCompressed( const unsigned char* input, 497 const int size, const bool unsignedData ); 498 499 /** 500 * Assume the input source points to a compressed native type. 501 * Decompress and read it. 502 */ 503 bool ReadCompressed( unsigned char* output, 504 const int size, const bool unsignedData ); 505 506 /** 507 * Reallocates (if necessary) in preparation of writing 508 * numberOfBitsToWrite 509 */ 510 void AddBitsAndReallocate( const int numberOfBitsToWrite ); 511 512 /** 513 * Number of bits currently used 514 */ 515 int numberOfBitsUsed; 516 /** 517 * Number of bits currently allocated 518 */ 519 int numberOfBitsAllocated; 520 /** 521 * Current readOffset 522 */ 523 int readOffset; 524 /** 525 * array of byte storing the data. Points to stackData or if is bigger than that then is allocated 526 */ 527 unsigned char *data; 528 /** 529 * true if the internal buffer is copy of the data passed to the 530 * constructor 531 */ 532 bool copyData; 533 534 unsigned char stackData[BITSTREAM_STACK_ALLOCATION_SIZE]; 535 }; 536 } 537 538 #endif 539