首页 / C# / C#版BitStream 1.0
C#版BitStream 1.0
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#版BitStream 1.0,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含44446字,纯文字阅读大概需要64分钟。
内容图文
根据C++版的改编,刚刚改完,估计使用会有问题,对于uint8处理的不好
关于使用:
1 BitStream bs = new BitStream( ); 2 bs.WriteInt32( 123 ); 34int 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. 5privatestaticreadonlyint B16_1 = 0; 6privatestaticreadonlyint B16_0 = 1; 7 8privatestaticreadonlyint B32_3 = 0; 9privatestaticreadonlyint B32_2 = 1; 10privatestaticreadonlyint B32_1 = 2; 11privatestaticreadonlyint B32_0 = 3; 12 13privatestaticreadonlyint B64_7 = 0; 14privatestaticreadonlyint B64_6 = 1; 15privatestaticreadonlyint B64_5 = 2; 16privatestaticreadonlyint B64_4 = 3; 17privatestaticreadonlyint B64_3 = 4; 18privatestaticreadonlyint B64_2 = 5; 19privatestaticreadonlyint B64_1 = 6; 20privatestaticreadonlyint B64_0 = 7; 21 22#else 23// Default to producing Little-End network streams. 24privatestaticreadonlyint B16_1 = 1; 25privatestaticreadonlyint B16_0 = 0; 26 27privatestaticreadonlyint B32_3 = 3; 28privatestaticreadonlyint B32_2 = 2; 29privatestaticreadonlyint B32_1 = 1; 30privatestaticreadonlyint B32_0 = 0; 31 32privatestaticreadonlyint B64_7 = 7; 33privatestaticreadonlyint B64_6 = 6; 34privatestaticreadonlyint B64_5 = 5; 35privatestaticreadonlyint B64_4 = 4; 36privatestaticreadonlyint B64_3 = 3; 37privatestaticreadonlyint B64_2 = 2; 38privatestaticreadonlyint B64_1 = 1; 39privatestaticreadonlyint B64_0 = 0; 40#endif 41publicstaticreadonlyint BITSTREAM_STACK_ALLOCATION_SIZE = 2048; 42 43/// Default Constructor 44publicstaticint BITS_TO_BYTES(int x) 45 { 46return (((x) + 7) >> 3); 47 } 48 49publicstaticint BYTES_TO_BITS(int x) 50 { 51return (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 65public BitStream() 66 { 67 numberOfBitsUsed = 0; 68//numberOfBitsAllocated = 32 * 8; 69 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE*8; 70 readOffset = 0; 71//data = ( unsigned char* ) malloc( 32 ); 72 data = stackData; 73 copyData = 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 81public BitStream(int initialBytesToAllocate) 82 { 83 numberOfBitsUsed = 0; 84 readOffset = 0; 85if (initialBytesToAllocate <= BITSTREAM_STACK_ALLOCATION_SIZE) 86 { 87 data = stackData; 88 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE*8; 89 } 90else 91 { 92 data = new Byte[initialBytesToAllocate]; 93 numberOfBitsAllocated = initialBytesToAllocate << 3; 94 } 95 copyData = 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 110public BitStream(Byte[] _data, int lengthInBytes, bool _copyData) 111 { 112 numberOfBitsUsed = lengthInBytes << 3; 113 readOffset = 0; 114 copyData = _copyData; 115 numberOfBitsAllocated = lengthInBytes << 3; 116 117if (copyData) 118 { 119if (lengthInBytes > 0) 120 { 121if (lengthInBytes < BITSTREAM_STACK_ALLOCATION_SIZE) 122 { 123 data = stackData; 124 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE << 3; 125 } 126else 127 { 128 data = new Byte[lengthInBytes]; 129 } 130 _data.CopyTo(data, 0); 131 } 132else 133 data = null; 134 } 135else 136 { 137 data = _data; 138 numberOfBitsUsed = 0; 139 } 140 } 141 142// 143public BitStream(Byte[] _data, int lengthInBytes, int datasize) 144 { 145 numberOfBitsUsed = datasize << 3; 146 readOffset = 0; 147 numberOfBitsAllocated = lengthInBytes << 3; 148 data = _data; 149 copyData = false; 150 } 151 152/** 153 * Destructor 154*/ 155//~BitStream(){} 156/** 157 * Reset the bitstream for reuse 158*/ 159 160privatevoid Reset() 161 { 162if (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 173publicvoid SetBuffer(Byte[] _data, int lengthInBytes, int datasize) 174 { 175 numberOfBitsUsed = datasize << 3; 176 readOffset = 0; 177 numberOfBitsAllocated = lengthInBytes << 3; 178 data = _data; 179 copyData = false; 180 } 181 182publicvoid ClearBuffer() 183 { 184 numberOfBitsUsed = 0; 185 readOffset = 0; 186 numberOfBitsAllocated = 0; 187 data = 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 196publicvoid WriteBool(bool input) 197 { 198if (input) 199 WriteInt8(1); 200else 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 210publicvoid 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 223publicvoid 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 234publicvoid WriteUInt16(UInt16 input) 235 { 236var 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 249publicvoid WriteInt16(Int16 input) 250 { 251var 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 264publicvoid WriteUInt32(UInt32 input) 265 { 266var 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 281publicvoid WriteInt32(int input) 282 { 283var 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 299publicvoid WriteUInt64(UInt64 input) 300 { 301var 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 320publicvoid WriteInt64(Int64 input) 321 { 322var 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 343publicvoid 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 354publicvoid 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 366publicvoid 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 376publicvoid WriteStr(string input) 377 { 378var len = (short) input.Length; 379 WriteUInt16((ushort) len); 380if (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*/ 400publicvoid 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 411publicvoid 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 422publicvoid 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 433publicvoid WriteCompUInt16(UInt16 input) 434 { 435var 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 448publicvoid WriteCompInt16(Int16 input) 449 { 450var 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 463publicvoid WriteCompUInt32(UInt32 input) 464 { 465var 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 480publicvoid WriteCompInt32(int input) 481 { 482var 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 498publicvoid WriteCompUInt64(UInt64 input) 499 { 500var 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 519publicvoid WriteCompInt64(Int64 input) 520 { 521var 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 541publicvoid 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 552publicvoid 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 565publicbool ReadBool() 566 { 567if (readOffset + 1 > numberOfBitsUsed) 568returnfalse; 569 570//if (ReadBit()) // Check that bit 571if ((data[readOffset >> 3] & (0x80 >> (readOffset++%8))) != 0) // Is it faster to just write it out here? 572returntrue; 573 574returnfalse; 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 585public SByte ReadUInt8() 586 { 587var x = new Byte[sizeof (SByte)]; 588if (ReadBits(ref x, sizeof (SByte)*8)) 589 { 590return (SByte) BitConverter.ToChar(x, 0); 591 } 592return0; 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 603public Byte ReadInt8() 604 { 605var x = new Byte[sizeof (Byte)]; 606if (ReadBits(ref x, sizeof (Byte)*8)) 607 { 608return (Byte) BitConverter.ToChar(x, 0); 609 ; 610 } 611return0; 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 622public UInt16 ReadUInt16() 623 { 624var uint16r = new Byte[2]; 625if (ReadBits(ref uint16r, sizeof (UInt16)*8) != true) 626return0; 627return (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 638publicshort ReadInt16() 639 { 640var int16r = new Byte[2]; 641if (ReadBits(ref int16r, sizeof (short)*8) != true) 642return0; 643 644return (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 655public UInt32 ReadUInt32() 656 { 657var uint32r = new Byte[4]; 658if (ReadBits(ref uint32r, sizeof (UInt32)*8) != true) 659return0; 660return (((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 674publicint ReadInt32() 675 { 676var int32r = new Byte[4]; 677if (ReadBits(ref int32r, sizeof (int)*8) != true) 678return0; 679return (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 695public UInt64 ReadUInt64() 696 { 697var uint64r = new Byte[8]; 698if (ReadBits(ref uint64r, sizeof (UInt64)*8) != true) 699return0; 700return (((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 714public Int64 ReadInt64() 715 { 716var int64r = new Byte[8]; 717if (ReadBits(ref int64r, sizeof (Int64)*8) != true) 718return0; 719return (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 734publicfloat ReadFloat() 735 { 736uint val = ReadUInt32(); 737return 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 748publicdouble ReadDouble() 749 { 750 UInt64 val = ReadUInt64(); 751return 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 763publicbool ReadBytes(ref Byte[] output, int numberOfBytes) 764 { 765return ReadBits(ref output, numberOfBytes*8); 766 } 767 768/** 769 * Read standard string 770 * @return 771*/ 772 773publicstring ReadStr() 774 { 775string strs; 776ushort len = ReadUInt16(); 777if (len > 0) 778 { 779var str = new Byte[len + 1]; 780if (ReadBytes(ref str, len)) 781 { 782 str[len] = 10; 783 strs = Encoding.Default.GetString(str); 784return strs; 785 } 786 } 787returnstring.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 796public SByte ReadCompUInt8() 797 { 798var uint8rc = new Byte[sizeof (Byte)]; 799 800if (ReadCompressed(ref uint8rc, sizeof (Byte)*8, true)) 801 { 802return (SByte) uint8rc[0]; 803 } 804return0; 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 813public Byte ReadCompInt8() 814 { 815var uint8rc = new Byte[sizeof (Byte)]; 816 817if (ReadCompressed(ref uint8rc, sizeof (Byte)*8, true)) 818 { 819return uint8rc[0]; 820 } 821return0; 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 830public UInt16 ReadCompUInt16() 831 { 832var uint16rc = new Byte[2]; 833if (ReadCompressed(ref uint16rc, sizeof (UInt16)*8, true) != true) 834return0; 835return (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 845publicshort ReadCompInt16() 846 { 847var int16rc = newbyte[2]; 848if (ReadCompressed(ref int16rc, sizeof (short)*8, false) != true) return0; 849return (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 858public UInt32 ReadCompUInt32() 859 { 860var uint32rc = new Byte[4]; 861if (ReadCompressed(ref uint32rc, sizeof (UInt32)*8, true) != true) 862return0; 863return (((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 875publicint ReadCompInt32() 876 { 877var int32rc = new Byte[4]; 878if (ReadCompressed(ref int32rc, sizeof (int)*8, false) != true) 879return0; 880return (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 893public UInt64 ReadCompUInt64() 894 { 895var uint64rc = new Byte[8]; 896if (ReadCompressed(ref uint64rc, sizeof (UInt64)*8, true) != true) 897return0; 898return (((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 910public Int64 ReadCompInt64() 911 { 912var int64rc = new Byte[8]; 913if (ReadCompressed(ref int64rc, sizeof (Int64)*8, false) != true) 914return0; 915return (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 928publicfloat ReadCompFloat() 929 { 930return 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 939publicdouble ReadCompDouble() 940 { 941return 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 958publicvoid AssertStreamEmpty() 959 { 960if (readOffset == numberOfBitsUsed) 961thrownew 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// */ 976publicvoid 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 989publicvoid SetWriteOffset(int offset) 990 { 991 numberOfBitsUsed = offset; 992 } 993 994/** 995 * Returns the length in bits of the stream 996*/ 997 998publicint GetWriteOffset() 999 { 1000return numberOfBitsUsed; 1001 } 10021003/** 1004 * Returns the length in bytes of the stream 1005*/10061007publicint GetNumberOfBytesUsed() 1008 { 1009return BITS_TO_BYTES(numberOfBitsUsed); 1010 } 10111012publicint GetNumberOfBytesRead() 1013 { 1014return BITS_TO_BYTES(readOffset); 1015 } 10161017/** 1018 * Move the read pointer to a position on the array. 1019 * @param offset 1020*/10211022publicvoid SetReadOffset(int offset) 1023 { 1024 readOffset = offset; 1025 } 10261027publicvoid SetByteReadOffSet(int offset) 1028 { 1029 readOffset = BYTES_TO_BITS(offset); 1030 } 10311032/** 1033 * Returns the number of bits into the stream that we have read 1034*/10351036publicint GetReadOffset() 1037 { 1038return readOffset; 1039 } 104010411042/** 1043 * Returns the number of bits left in the stream that haven‘t been read 1044*/10451046publicint GetNumberOfUnreadBits() 1047 { 1048return numberOfBitsUsed - readOffset; 1049 } 10501051/** 1052 * Makes a copy of the internal data for you Data will point to 1053 * the stream. Returns the length in bits of the stream. Partial 1054 * bytes are left aligned 1055 * @param _data the resulting byte copy of the internal state. 1056*/10571058publicint CopyData(Byte[] _data) 1059 { 1060 _data = new Byte[BITS_TO_BYTES(numberOfBitsUsed)]; 1061 data.CopyTo(_data, 0); 1062return numberOfBitsUsed; 1063 } 10641065/** 1066 * Set the stream to some initial data. For internal use 1067 * Partial bytes are left aligned 1068 * @param input The data 1069 * @param numberOfBits the number of bits set in the data buffer 1070*/10711072publicvoid SetData(Byte[] input, int numberOfBits) 1073 { 1074if (numberOfBits <= 0) 1075return; 1076 AddBitsAndReallocate(numberOfBits); 1077 input.CopyTo(data, 0); 1078 numberOfBitsUsed = numberOfBits; 1079 } 10801081/** 1082 * Exposes the internal data. 1083 * Partial bytes are left aligned. 1084 * @return A pointer to the internal state 1085*/10861087public Byte[] GetData() 1088 { 1089return data; 1090 } 10911092/** 1093 * Write numberToWrite bits from the input source Right aligned 1094 * data means in the case of a partial byte, the bits are aligned 1095 * from the right (bit 0) rather than the left (as in the normal 1096 * internal representation) You would set this to true when 1097 * writing user data, and false when copying bitstream data, such 1098 * as writing one bitstream to another 1099 * @param input The data 1100 * @param numberOfBitsToWrite The number of bits to write 1101 * @param rightAlignedBits if true data will be right aligned 1102*/11031104publicvoid WriteBits(Byte[] input, int numberOfBitsToWrite, bool rightAlignedBits = true) 1105 { 1106 AddBitsAndReallocate(numberOfBitsToWrite); 1107int offset = 0; 1108 Byte dataByte; 1109int numberOfBitsUsedMod8; 11101111 numberOfBitsUsedMod8 = numberOfBitsUsed%8; 11121113// Faster to put the while at the top surprisingly enough1114while (numberOfBitsToWrite > 0) 1115//do1116 { 1117 dataByte = input[offset]; //*( input + offset );11181119if (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 representation 11231124// Writing to a new byte each time1125if (numberOfBitsUsedMod8 == 0) 1126 data[numberOfBitsUsed >> 3] = dataByte; //*( data + ( numberOfBitsUsed >> 3 ) ) = dataByte;1127else1128 { 1129// Copy over the new data.1130 data[numberOfBitsUsed >> 3] |= (Byte) (dataByte >> (numberOfBitsUsedMod8)); 1131//*( data + ( numberOfBitsUsed >> 3 ) ) |= dataByte >> ( numberOfBitsUsedMod8 ); // First half11321133if (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 } 11401141if (numberOfBitsToWrite >= 8) 1142 numberOfBitsUsed += 8; 1143else1144 numberOfBitsUsed += numberOfBitsToWrite; 11451146 numberOfBitsToWrite -= 8; 11471148 offset++; 1149 } 1150 } 11511152/** 1153 * Align the bitstream to the byte boundary and then write the 1154 * specified number of bits. This is faster than WriteBits but 1155 * wastes the bits to do the alignment and requires you to call 1156 * ReadAlignedBits at the corresponding read position. 1157 * @param input The data 1158 * @param numberOfBytesToWrite The size of data. 1159*/11601161publicvoid WriteAlignedBytes(Byte[] input, int numberOfBytesToWrite) 1162 { 1163 AlignWriteToByteBoundary(); 1164// Allocate enough memory to hold everything1165 AddBitsAndReallocate(numberOfBytesToWrite << 3); 11661167// Write the data 1168//memcpy( data + ( numberOfBitsUsed >> 3 ), input, numberOfBytesToWrite );1169 input.CopyTo(data, (numberOfBitsUsed >> 3)); 1170 numberOfBitsUsed += numberOfBytesToWrite << 3; 1171 } 11721173/** 1174 * Read bits, starting at the next aligned bits. Note that the 1175 * modulus 8 starting offset of the sequence must be the same as 1176 * was used with WriteBits. This will be a problem with packet 1177 * coalescence unless you byte align the coalesced packets. 1178 * @param output The byte array larger than @em numberOfBytesToRead 1179 * @param numberOfBytesToRead The number of byte to read from the internal state 1180 * @return true if there is enough byte. 1181*/11821183publicbool ReadAlignedBytes(out Byte[] output, int numberOfBytesToRead) 1184 { 1185if (numberOfBytesToRead <= 0) 1186 { 1187 output = null; 1188returnfalse; 1189 } 1190// Byte align1191 AlignReadToByteBoundary(); 1192if (readOffset + (numberOfBytesToRead << 3) > numberOfBitsUsed) 1193 { 1194 output = null; 1195returnfalse; 1196 } 11971198// Write the data 1199//memcpy( output, data + ( readOffset >> 3 ), numberOfBytesToRead );1200 output = newbyte[] {}; 1201 Array.Copy(data, readOffset >> 3, output, 0, numberOfBytesToRead); 1202 readOffset += numberOfBytesToRead << 3; 1203returntrue; 1204 } 12051206/** 1207 * Align the next write and/or read to a byte boundary. This can 1208 * be used to ‘waste‘ bits to byte align for efficiency reasons It 1209 * can also be used to force coalesced bitstreams to start on byte 1210 * boundaries so so WriteAlignedBits and ReadAlignedBits both 1211 * calculate the same offset when aligning. 1212*/12131214publicvoid AlignWriteToByteBoundary() 1215 { 1216if (numberOfBitsUsed > 0) 1217 numberOfBitsUsed += 8 - ((numberOfBitsUsed - 1)%8 + 1); 1218 } 12191220/** 1221 * Align the next write and/or read to a byte boundary. This can 1222 * be used to ‘waste‘ bits to byte align for efficiency reasons It 1223 * can also be used to force coalesced bitstreams to start on byte 1224 * boundaries so so WriteAlignedBits and ReadAlignedBits both 1225 * calculate the same offset when aligning. 1226*/12271228publicvoid AlignReadToByteBoundary() 1229 { 1230if (readOffset > 0) 1231 readOffset += 8 - ((readOffset - 1)%8 + 1); 1232 } 12331234/** 1235 * Read numberOfBitsToRead bits to the output source 1236 * alignBitsToRight should be set to true to convert internal 1237 * bitstream data to userdata It should be false if you used 1238 * WriteBits with rightAlignedBits false 1239 * @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*/12441245publicbool ReadBits(ref Byte[] output, int numberOfBitsToRead, bool alignBitsToRight = true) 1246 { 1247if (readOffset + numberOfBitsToRead > numberOfBitsUsed) 1248 { 1249 output = null; 1250returnfalse; 1251 } 12521253int readOffsetMod8; 1254int offset = 0; 1255//memset( output, 0, BITS_TO_BYTES( numberOfBitsToRead ) );1256 readOffsetMod8 = readOffset%8; 12571258// do 1259// Faster to put the while at the top surprisingly enough1260while (numberOfBitsToRead > 0) 1261 { 1262//*( output + offset ) |= *( data + ( readOffset >> 3 ) ) << ( readOffsetMod8 ); // First half1263 output[offset] |= (Byte) (data[readOffset >> 3] << (readOffsetMod8)); 1264if (readOffsetMod8 > 0 && numberOfBitsToRead > 8 - (readOffsetMod8)) 1265// If we have a second half, we didn‘t read enough bytes in the first half 1266//*(output + offset) |= *(data + (readOffset >> 3) + 1) >> (8 - (readOffsetMod8));1267 output[offset] |= (Byte) (data[(readOffset >> 3) + 1] >> (8 - (readOffsetMod8))); 1268// Second half (overlaps byte boundary)12691270 numberOfBitsToRead -= 8; 12711272if (numberOfBitsToRead < 0) 1273// Reading a partial byte for the last byte, shift right so the data is aligned on the right1274 { 1275if (alignBitsToRight) 1276 output[offset] >>= -numberOfBitsToRead; 1277//*(output + offset) >>= -numberOfBitsToRead;12781279 readOffset += 8 + numberOfBitsToRead; 1280 } 1281else1282 readOffset += 8; 12831284 offset++; 1285 } 1286returntrue; 1287 } 12881289/** 1290 * --- Low level functions --- 1291 * These are for when you want to deal 1292 * with bits and don‘t care about type checking 1293 * Write a 0 1294*/12951296publicvoid Write0() 1297 { 1298 AddBitsAndReallocate(1); 12991300// New bytes need to be zeroed13011302if ((numberOfBitsUsed%8) == 0) 1303 data[numberOfBitsUsed >> 3] = 0; 13041305 numberOfBitsUsed++; 1306 } 13071308/** 1309 * --- Low level functions --- 1310 * These are for when you want to deal 1311 * with bits and don‘t care about type checking 1312 * Write a 1 1313*/13141315publicvoid Write1() 1316 { 1317 AddBitsAndReallocate(1); 13181319int numberOfBitsMod8 = numberOfBitsUsed%8; 13201321if (numberOfBitsMod8 == 0) 1322 data[numberOfBitsUsed >> 3] = 0x80; 1323else1324 data[numberOfBitsUsed >> 3] |= (Byte) (0x80 >> (numberOfBitsMod8)); 1325//data[ numberOfBitsUsed >> 3 ] |= 0x80 >> ( numberOfBitsMod8 ); // Set the bit to 113261327 numberOfBitsUsed++; 1328 } 13291330/** 1331 * --- Low level functions --- 1332 * These are for when you want to deal 1333 * 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 0 1335*/13361337publicbool ReadBit() 1338 { 1339return (data[readOffset >> 3] & (0x80 >> (readOffset++%8))) == 1; 1340 } 13411342/** 1343 * If we used the constructor version with copy data off, this 1344 * makes sure it is set to on and the data pointed to is copied. 1345*/13461347publicvoid AssertCopyData() 1348 { 1349if (copyData == false) 1350 { 1351 copyData = true; 13521353if (numberOfBitsAllocated > 0) 1354 { 1355var newdata = new Byte[BITS_TO_BYTES(numberOfBitsAllocated)]; 1356 data.CopyTo(newdata, 0); 1357 data = newdata; 1358 } 1359else1360 data = null; 1361 } 1362 } 13631364/** 1365 * Use this if you pass a pointer copy to the constructor 1366 * (_copyData==false) and want to overallocate to prevent 1367 * reallocation 1368*/13691370publicvoid SetNumberOfBitsAllocated(int lengthInBits) 1371 { 1372 numberOfBitsAllocated = lengthInBits; 1373 } 137413751376/** 1377 * Assume the input source points to a native type, compress and write it. 1378*/13791380publicvoid WriteCompressed(Byte[] input, int size, bool unsignedData) 1381 { 1382int currentByte = (size >> 3) - 1; // PCs13831384 Byte byteMatch; 13851386if (unsignedData) 1387 { 1388 byteMatch = 0; 1389 } 13901391else1392 { 1393 byteMatch = 0xFF; 1394 } 13951396// Write upper bytes with a single 1 1397// 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 bytes1398while (currentByte > 0) 1399 { 1400if (input[currentByte] == byteMatch) 1401// If high byte is byteMatch (0 of 0xff) then it would have the same value shifted1402 { 1403bool b = true; 1404 WriteBool(b); 1405 } 1406else1407 { 1408// Write the remainder of the data after writing 01409bool b = false; 1410 WriteBool(b); 14111412 WriteBits(input, (currentByte + 1) << 3, true); 1413// currentByte--;141414151416return; 1417 } 14181419 currentByte--; 1420 } 14211422// 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.1423if ((unsignedData && (((input[currentByte])) & 0xF0) == 0x00) || 1424 (unsignedData == false && (((input[currentByte])) & 0xF0) == 0xF0)) 1425 { 1426bool b = true; 1427 WriteBool(b); 1428var bs = newbyte[4]; 1429 Array.Copy(input, currentByte, bs, 0, 4); 1430 WriteBits(bs, 4, true); 1431 } 14321433else1434 { 1435bool b = false; 1436 WriteBool(b); 1437var bs = newbyte[9]; 1438 Array.Copy(input, currentByte, bs, 0, 9); 1439 WriteBits(bs, 8, true); 1440 } 1441 } 14421443/** 1444 * Assume the input source points to a compressed native type. 1445 * Decompress and read it. 1446*/14471448publicbool ReadCompressed(ref Byte[] output, int size, bool unsignedData) 1449 { 1450int currentByte = (size >> 3) - 1; 145114521453 Byte byteMatch, halfByteMatch; 14541455if (unsignedData) 1456 { 1457 byteMatch = 0; 1458 halfByteMatch = 0; 1459 } 14601461else1462 { 1463 byteMatch = 0xFF; 1464 halfByteMatch = 0xF0; 1465 } 14661467// Upper bytes are specified with a single 1 if they match byteMatch 1468// 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 bytes1469while (currentByte > 0) 1470 { 1471// If we read a 1 then the data is byteMatch.14721473bool b = ReadBool(); 14741475if (b) // Check that bit1476 { 1477 output[currentByte] = byteMatch; 1478 currentByte--; 1479 } 1480else1481 { 1482// Read the rest of the bytes14831484if (ReadBits(ref output, (currentByte + 1) << 3) == false) 1485returnfalse; 14861487returntrue; 1488 } 1489 } 1490returnfalse; 1491 } 14921493/** 1494 * Reallocates (if necessary) in preparation of writing 1495 * numberOfBitsToWrite 1496*/14971498publicvoid AddBitsAndReallocate(int numberOfBitsToWrite) 1499 { 1500if (numberOfBitsToWrite <= 0) 1501return; 15021503int newNumberOfBitsAllocated = numberOfBitsToWrite + numberOfBitsUsed; 15041505if (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 resizing1513int amountToAllocate = BITS_TO_BYTES(newNumberOfBitsAllocated); 1514if (data == stackData) 1515 { 1516if (amountToAllocate > BITSTREAM_STACK_ALLOCATION_SIZE) 1517 { 1518 data = newbyte[amountToAllocate]; 15191520// need to copy the stack data over to our new memory area too1521 stackData.CopyTo(data, 0); 1522 } 1523 } 1524else1525 { 1526 data = data.Concat(new Byte[amountToAllocate - data.Length]).ToArray(); 1527//data = ( unsigned char* ) realloc( data, amountToAllocate );1528 } 1529// memset(data+newByteOffset, 0, ((newNumberOfBitsAllocated-1)>>3) - ((numberOfBitsAllocated-1)>>3)); // Set the new data block to 01530 } 15311532if (newNumberOfBitsAllocated > numberOfBitsAllocated) 1533 numberOfBitsAllocated = newNumberOfBitsAllocated; 1534 } 15351536/** 1537 * Number of bits currently used 1538*/1539privateint numberOfBitsUsed; 1540/** 1541 * Number of bits currently allocated 1542*/15431544private1545int numberOfBitsAllocated; 15461547/** 1548 * Current readOffset 1549*/15501551private1552int readOffset; 15531554/** 1555 * array of byte storing the data. Points to stackData or if is bigger than that then is allocated 1556*/15571558private1559 Byte[] data; 15601561/** 1562 * true if the internal buffer is copy of the data passed to the 1563 * constructor 1564*/15651566private1567bool copyData; 15681569private Byte[] stackData = new Byte[BITSTREAM_STACK_ALLOCATION_SIZE]; 1570 }
原文:http://www.cnblogs.com/ishowfun/p/4026834.html
内容总结
以上是互联网集市为您收集整理的C#版BitStream 1.0全部内容,希望文章能够帮你解决C#版BitStream 1.0所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。