首页 > 代码库 > C#版BitStream 1.0
C#版BitStream 1.0
根据C++版的改编,刚刚改完,估计使用会有问题,对于uint8处理的不好
关于使用:
1 BitStream bs = new BitStream( );2 bs.WriteInt32( 123 );3 4 int a = bs.ReadInt32( );
非常简单
BitStream.cs
1 public class BitStream 2 { 3 #if __BITSTREAM_BIG_END 4 // Set up the read/write routines to produce Big-End network streams. 5 private static readonly int B16_1 = 0; 6 private static readonly int B16_0 = 1; 7 8 private static readonly int B32_3 = 0; 9 private static readonly int B32_2 = 1; 10 private static readonly int B32_1 = 2; 11 private static readonly int B32_0 = 3; 12 13 private static readonly int B64_7 = 0; 14 private static readonly int B64_6 = 1; 15 private static readonly int B64_5 = 2; 16 private static readonly int B64_4 = 3; 17 private static readonly int B64_3 = 4; 18 private static readonly int B64_2 = 5; 19 private static readonly int B64_1 = 6; 20 private static readonly int B64_0 = 7; 21 22 #else 23 // Default to producing Little-End network streams. 24 private static readonly int B16_1 = 1; 25 private static readonly int B16_0 = 0; 26 27 private static readonly int B32_3 = 3; 28 private static readonly int B32_2 = 2; 29 private static readonly int B32_1 = 1; 30 private static readonly int B32_0 = 0; 31 32 private static readonly int B64_7 = 7; 33 private static readonly int B64_6 = 6; 34 private static readonly int B64_5 = 5; 35 private static readonly int B64_4 = 4; 36 private static readonly int B64_3 = 3; 37 private static readonly int B64_2 = 2; 38 private static readonly int B64_1 = 1; 39 private static readonly int B64_0 = 0; 40 #endif 41 public static readonly int BITSTREAM_STACK_ALLOCATION_SIZE = 2048; 42 43 /// Default Constructor 44 public static int BITS_TO_BYTES(int x) 45 { 46 return (((x) + 7) >> 3); 47 } 48 49 public static int BYTES_TO_BITS(int x) 50 { 51 return (x << 3); 52 } 53 54 /** 55 * @brief Packets encoding and decoding facilities 56 * 57 * Helper class to encode and decode packets. 58 * 59 */ 60 61 /** 62 * Default Constructor 63 */ 64 65 public BitStream() 66 { 67 numberOfBitsUsed = 0; 68 //numberOfBitsAllocated = 32 * 8; 69 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE*8; 70 readOffset = 0; 71 //data = http://www.mamicode.com/( unsigned char* ) malloc( 32 ); 72 data =http://www.mamicode.com/ stackData; 73 copyData = http://www.mamicode.com/true; 74 } 75 76 /** 77 * Preallocate some memory for the construction of the packet 78 * @param initialBytesToAllocate the amount of byte to pre-allocate. 79 */ 80 81 public BitStream(int initialBytesToAllocate) 82 { 83 numberOfBitsUsed = 0; 84 readOffset = 0; 85 if (initialBytesToAllocate <= BITSTREAM_STACK_ALLOCATION_SIZE) 86 { 87 data =http://www.mamicode.com/ stackData; 88 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE*8; 89 } 90 else 91 { 92 data = http://www.mamicode.com/new Byte[initialBytesToAllocate]; 93 numberOfBitsAllocated = initialBytesToAllocate << 3; 94 } 95 copyData = http://www.mamicode.com/true; 96 } 97 98 /** 99 * Initialize the BitStream object using data from the network. 100 * Set _copyData to true if you want to make an internal copy of 101 * the data you are passing. You can then Write and do all other 102 * operations Set it to false if you want to just use a pointer to 103 * the data you are passing, in order to save memory and speed. 104 * You should only then do read operations. 105 * @param _data An array of bytes. 106 * @param lengthInBytes Size of the @em _data. 107 * @param _copyData Does a copy of the input data. 108 */ 109 110 public BitStream(Byte[] _data, int lengthInBytes, bool _copyData) 111 { 112 numberOfBitsUsed = lengthInBytes << 3; 113 readOffset = 0; 114 copyData =http://www.mamicode.com/ _copyData; 115 numberOfBitsAllocated = lengthInBytes << 3; 116 117 if (copyData) 118 { 119 if (lengthInBytes > 0) 120 { 121 if (lengthInBytes < BITSTREAM_STACK_ALLOCATION_SIZE) 122 { 123 data =http://www.mamicode.com/ stackData; 124 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE << 3; 125 } 126 else 127 { 128 data = http://www.mamicode.com/new Byte[lengthInBytes]; 129 } 130 _data.CopyTo(data, 0); 131 } 132 else 133 data = http://www.mamicode.com/null; 134 } 135 else 136 { 137 data =http://www.mamicode.com/ _data; 138 numberOfBitsUsed = 0; 139 } 140 } 141 142 // 143 public BitStream(Byte[] _data, int lengthInBytes, int datasize) 144 { 145 numberOfBitsUsed = datasize << 3; 146 readOffset = 0; 147 numberOfBitsAllocated = lengthInBytes << 3; 148 data =http://www.mamicode.com/ _data; 149 copyData = http://www.mamicode.com/false; 150 } 151 152 /** 153 * Destructor 154 */ 155 //~BitStream(){} 156 /** 157 * Reset the bitstream for reuse 158 */ 159 160 private void Reset() 161 { 162 if (numberOfBitsUsed > 0) 163 { 164 // memset(data, 0, BITS_TO_BYTES(numberOfBitsUsed)); 165 } 166 // Don‘t free memory here for speed efficiency 167 //free(data); // Use realloc and free so we are more efficient than delete and new for resizing 168 numberOfBitsUsed = 0; 169 //numberOfBitsAllocated=8; 170 readOffset = 0; 171 } 172 173 public void SetBuffer(Byte[] _data, int lengthInBytes, int datasize) 174 { 175 numberOfBitsUsed = datasize << 3; 176 readOffset = 0; 177 numberOfBitsAllocated = lengthInBytes << 3; 178 data =http://www.mamicode.com/ _data; 179 copyData = http://www.mamicode.com/false; 180 } 181 182 public void ClearBuffer() 183 { 184 numberOfBitsUsed = 0; 185 readOffset = 0; 186 numberOfBitsAllocated = 0; 187 data = http://www.mamicode.com/null; 188 } 189 190 /** 191 * Write the native types to the end of the buffer 192 * without any compression mecanism. 193 * @param input The data 194 */ 195 196 public void WriteBool(bool input) 197 { 198 if (input) 199 WriteInt8(1); 200 else 201 WriteInt8(0); 202 } 203 204 /** 205 * Write the native types to the end of the buffer 206 * without any compression mecanism. 207 * @param input The data 208 */ 209 210 public void WriteUInt8(Byte input) 211 { 212 WriteBits(BitConverter.GetBytes(input), sizeof (Byte)*8, true); 213 } 214 215 // 216 217 /** 218 * Write the native types to the end of the buffer 219 * without any compression mecanism. 220 * @param input The data 221 */ 222 223 public void WriteInt8(SByte input) 224 { 225 WriteBits(BitConverter.GetBytes(input), sizeof (SByte)*8, true); 226 } 227 228 /** 229 * Write the native types to the end of the buffer 230 * without any compression mecanism. 231 * @param input The data 232 */ 233 234 public void WriteUInt16(UInt16 input) 235 { 236 var uint16w = new Byte[2]; 237 uint16w[B16_1] = (Byte) ((Byte) (input >> 8) & (0xff)); 238 uint16w[B16_0] = (Byte) (input & (0xff)); 239 240 WriteBits(uint16w, sizeof (UInt16)*8, true); 241 } 242 243 /** 244 * Write the native types to the end of the buffer 245 * without any compression mecanism. 246 * @param input The data 247 */ 248 249 public void WriteInt16(Int16 input) 250 { 251 var int16w = new Byte[2]; 252 int16w[B16_1] = (Byte) ((Byte) (input >> 8) & (0xff)); 253 int16w[B16_0] = (Byte) (input & (0xff)); 254 255 WriteBits(int16w, sizeof (Int16)*8, true); 256 } 257 258 /** 259 * Write the native types to the end of the buffer 260 * without any compression mecanism. 261 * @param input The data 262 */ 263 264 public void WriteUInt32(UInt32 input) 265 { 266 var uint32w = new Byte[4]; 267 uint32w[B32_3] = (Byte) ((Byte) (input >> 24) & (0x000000ff)); 268 uint32w[B32_2] = (Byte) ((Byte) (input >> 16) & (0x000000ff)); 269 uint32w[B32_1] = (Byte) ((Byte) (input >> 8) & (0x000000ff)); 270 uint32w[B32_0] = (Byte) ((input) & (0x000000ff)); 271 272 WriteBits(uint32w, sizeof (UInt32)*8, true); 273 } 274 275 /** 276 * Write the native types to the end of the buffer 277 * without any compression mecanism. 278 * @param input The data 279 */ 280 281 public void WriteInt32(int input) 282 { 283 var int32w = new Byte[4]; 284 int32w[B32_3] = (Byte) ((Byte) (input >> 24) & (0x000000ff)); 285 int32w[B32_2] = (Byte) ((Byte) (input >> 16) & (0x000000ff)); 286 int32w[B32_1] = (Byte) ((Byte) (input >> 8) & (0x000000ff)); 287 int32w[B32_0] = (Byte) ((input) & (0x000000ff)); 288 289 WriteBits(int32w, sizeof (int)*8, true); 290 } 291 292 //#if HAS_INT64 293 /** 294 * Write the native types to the end of the buffer 295 * without any compression mecanism. 296 * @param input The data 297 */ 298 299 public void WriteUInt64(UInt64 input) 300 { 301 var uint64w = new Byte[8]; 302 uint64w[B64_7] = (Byte) ((input >> 56) & 0xff); 303 uint64w[B64_6] = (Byte) ((input >> 48) & 0xff); 304 uint64w[B64_5] = (Byte) ((input >> 40) & 0xff); 305 uint64w[B64_4] = (Byte) ((input >> 32) & 0xff); 306 uint64w[B64_3] = (Byte) ((input >> 24) & 0xff); 307 uint64w[B64_2] = (Byte) ((input >> 16) & 0xff); 308 uint64w[B64_1] = (Byte) ((input >> 8) & 0xff); 309 uint64w[B64_0] = (Byte) (input & 0xff); 310 311 WriteBits(uint64w, sizeof (UInt64)*8, true); 312 } 313 314 /** 315 * Write the native types to the end of the buffer 316 * without any compression mecanism. 317 * @param input The data 318 */ 319 320 public void WriteInt64(Int64 input) 321 { 322 var int64w = new Byte[8]; 323 int64w[B64_7] = (Byte) ((input >> 56) & 0xff); 324 int64w[B64_6] = (Byte) ((input >> 48) & 0xff); 325 int64w[B64_5] = (Byte) ((input >> 40) & 0xff); 326 int64w[B64_4] = (Byte) ((input >> 32) & 0xff); 327 int64w[B64_3] = (Byte) ((input >> 24) & 0xff); 328 int64w[B64_2] = (Byte) ((input >> 16) & 0xff); 329 int64w[B64_1] = (Byte) ((input >> 8) & 0xff); 330 int64w[B64_0] = (Byte) (input & 0xff); 331 332 WriteBits(int64w, sizeof (Int64)*8, true); 333 } 334 335 //#endif 336 337 /** 338 * Write the native types to the end of the buffer 339 * without any compression mecanism. 340 * @param input The data 341 */ 342 343 public void WriteFloat(float input) 344 { 345 WriteBits(BitConverter.GetBytes(input), sizeof (float)*8, true); 346 } 347 348 /** 349 * Write the native types to the end of the buffer 350 * without any compression mechanism. 351 * @param input The data 352 */ 353 354 public void WriteDouble(double input) 355 { 356 WriteBits(BitConverter.GetBytes(input), sizeof (double)*8, true); 357 } 358 359 /** 360 * Write an array or casted stream. It is supposed to 361 * be raw data. It is also not possible to deal with endian problem 362 * @param input a byte buffer 363 * @param numberOfBytes the size of the byte buffer 364 */ 365 366 public void WriteBytes(Byte[] input, int numberOfBytes) 367 { 368 WriteBits(input, numberOfBytes*8, true); 369 } 370 371 /** 372 * write multi bytes string 373 * @param input 374 */ 375 376 public void WriteStr(string input) 377 { 378 var len = (short) input.Length; 379 WriteUInt16((ushort) len); 380 if (len > 0) 381 { 382 WriteBytes(Encoding.Default.GetBytes(input), len); 383 } 384 } 385 386 /// ** 387 // * write standard string 388 // * @param input 389 // */ 390 // public void WriteStr( 391 // const std:: 392 // string 393 //& 394 // input 395 //){} 396 /** 397 * Copy from another bitstream 398 * @bitStream the bitstream to copy from 399 */ 400 public void WriteBS(BitStream bitStream) 401 { 402 WriteBits(bitStream.GetData(), bitStream.GetWriteOffset(), false); 403 } 404 405 /** 406 * Write the native types with simple compression. 407 * Best used with negatives and positives close to 0 408 * @param input The data. 409 */ 410 411 public void WriteCompUInt8(Byte input) 412 { 413 WriteCompressed(BitConverter.GetBytes(input), sizeof (Byte)*8, true); 414 } 415 416 /** 417 * Write the native types with simple compression. 418 * Best used with negatives and positives close to 0 419 * @param input The data. 420 */ 421 422 public void WriteCompInt8(SByte input) 423 { 424 WriteCompressed(BitConverter.GetBytes(input), sizeof (SByte)*8, false); 425 } 426 427 /** 428 * Write the native types with simple compression. 429 * Best used with negatives and positives close to 0 430 * @param input The data. 431 */ 432 433 public void WriteCompUInt16(UInt16 input) 434 { 435 var uint16wc = new Byte[2]; 436 uint16wc[B16_1] = (byte) ((Byte) (input >> 8) & (0xff)); 437 uint16wc[B16_0] = (byte) (input & (0xff)); 438 439 WriteCompressed(uint16wc, sizeof (UInt16)*8, true); 440 } 441 442 /** 443 * Write the native types with simple compression. 444 * Best used with negatives and positives close to 0 445 * @param input The data. 446 */ 447 448 public void WriteCompInt16(Int16 input) 449 { 450 var int16wc = new Byte[2]; 451 int16wc[B16_1] = (Byte) ((input >> 8) & (0xff)); 452 int16wc[B16_0] = (Byte) (input & (0xff)); 453 454 WriteCompressed(int16wc, sizeof (Int16)*8, false); 455 } 456 457 /** 458 * Write the native types with simple compression. 459 * Best used with negatives and positives close to 0 460 * @param input The data. 461 */ 462 463 public void WriteCompUInt32(UInt32 input) 464 { 465 var uint32wc = new Byte[4]; 466 uint32wc[B32_3] = (Byte) ((input >> 24) & (0x000000ff)); 467 uint32wc[B32_2] = (Byte) ((input >> 16) & (0x000000ff)); 468 uint32wc[B32_1] = (Byte) ((input >> 8) & (0x000000ff)); 469 uint32wc[B32_0] = (Byte) ((input) & (0x000000ff)); 470 471 WriteCompressed(uint32wc, sizeof (UInt32)*8, true); 472 } 473 474 /** 475 * Write the native types with simple compression. 476 * Best used with negatives and positives close to 0 477 * @param input The data. 478 */ 479 480 public void WriteCompInt32(int input) 481 { 482 var int32wc = new Byte[4]; 483 int32wc[B32_3] = (Byte) ((input >> 24) & (0x000000ff)); 484 int32wc[B32_2] = (Byte) ((input >> 16) & (0x000000ff)); 485 int32wc[B32_1] = (Byte) ((input >> 8) & (0x000000ff)); 486 int32wc[B32_0] = (Byte) ((input) & (0x000000ff)); 487 488 WriteCompressed(int32wc, sizeof (int)*8, false); 489 } 490 491 //#ifdef HAS_INT64 492 /** 493 * Write the native types with simple compression. 494 * Best used with negatives and positives close to 0 495 * @param input The data. 496 */ 497 498 public void WriteCompUInt64(UInt64 input) 499 { 500 var uint64wc = new Byte[8]; 501 uint64wc[B64_7] = (Byte) ((input >> 56) & 0xff); 502 uint64wc[B64_6] = (Byte) ((input >> 48) & 0xff); 503 uint64wc[B64_5] = (Byte) ((input >> 40) & 0xff); 504 uint64wc[B64_4] = (Byte) ((input >> 32) & 0xff); 505 uint64wc[B64_3] = (Byte) ((input >> 24) & 0xff); 506 uint64wc[B64_2] = (Byte) ((input >> 16) & 0xff); 507 uint64wc[B64_1] = (Byte) ((input >> 8) & 0xff); 508 uint64wc[B64_0] = (Byte) (input & 0xff); 509 510 WriteCompressed(uint64wc, sizeof (UInt64)*8, true); 511 } 512 513 /** 514 * Write the native types with simple compression. 515 * Best used with negatives and positives close to 0 516 * @param input The data. 517 */ 518 519 public void WriteCompInt64(Int64 input) 520 { 521 var int64wc = new Byte[8]; 522 int64wc[B64_7] = (Byte) ((input >> 56) & 0xff); 523 int64wc[B64_6] = (Byte) ((input >> 48) & 0xff); 524 int64wc[B64_5] = (Byte) ((input >> 40) & 0xff); 525 int64wc[B64_4] = (Byte) ((input >> 32) & 0xff); 526 int64wc[B64_3] = (Byte) ((input >> 24) & 0xff); 527 int64wc[B64_2] = (Byte) ((input >> 16) & 0xff); 528 int64wc[B64_1] = (Byte) ((input >> 8) & 0xff); 529 int64wc[B64_0] = (Byte) (input & 0xff); 530 531 WriteCompressed(int64wc, sizeof (Int64)*8, false); 532 } 533 534 //#endif 535 /** 536 * Write the native types with simple compression. 537 * Best used with negatives and positives close to 0 538 * @param input The data. 539 */ 540 541 public void WriteCompFloat(float input) 542 { 543 WriteFloat(input); 544 } 545 546 /** 547 * Write the native types with simple compression. 548 * Best used with negatives and positives close to 0 549 * @param input The data. 550 */ 551 552 public void WriteCompDouble(double input) 553 { 554 WriteDouble(input); 555 } 556 557 /** 558 * Read the native types from the front of the buffer 559 * @param output The readed value. 560 * @return true on success false otherwise. The result of a reading 561 * can only be wrong in the case we reach the end of the BitStream 562 * with some missing bits. 563 */ 564 565 public bool ReadBool() 566 { 567 if (readOffset + 1 > numberOfBitsUsed) 568 return false; 569 570 //if (ReadBit()) // Check that bit 571 if ((data[readOffset >> 3] & (0x80 >> (readOffset++%8))) != 0) // Is it faster to just write it out here? 572 return true; 573 574 return false; 575 } 576 577 /** 578 * Read the native types from the front of the buffer 579 * @param output The readed value. 580 * @return true on success false otherwise. The result of a reading 581 * can only be wrong in the case we reach the end of the BitStream 582 * with some missing bits. 583 */ 584 585 public SByte ReadUInt8() 586 { 587 var x = new Byte[sizeof (SByte)]; 588 if (ReadBits(ref x, sizeof (SByte)*8)) 589 { 590 return (SByte) BitConverter.ToChar(x, 0); 591 } 592 return 0; 593 } 594 595 /** 596 * Read the native types from the front of the buffer 597 * @param output The readed value. 598 * @return true on success false otherwise. The result of a reading 599 * can only be wrong in the case we reach the end of the BitStream 600 * with some missing bits. 601 */ 602 603 public Byte ReadInt8() 604 { 605 var x = new Byte[sizeof (Byte)]; 606 if (ReadBits(ref x, sizeof (Byte)*8)) 607 { 608 return (Byte) BitConverter.ToChar(x, 0); 609 ; 610 } 611 return 0; 612 } 613 614 /** 615 * Read the native types from the front of the buffer 616 * @param output The readed value. 617 * @return true on success false otherwise. The result of a reading 618 * can only be wrong in the case we reach the end of the BitStream 619 * with some missing bits. 620 */ 621 622 public UInt16 ReadUInt16() 623 { 624 var uint16r = new Byte[2]; 625 if (ReadBits(ref uint16r, sizeof (UInt16)*8) != true) 626 return 0; 627 return (ushort) ((uint16r[B16_1] << 8) | uint16r[B16_0]); 628 } 629 630 /** 631 * Read the native types from the front of the buffer 632 * @param output The readed value. 633 * @return true on success false otherwise. The result of a reading 634 * can only be wrong in the case we reach the end of the BitStream 635 * with some missing bits. 636 */ 637 638 public short ReadInt16() 639 { 640 var int16r = new Byte[2]; 641 if (ReadBits(ref int16r, sizeof (short)*8) != true) 642 return 0; 643 644 return (short) ((int16r[B16_1] << 8) | int16r[B16_0]); 645 } 646 647 /** 648 * Read the native types from the front of the buffer 649 * @param output The readed value. 650 * @return true on success false otherwise. The result of a reading 651 * can only be wrong in the case we reach the end of the BitStream 652 * with some missing bits. 653 */ 654 655 public UInt32 ReadUInt32() 656 { 657 var uint32r = new Byte[4]; 658 if (ReadBits(ref uint32r, sizeof (UInt32)*8) != true) 659 return 0; 660 return (((UInt32) uint32r[B32_3]) << 24) | 661 (((UInt32) uint32r[B32_2]) << 16) | 662 (((UInt32) uint32r[B32_1]) << 8) | 663 uint32r[B32_0]; 664 } 665 666 /** 667 * Read the native types from the front of the buffer 668 * @param output The readed value. 669 * @return true on success false otherwise. The result of a reading 670 * can only be wrong in the case we reach the end of the BitStream 671 * with some missing bits. 672 */ 673 674 public int ReadInt32() 675 { 676 var int32r = new Byte[4]; 677 if (ReadBits(ref int32r, sizeof (int)*8) != true) 678 return 0; 679 return (int32r[B32_3] << 24) | 680 (int32r[B32_2] << 16) | 681 (int32r[B32_1] << 8) | 682 int32r[B32_0]; 683 } 684 685 686 //#ifdef HAS_INT64 687 /** 688 * Read the native types from the front of the buffer 689 * @param output The readed value. 690 * @return true on success false otherwise. The result of a reading 691 * can only be wrong in the case we reach the end of the BitStream 692 * with some missing bits. 693 */ 694 695 public UInt64 ReadUInt64() 696 { 697 var uint64r = new Byte[8]; 698 if (ReadBits(ref uint64r, sizeof (UInt64)*8) != true) 699 return 0; 700 return (((UInt64) uint64r[B64_7]) << 56) | (((UInt64) uint64r[B64_6]) << 48) | 701 (((UInt64) uint64r[B64_5]) << 40) | (((UInt64) uint64r[B64_4]) << 32) | 702 (((UInt64) uint64r[B64_3]) << 24) | (((UInt64) uint64r[B64_2]) << 16) | 703 (((UInt64) uint64r[B64_1]) << 8) | uint64r[B64_0]; 704 } 705 706 /** 707 * Read the native types from the front of the buffer 708 * @param output The readed value. 709 * @return true on success false otherwise. The result of a reading 710 * can only be wrong in the case we reach the end of the BitStream 711 * with some missing bits. 712 */ 713 714 public Int64 ReadInt64() 715 { 716 var int64r = new Byte[8]; 717 if (ReadBits(ref int64r, sizeof (Int64)*8) != true) 718 return 0; 719 return (Int64) ((((UInt64) int64r[B64_7]) << 56) | (((UInt64) int64r[B64_6]) << 48) | 720 (((UInt64) int64r[B64_5]) << 40) | (((UInt64) int64r[B64_4]) << 32) | 721 (((UInt64) int64r[B64_3]) << 24) | (((UInt64) int64r[B64_2]) << 16) | 722 (((UInt64) int64r[B64_1]) << 8) | int64r[B64_0]); 723 } 724 725 //#endif 726 /** 727 * Read the native types from the front of the buffer 728 * @param output The readed value. 729 * @return true on success false otherwise. The result of a reading 730 * can only be wrong in the case we reach the end of the BitStream 731 * with some missing bits. 732 */ 733 734 public float ReadFloat() 735 { 736 uint val = ReadUInt32(); 737 return BitConverter.ToSingle(BitConverter.GetBytes(val), 0); 738 } 739 740 /** 741 * Read the native types from the front of the buffer 742 * @param output The readed value. 743 * @return true on success false otherwise. The result of a reading 744 * can only be wrong in the case we reach the end of the BitStream 745 * with some missing bits. 746 */ 747 748 public double ReadDouble() 749 { 750 UInt64 val = ReadUInt64(); 751 return BitConverter.ToDouble(BitConverter.GetBytes(val), 0); 752 } 753 754 /** 755 * Read an array or casted stream of byte. The array 756 * is raw data. There is no automatic conversion on 757 * big endian arch 758 * @param output The result byte array. It should be larger than @em numberOfBytes. 759 * @param numberOfBytes The number of byte to read 760 * @return true on success false if there is some missing bytes. 761 */ 762 763 public bool ReadBytes(ref Byte[] output, int numberOfBytes) 764 { 765 return ReadBits(ref output, numberOfBytes*8); 766 } 767 768 /** 769 * Read standard string 770 * @return 771 */ 772 773 public string ReadStr() 774 { 775 string strs; 776 ushort len = ReadUInt16(); 777 if (len > 0) 778 { 779 var str = new Byte[len + 1]; 780 if (ReadBytes(ref str, len)) 781 { 782 str[len] = 10; 783 strs = Encoding.Default.GetString(str); 784 return strs; 785 } 786 } 787 return string.Empty; 788 } 789 790 /** 791 * Read the types you wrote with WriteCompressed 792 * @param output The read value 793 * @return true on success, false on not enough data to read 794 */ 795 796 public SByte ReadCompUInt8() 797 { 798 var uint8rc = new Byte[sizeof (Byte)]; 799 800 if (ReadCompressed(ref uint8rc, sizeof (Byte)*8, true)) 801 { 802 return (SByte) uint8rc[0]; 803 } 804 return 0; 805 } 806 807 /** 808 * Read the types you wrote with WriteCompressed 809 * @param output The read value 810 * @return true on success, false on not enough data to read 811 */ 812 813 public Byte ReadCompInt8() 814 { 815 var uint8rc = new Byte[sizeof (Byte)]; 816 817 if (ReadCompressed(ref uint8rc, sizeof (Byte)*8, true)) 818 { 819 return uint8rc[0]; 820 } 821 return 0; 822 } 823 824 /** 825 * Read the types you wrote with WriteCompressed 826 * @param output The read value 827 * @return true on success, false on not enough data to read 828 */ 829 830 public UInt16 ReadCompUInt16() 831 { 832 var uint16rc = new Byte[2]; 833 if (ReadCompressed(ref uint16rc, sizeof (UInt16)*8, true) != true) 834 return 0; 835 return (ushort) ((uint16rc[B16_1] << 8) | 836 uint16rc[B16_0]); 837 } 838 839 /** 840 * Read the types you wrote with WriteCompressed 841 * @param output The read value 842 * @return true on success, false on not enough data to read 843 */ 844 845 public short ReadCompInt16() 846 { 847 var int16rc = new byte[2]; 848 if (ReadCompressed(ref int16rc, sizeof (short)*8, false) != true) return 0; 849 return (short) ((int16rc[B16_1] << 8) | int16rc[B16_0]); 850 } 851 852 /** 853 * Read the types you wrote with WriteCompressed 854 * @param output The read value 855 * @return true on success, false on not enough data to read 856 */ 857 858 public UInt32 ReadCompUInt32() 859 { 860 var uint32rc = new Byte[4]; 861 if (ReadCompressed(ref uint32rc, sizeof (UInt32)*8, true) != true) 862 return 0; 863 return (((UInt32) uint32rc[B32_3]) << 24) | 864 (((UInt32) uint32rc[B32_2]) << 16) | 865 (((UInt32) uint32rc[B32_1]) << 8) | 866 uint32rc[B32_0]; 867 } 868 869 /** 870 * Read the types you wrote with WriteCompressed 871 * @param output The read value 872 * @return true on success, false on not enough data to read 873 */ 874 875 public int ReadCompInt32() 876 { 877 var int32rc = new Byte[4]; 878 if (ReadCompressed(ref int32rc, sizeof (int)*8, false) != true) 879 return 0; 880 return (int) ((((UInt32) int32rc[B32_3]) << 24) | 881 (((UInt32) int32rc[B32_2]) << 16) | 882 (((UInt32) int32rc[B32_1]) << 8) | 883 int32rc[B32_0]); 884 } 885 886 //#ifdef HAS_INT64 887 /** 888 * Read the types you wrote with WriteCompressed 889 * @param output The read value 890 * @return true on success, false on not enough data to read 891 */ 892 893 public UInt64 ReadCompUInt64() 894 { 895 var uint64rc = new Byte[8]; 896 if (ReadCompressed(ref uint64rc, sizeof (UInt64)*8, true) != true) 897 return 0; 898 return (((UInt64) uint64rc[B64_7]) << 56) | (((UInt64) uint64rc[B64_6]) << 48) | 899 (((UInt64) uint64rc[B64_5]) << 40) | (((UInt64) uint64rc[B64_4]) << 32) | 900 (((UInt64) uint64rc[B64_3]) << 24) | (((UInt64) uint64rc[B64_2]) << 16) | 901 (((UInt64) uint64rc[B64_1]) << 8) | uint64rc[B64_0]; 902 } 903 904 /** 905 * Read the types you wrote with WriteCompressed 906 * @param output The read value 907 * @return true on success, false on not enough data to read 908 */ 909 910 public Int64 ReadCompInt64() 911 { 912 var int64rc = new Byte[8]; 913 if (ReadCompressed(ref int64rc, sizeof (Int64)*8, false) != true) 914 return 0; 915 return (Int64) ((((UInt64) int64rc[B64_7]) << 56) | (((UInt64) int64rc[B64_6]) << 48) | 916 (((UInt64) int64rc[B64_5]) << 40) | (((UInt64) int64rc[B64_4]) << 32) | 917 (((UInt64) int64rc[B64_3]) << 24) | (((UInt64) int64rc[B64_2]) << 16) | 918 (((UInt64) int64rc[B64_1]) << 8) | int64rc[B64_0]); 919 } 920 921 //#endif 922 /** 923 * Read the types you wrote with WriteCompressed 924 * @param output The read value 925 * @return true on success, false on not enough data to read 926 */ 927 928 public float ReadCompFloat() 929 { 930 return ReadFloat(); 931 } 932 933 /** 934 * Read the types you wrote with WriteCompressed 935 * @param output The read value 936 * @return true on success, false on not enough data to read 937 */ 938 939 public double ReadCompDouble() 940 { 941 return ReadDouble(); 942 } 943 944 /** 945 * Read a normalized 3D vector, using (at most) 4 bytes + 3 bits instead of 12 bytes. Will further compress y or z axis aligned vectors. 946 * Accurate to 1/32767.5. 947 * @param x x 948 * @param y y 949 * @param z z 950 */ 951 952 953 /** 954 * This is good to call when you are done with the stream to make 955 * sure you didn‘t leave any data left over void 956 */ 957 958 public void AssertStreamEmpty() 959 { 960 if (readOffset == numberOfBitsUsed) 961 throw new Exception(); 962 } 963 964 // * print to the standard output the state of the stream bit by bit 965 // */ 966 967 //public void PrintBits() 968 //{ 969 970 //} 971 /// ** 972 /// ** 973 // * Ignore data we don‘t intend to read 974 // * @param numberOfBits The number of bits to ignore 975 // */ 976 public void IgnoreBits(int numberOfBits) 977 { 978 readOffset += numberOfBits; 979 } 980 981 /** 982 * Move the write pointer to a position on the array. 983 * @param offset the offset from the start of the array. 984 * @attention 985 * Dangerous if you don‘t know what you are doing! 986 * 987 */ 988 989 public void SetWriteOffset(int offset) 990 { 991 numberOfBitsUsed = offset; 992 } 993 994 /** 995 * Returns the length in bits of the stream 996 */ 997 998 public int GetWriteOffset() 999 {1000 return numberOfBitsUsed;1001 }1002 1003 /**1004 * Returns the length in bytes of the stream1005 */1006 1007 public int GetNumberOfBytesUsed()1008 {1009 return BITS_TO_BYTES(numberOfBitsUsed);1010 }1011 1012 public int GetNumberOfBytesRead()1013 {1014 return BITS_TO_BYTES(readOffset);1015 }1016 1017 /**1018 * Move the read pointer to a position on the array.1019 * @param offset1020 */1021 1022 public void SetReadOffset(int offset)1023 {1024 readOffset = offset;1025 }1026 1027 public void SetByteReadOffSet(int offset)1028 {1029 readOffset = BYTES_TO_BITS(offset);1030 }1031 1032 /**1033 * Returns the number of bits into the stream that we have read1034 */1035 1036 public int GetReadOffset()1037 {1038 return readOffset;1039 }1040 1041 1042 /**1043 * Returns the number of bits left in the stream that haven‘t been read1044 */1045 1046 public int GetNumberOfUnreadBits()1047 {1048 return numberOfBitsUsed - readOffset;1049 }1050 1051 /**1052 * Makes a copy of the internal data for you Data will point to1053 * the stream. Returns the length in bits of the stream. Partial1054 * bytes are left aligned 1055 * @param _data the resulting byte copy of the internal state. 1056 */1057 1058 public int CopyData(Byte[] _data)1059 {1060 _data = http://www.mamicode.com/new Byte[BITS_TO_BYTES(numberOfBitsUsed)];1061 data.CopyTo(_data, 0);1062 return numberOfBitsUsed;1063 }1064 1065 /**1066 * Set the stream to some initial data. For internal use1067 * Partial bytes are left aligned1068 * @param input The data1069 * @param numberOfBits the number of bits set in the data buffer 1070 */1071 1072 public void SetData(Byte[] input, int numberOfBits)1073 {1074 if (numberOfBits <= 0)1075 return;1076 AddBitsAndReallocate(numberOfBits);1077 input.CopyTo(data, 0);1078 numberOfBitsUsed = numberOfBits;1079 }1080 1081 /**1082 * Exposes the internal data.1083 * Partial bytes are left aligned.1084 * @return A pointer to the internal state 1085 */1086 1087 public Byte[] GetData()1088 {1089 return data;1090 }1091 1092 /**1093 * Write numberToWrite bits from the input source Right aligned1094 * data means in the case of a partial byte, the bits are aligned1095 * from the right (bit 0) rather than the left (as in the normal1096 * internal representation) You would set this to true when1097 * writing user data, and false when copying bitstream data, such1098 * as writing one bitstream to another1099 * @param input The data 1100 * @param numberOfBitsToWrite The number of bits to write 1101 * @param rightAlignedBits if true data will be right aligned 1102 */1103 1104 public void WriteBits(Byte[] input, int numberOfBitsToWrite, bool rightAlignedBits = true)1105 {1106 AddBitsAndReallocate(numberOfBitsToWrite);1107 int offset = 0;1108 Byte dataByte;1109 int numberOfBitsUsedMod8;1110 1111 numberOfBitsUsedMod8 = numberOfBitsUsed%8;1112 1113 // Faster to put the while at the top surprisingly enough1114 while (numberOfBitsToWrite > 0)1115 //do1116 {1117 dataByte = input[offset]; //*( input + offset );1118 1119 if (numberOfBitsToWrite < 8 && rightAlignedBits)1120 // rightAlignedBits means in the case of a partial byte, the bits are aligned from the right (bit 0) rather than the left (as in the normal internal representation)1121 dataByte <<= 8 - numberOfBitsToWrite;1122 // shift left to get the bits on the left, as in our internal representation1123 1124 // Writing to a new byte each time1125 if (numberOfBitsUsedMod8 == 0)1126 data[numberOfBitsUsed >> 3] = dataByte; //*( data + ( numberOfBitsUsed >> 3 ) ) = dataByte;1127 else1128 {1129 // Copy over the new data.1130 data[numberOfBitsUsed >> 3] |= (Byte) (dataByte >> (numberOfBitsUsedMod8));1131 //*( data + ( numberOfBitsUsed >> 3 ) ) |= dataByte >> ( numberOfBitsUsedMod8 ); // First half1132 1133 if (8 - (numberOfBitsUsedMod8) < 8 && 8 - (numberOfBitsUsedMod8) < numberOfBitsToWrite)1134 // If we didn‘t write it all out in the first half (8 - (numberOfBitsUsed%8) is the number we wrote in the first half)1135 {1136 //*( data + ( numberOfBitsUsed >> 3 ) + 1 ) = (unsigned char) ( dataByte << ( 8 - ( numberOfBitsUsedMod8 ) ) ); // Second half (overlaps byte boundary)1137 data[(numberOfBitsUsed >> 3) + 1] = (Byte) (dataByte << (8 - (numberOfBitsUsedMod8)));1138 }1139 }1140 1141 if (numberOfBitsToWrite >= 8)1142 numberOfBitsUsed += 8;1143 else1144 numberOfBitsUsed += numberOfBitsToWrite;1145 1146 numberOfBitsToWrite -= 8;1147 1148 offset++;1149 }1150 }1151 1152 /**1153 * Align the bitstream to the byte boundary and then write the1154 * specified number of bits. This is faster than WriteBits but1155 * wastes the bits to do the alignment and requires you to call1156 * ReadAlignedBits at the corresponding read position.1157 * @param input The data1158 * @param numberOfBytesToWrite The size of data. 1159 */1160 1161 public void WriteAlignedBytes(Byte[] input, int numberOfBytesToWrite)1162 {1163 AlignWriteToByteBoundary();1164 // Allocate enough memory to hold everything1165 AddBitsAndReallocate(numberOfBytesToWrite << 3);1166 1167 // Write the data1168 //memcpy( data + ( numberOfBitsUsed >> 3 ), input, numberOfBytesToWrite );1169 input.CopyTo(data, (numberOfBitsUsed >> 3));1170 numberOfBitsUsed += numberOfBytesToWrite << 3;1171 }1172 1173 /**1174 * Read bits, starting at the next aligned bits. Note that the1175 * modulus 8 starting offset of the sequence must be the same as1176 * was used with WriteBits. This will be a problem with packet1177 * coalescence unless you byte align the coalesced packets.1178 * @param output The byte array larger than @em numberOfBytesToRead1179 * @param numberOfBytesToRead The number of byte to read from the internal state 1180 * @return true if there is enough byte. 1181 */1182 1183 public bool ReadAlignedBytes(out Byte[] output, int numberOfBytesToRead)1184 {1185 if (numberOfBytesToRead <= 0)1186 {1187 output = null;1188 return false;1189 }1190 // Byte align1191 AlignReadToByteBoundary();1192 if (readOffset + (numberOfBytesToRead << 3) > numberOfBitsUsed)1193 {1194 output = null;1195 return false;1196 }1197 1198 // Write the data1199 //memcpy( output, data + ( readOffset >> 3 ), numberOfBytesToRead );1200 output = new byte[] {};1201 Array.Copy(data, readOffset >> 3, output, 0, numberOfBytesToRead);1202 readOffset += numberOfBytesToRead << 3;1203 return true;1204 }1205 1206 /**1207 * Align the next write and/or read to a byte boundary. This can1208 * be used to ‘waste‘ bits to byte align for efficiency reasons It1209 * can also be used to force coalesced bitstreams to start on byte1210 * boundaries so so WriteAlignedBits and ReadAlignedBits both1211 * calculate the same offset when aligning.1212 */1213 1214 public void AlignWriteToByteBoundary()1215 {1216 if (numberOfBitsUsed > 0)1217 numberOfBitsUsed += 8 - ((numberOfBitsUsed - 1)%8 + 1);1218 }1219 1220 /**1221 * Align the next write and/or read to a byte boundary. This can1222 * be used to ‘waste‘ bits to byte align for efficiency reasons It1223 * can also be used to force coalesced bitstreams to start on byte1224 * boundaries so so WriteAlignedBits and ReadAlignedBits both1225 * calculate the same offset when aligning.1226 */1227 1228 public void AlignReadToByteBoundary()1229 {1230 if (readOffset > 0)1231 readOffset += 8 - ((readOffset - 1)%8 + 1);1232 }1233 1234 /**1235 * Read numberOfBitsToRead bits to the output source1236 * alignBitsToRight should be set to true to convert internal1237 * bitstream data to userdata It should be false if you used1238 * WriteBits with rightAlignedBits false1239 * @param output The resulting bits array 1240 * @param numberOfBitsToRead The number of bits to read 1241 * @param alignsBitsToRight if true bits will be right aligned. 1242 * @return true if there is enough bits to read 1243 */1244 1245 public bool ReadBits(ref Byte[] output, int numberOfBitsToRead, bool alignBitsToRight = true)1246 {1247 if (readOffset + numberOfBitsToRead > numberOfBitsUsed)1248 {1249 output = null;1250 return false;1251 }1252 1253 int readOffsetMod8;1254 int offset = 0;1255 //memset( output, 0, BITS_TO_BYTES( numberOfBitsToRead ) );1256 readOffsetMod8 = readOffset%8;1257 1258 // do1259 // Faster to put the while at the top surprisingly enough1260 while (numberOfBitsToRead > 0)1261 {1262 //*( output + offset ) |= *( data + ( readOffset >> 3 ) ) << ( readOffsetMod8 ); // First half1263 output[offset] |= (Byte) (data[readOffset >> 3] << (readOffsetMod8));1264 if (readOffsetMod8 > 0 && numberOfBitsToRead > 8 - (readOffsetMod8))1265 // If we have a second half, we didn‘t read enough bytes in the first half1266 //*(output + offset) |= *(data + (readOffset >> 3) + 1) >> (8 - (readOffsetMod8));1267 output[offset] |= (Byte) (data[(readOffset >> 3) + 1] >> (8 - (readOffsetMod8)));1268 // Second half (overlaps byte boundary)1269 1270 numberOfBitsToRead -= 8;1271 1272 if (numberOfBitsToRead < 0)1273 // Reading a partial byte for the last byte, shift right so the data is aligned on the right1274 {1275 if (alignBitsToRight)1276 output[offset] >>= -numberOfBitsToRead;1277 //*(output + offset) >>= -numberOfBitsToRead;1278 1279 readOffset += 8 + numberOfBitsToRead;1280 }1281 else1282 readOffset += 8;1283 1284 offset++;1285 }1286 return true;1287 }1288 1289 /**1290 * --- Low level functions --- 1291 * These are for when you want to deal1292 * with bits and don‘t care about type checking 1293 * Write a 0 1294 */1295 1296 public void Write0()1297 {1298 AddBitsAndReallocate(1);1299 1300 // New bytes need to be zeroed1301 1302 if ((numberOfBitsUsed%8) == 0)1303 data[numberOfBitsUsed >> 3] = 0;1304 1305 numberOfBitsUsed++;1306 }1307 1308 /**1309 * --- Low level functions --- 1310 * These are for when you want to deal1311 * with bits and don‘t care about type checking 1312 * Write a 1 1313 */1314 1315 public void Write1()1316 {1317 AddBitsAndReallocate(1);1318 1319 int numberOfBitsMod8 = numberOfBitsUsed%8;1320 1321 if (numberOfBitsMod8 == 0)1322 data[numberOfBitsUsed >> 3] = 0x80;1323 else1324 data[numberOfBitsUsed >> 3] |= (Byte) (0x80 >> (numberOfBitsMod8));1325 //data[ numberOfBitsUsed >> 3 ] |= 0x80 >> ( numberOfBitsMod8 ); // Set the bit to 11326 1327 numberOfBitsUsed++;1328 }1329 1330 /**1331 * --- Low level functions --- 1332 * These are for when you want to deal1333 * with bits and don‘t care about type checking 1334 * Reads 1 bit and returns true if that bit is 1 and false if it is 01335 */1336 1337 public bool ReadBit()1338 {1339 return (data[readOffset >> 3] & (0x80 >> (readOffset++%8))) == 1;1340 }1341 1342 /**1343 * If we used the constructor version with copy data off, this1344 * makes sure it is set to on and the data pointed to is copied.1345 */1346 1347 public void AssertCopyData()1348 {1349 if (copyData =http://www.mamicode.com/= false)1350 {1351 copyData = http://www.mamicode.com/true;1352 1353 if (numberOfBitsAllocated > 0)1354 {1355 var newdata = http://www.mamicode.com/new Byte[BITS_TO_BYTES(numberOfBitsAllocated)];1356 data.CopyTo(newdata, 0);1357 data =http://www.mamicode.com/ newdata;1358 }1359 else1360 data = http://www.mamicode.com/null;1361 }1362 }1363 1364 /**1365 * Use this if you pass a pointer copy to the constructor1366 * (_copyData=http://www.mamicode.com/=false) and want to overallocate to prevent>1367 * reallocation1368 */1369 1370 public void SetNumberOfBitsAllocated(int lengthInBits)1371 {1372 numberOfBitsAllocated = lengthInBits;1373 }1374 1375 1376 /**1377 * Assume the input source points to a native type, compress and write it.1378 */1379 1380 public void WriteCompressed(Byte[] input, int size, bool unsignedData)1381 {1382 int currentByte = (size >> 3) - 1; // PCs1383 1384 Byte byteMatch;1385 1386 if (unsignedData)1387 {1388 byteMatch = 0;1389 }1390 1391 else1392 {1393 byteMatch = 0xFF;1394 }1395 1396 // Write upper bytes with a single 11397 // From high byte to low byte, if high byte is a byteMatch then write a 1 bit. Otherwise write a 0 bit and then write the remaining bytes1398 while (currentByte > 0)1399 {1400 if (input[currentByte] == byteMatch)1401 // If high byte is byteMatch (0 of 0xff) then it would have the same value shifted1402 {1403 bool b = true;1404 WriteBool(b);1405 }1406 else1407 {1408 // Write the remainder of the data after writing 01409 bool b = false;1410 WriteBool(b);1411 1412 WriteBits(input, (currentByte + 1) << 3, true);1413 // currentByte--;1414 1415 1416 return;1417 }1418 1419 currentByte--;1420 }1421 1422 // If the upper half of the last byte is a 0 (positive) or 16 (negative) then write a 1 and the remaining 4 bits. Otherwise write a 0 and the 8 bites.1423 if ((unsignedData && (((input[currentByte])) & 0xF0) == 0x00) ||1424 (unsignedData =http://www.mamicode.com/= false && (((input[currentByte])) & 0xF0) == 0xF0))1425 {1426 bool b = true;1427 WriteBool(b);1428 var bs = new byte[4];1429 Array.Copy(input, currentByte, bs, 0, 4);1430 WriteBits(bs, 4, true);1431 }1432 1433 else1434 {1435 bool b = false;1436 WriteBool(b);1437 var bs = new byte[9];1438 Array.Copy(input, currentByte, bs, 0, 9);1439 WriteBits(bs, 8, true);1440 }1441 }1442 1443 /**1444 * Assume the input source points to a compressed native type.1445 * Decompress and read it.1446 */1447 1448 public bool ReadCompressed(ref Byte[] output, int size, bool unsignedData)1449 {1450 int currentByte = (size >> 3) - 1;1451 1452 1453 Byte byteMatch, halfByteMatch;1454 1455 if (unsignedData)1456 {1457 byteMatch = 0;1458 halfByteMatch = 0;1459 }1460 1461 else1462 {1463 byteMatch = 0xFF;1464 halfByteMatch = 0xF0;1465 }1466 1467 // Upper bytes are specified with a single 1 if they match byteMatch1468 // From high byte to low byte, if high byte is a byteMatch then write a 1 bit. Otherwise write a 0 bit and then write the remaining bytes1469 while (currentByte > 0)1470 {1471 // If we read a 1 then the data is byteMatch.1472 1473 bool b = ReadBool();1474 1475 if (b) // Check that bit1476 {1477 output[currentByte] = byteMatch;1478 currentByte--;1479 }1480 else1481 {1482 // Read the rest of the bytes1483 1484 if (ReadBits(ref output, (currentByte + 1) << 3) == false)1485 return false;1486 1487 return true;1488 }1489 }1490 return false;1491 }1492 1493 /**1494 * Reallocates (if necessary) in preparation of writing1495 * numberOfBitsToWrite 1496 */1497 1498 public void AddBitsAndReallocate(int numberOfBitsToWrite)1499 {1500 if (numberOfBitsToWrite <= 0)1501 return;1502 1503 int newNumberOfBitsAllocated = numberOfBitsToWrite + numberOfBitsUsed;1504 1505 if (numberOfBitsToWrite + numberOfBitsUsed > 0 &&1506 ((numberOfBitsAllocated - 1) >> 3) < ((newNumberOfBitsAllocated - 1) >> 3))1507 // If we need to allocate 1 or more new bytes1508 {1509 // Less memory efficient but saves on news and deletes1510 newNumberOfBitsAllocated = (numberOfBitsToWrite + numberOfBitsUsed)*2;1511 // int newByteOffset = BITS_TO_BYTES( numberOfBitsAllocated );1512 // Use realloc and free so we are more efficient than delete and new for resizing1513 int amountToAllocate = BITS_TO_BYTES(newNumberOfBitsAllocated);1514 if (data =http://www.mamicode.com/= stackData)1515 {1516 if (amountToAllocate > BITSTREAM_STACK_ALLOCATION_SIZE)1517 {1518 data = http://www.mamicode.com/new byte[amountToAllocate];1519 1520 // need to copy the stack data over to our new memory area too1521 stackData.CopyTo(data, 0);1522 }1523 }1524 else1525 {1526 data = http://www.mamicode.com/data.Concat(new Byte[amountToAllocate - data.Length]).ToArray();1527 //data = http://www.mamicode.com/( unsigned char* ) realloc( data, amountToAllocate );1528 }1529 // memset(data+newByteOffset, 0, ((newNumberOfBitsAllocated-1)>>3) - ((numberOfBitsAllocated-1)>>3)); // Set the new data block to 01530 }1531 1532 if (newNumberOfBitsAllocated > numberOfBitsAllocated)1533 numberOfBitsAllocated = newNumberOfBitsAllocated;1534 }1535 1536 /**1537 * Number of bits currently used 1538 */1539 private int numberOfBitsUsed;1540 /**1541 * Number of bits currently allocated 1542 */1543 1544 private1545 int numberOfBitsAllocated;1546 1547 /**1548 * Current readOffset 1549 */1550 1551 private1552 int readOffset;1553 1554 /**1555 * array of byte storing the data. Points to stackData or if is bigger than that then is allocated1556 */1557 1558 private1559 Byte[] data;1560 1561 /**1562 * true if the internal buffer is copy of the data passed to the1563 * constructor1564 */1565 1566 private1567 bool copyData;1568 1569 private Byte[] stackData = http://www.mamicode.com/new Byte[BITSTREAM_STACK_ALLOCATION_SIZE];1570 }
C#版BitStream 1.0
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。