@@ -67,7 +67,7 @@ public BitStream(byte[] target)
6767 {
6868 this . target = target ;
6969 Resizable = false ;
70- BitLength = ( ulong ) ( target . Length << 3 ) ;
70+ BitLength = ( ulong ) ( target . Length << 3 ) ;
7171 }
7272
7373 /// <summary>
@@ -99,15 +99,16 @@ public BitStream(byte[] target)
9999 /// <summary>
100100 /// Current buffer size. The buffer will not be resized (if possible) until Position is equal to Capacity and an attempt to write data is made.
101101 /// </summary>
102- public long Capacity {
102+ public long Capacity
103+ {
103104 get => target . LongLength ; // Optimized CeilingExact
104105 set
105106 {
106107 if ( value < Length ) throw new ArgumentOutOfRangeException ( "New capcity too small!" ) ;
107108 SetCapacity ( value ) ;
108109 }
109110 }
110-
111+
111112 /// <summary>
112113 /// The current length of data considered to be "written" to the buffer.
113114 /// </summary>
@@ -116,7 +117,7 @@ public long Capacity {
116117 /// <summary>
117118 /// The index that will be written to when any call to write data is made to this stream.
118119 /// </summary>
119- public override long Position { get => ( long ) ( BitPosition >> 3 ) ; set => BitPosition = ( ulong ) value << 3 ; }
120+ public override long Position { get => ( long ) ( BitPosition >> 3 ) ; set => BitPosition = ( ulong ) value << 3 ; }
120121
121122 /// <summary>
122123 /// Bit offset into the buffer that new data will be written to.
@@ -146,7 +147,7 @@ public override void Flush() { } // NOP
146147 private byte ReadByteMisaligned ( )
147148 {
148149 int mod = ( int ) ( BitPosition & 7 ) ;
149- return ( byte ) ( ( target [ ( int ) Position ++ ] >> mod ) | ( target [ ( int ) Position ] << ( 8 - mod ) ) ) ;
150+ return ( byte ) ( ( target [ ( int ) Position ] >> mod ) | ( target [ ( int ) ( BitPosition += 8 ) >> 3 ] << ( 8 - mod ) ) ) ;
150151 }
151152 /// <summary>
152153 /// Read an aligned byte from the buffer. It's recommended to not use this when the BitPosition is byte-misaligned.
@@ -224,8 +225,9 @@ private void SetCapacity(long value)
224225 public override void SetLength ( long value )
225226 {
226227 if ( value < 0 ) throw new IndexOutOfRangeException ( "Cannot set a negative length!" ) ;
227- if ( value > Capacity ) Grow ( value - Capacity ) ;
228+ if ( value > Capacity ) Grow ( value - Capacity ) ;
228229 BitLength = ( ulong ) value << 3 ;
230+ BitPosition = Math . Min ( ( ulong ) value << 3 , BitPosition ) ;
229231 }
230232
231233 /// <summary>
@@ -271,7 +273,7 @@ public void WriteBit(bool bit)
271273 {
272274 if ( BitAligned && Position == target . Length ) Grow ( 1 ) ;
273275 int offset = ( int ) ( BitPosition & 7 ) ;
274- ulong pos = BitPosition >> 3 ;
276+ long pos = Position ;
275277 ++ BitPosition ;
276278 target [ pos ] = ( byte ) ( bit ? ( target [ pos ] & ~ ( 1 << offset ) ) | ( 1 << offset ) : ( target [ pos ] & ~ ( 1 << offset ) ) ) ;
277279 UpdateLength ( ) ;
@@ -313,7 +315,7 @@ public void WriteDouble(double value)
313315 /// <param name="value">Value to write</param>
314316 public void WriteSinglePacked ( float value )
315317 {
316- lock ( holder_f )
318+ lock ( holder_f )
317319 lock ( holder_i )
318320 {
319321 holder_f [ 0 ] = value ;
@@ -470,8 +472,8 @@ public void WriteRangedSingle(float value, float minValue, float maxValue, int b
470472 {
471473 if ( bytes < 1 || bytes > 4 ) throw new ArgumentOutOfRangeException ( "Result must occupy between 1 and 4 bytes!" ) ;
472474 if ( value < minValue || value > maxValue ) throw new ArgumentOutOfRangeException ( "Given value does not match the given constraints!" ) ;
473- uint result = ( uint ) ( ( ( value + minValue ) / ( maxValue + minValue ) ) * ( ( 0x100 * bytes ) - 1 ) ) ;
474- for ( int i = 0 ; i < bytes ; ++ i ) _WriteByte ( ( byte ) ( result >> ( i << 3 ) ) ) ;
475+ uint result = ( uint ) ( ( ( value + minValue ) / ( maxValue + minValue ) ) * ( ( 0x100 * bytes ) - 1 ) ) ;
476+ for ( int i = 0 ; i < bytes ; ++ i ) _WriteByte ( ( byte ) ( result >> ( i << 3 ) ) ) ;
475477 }
476478
477479 /// <summary>
@@ -485,7 +487,7 @@ public void WriteRangedDouble(double value, double minValue, double maxValue, in
485487 {
486488 if ( bytes < 1 || bytes > 8 ) throw new ArgumentOutOfRangeException ( "Result must occupy between 1 and 8 bytes!" ) ;
487489 if ( value < minValue || value > maxValue ) throw new ArgumentOutOfRangeException ( "Given value does not match the given constraints!" ) ;
488- ulong result = ( ulong ) ( ( ( value + minValue ) / ( maxValue + minValue ) ) * ( ( 0x100 * bytes ) - 1 ) ) ;
490+ ulong result = ( ulong ) ( ( ( value + minValue ) / ( maxValue + minValue ) ) * ( ( 0x100 * bytes ) - 1 ) ) ;
489491 for ( int i = 0 ; i < bytes ; ++ i ) _WriteByte ( ( byte ) ( result >> ( i << 3 ) ) ) ;
490492 }
491493
@@ -497,7 +499,7 @@ public void WriteRangedDouble(double value, double minValue, double maxValue, in
497499 public void WriteRotation ( Quaternion rotation , int bytesPerAngle )
498500 {
499501 if ( bytesPerAngle < 1 || bytesPerAngle > 4 ) throw new ArgumentOutOfRangeException ( "Bytes per angle must be at least 1 byte and at most 4 bytes!" ) ;
500- if ( bytesPerAngle == 4 ) WriteVector3 ( rotation . eulerAngles ) ;
502+ if ( bytesPerAngle == 4 ) WriteVector3 ( rotation . eulerAngles ) ;
501503 else
502504 {
503505 Vector3 rot = rotation . eulerAngles ;
@@ -539,15 +541,15 @@ public double ReadDouble()
539541 return holder_d [ 0 ] ;
540542 }
541543 }
542-
544+
543545 /// <summary>
544546 /// Read a single-precision floating point value from the stream from a varint
545547 /// </summary>
546548 /// <returns>The read value</returns>
547549 public float ReadSinglePacked ( )
548550 {
549551 uint read = ReadUInt32Packed ( ) ;
550- lock ( holder_f )
552+ lock ( holder_f )
551553 lock ( holder_i )
552554 {
553555 holder_i [ 0 ] = BinaryHelpers . SwapEndian ( read ) ;
@@ -700,7 +702,7 @@ public void WriteNibble(byte value)
700702 value &= 0x0F ;
701703 int offset = ( int ) ( BitPosition & 7 ) , offset_inv = 8 - offset ;
702704 target [ Position ] = ( byte ) ( ( target [ Position ] & ( 0xFF >> offset_inv ) ) | ( byte ) ( value << offset ) ) ;
703- if ( offset > 4 ) target [ Position + 1 ] = ( byte ) ( ( target [ Position + 1 ] & ( 0xFF << ( offset & 3 ) ) ) | ( byte ) ( value >> offset_inv ) ) ;
705+ if ( offset > 4 ) target [ Position + 1 ] = ( byte ) ( ( target [ Position + 1 ] & ( 0xFF << ( offset & 3 ) ) ) | ( byte ) ( value >> offset_inv ) ) ;
704706 BitPosition += 4 ;
705707 }
706708 UpdateLength ( ) ;
@@ -719,13 +721,13 @@ public void WriteNibble(byte value)
719721 /// <param name="bitCount">Amount of bits to write</param>
720722 public void WriteBits ( ulong value , int bitCount )
721723 {
722- if ( BitPosition + ( ulong ) bitCount > ( ( ulong ) target . LongLength << 3 ) ) Grow ( Div8Ceil ( BitPosition + ( ulong ) bitCount ) ) ;
724+ if ( BitPosition + ( ulong ) bitCount > ( ( ulong ) target . LongLength << 3 ) ) Grow ( Div8Ceil ( BitPosition + ( ulong ) bitCount ) ) ;
723725 if ( bitCount > 64 ) throw new ArgumentOutOfRangeException ( "Cannot read more than 64 bits from a 64-bit value!" ) ;
724726 if ( bitCount < 0 ) throw new ArgumentOutOfRangeException ( "Cannot read fewer than 0 bits!" ) ;
725727 int count = - 8 ;
726- while ( bitCount > ( count += 8 ) ) _WriteULongByte ( value >> count ) ;
728+ while ( bitCount > ( count += 8 ) ) _WriteULongByte ( value >> count ) ;
727729 BitPosition += ( ulong ) count ;
728- if ( ( bitCount & 7 ) != 0 ) _WriteBits ( ( byte ) ( value >> count ) , bitCount & 7 ) ;
730+ if ( ( bitCount & 7 ) != 0 ) _WriteBits ( ( byte ) ( value >> count ) , bitCount & 7 ) ;
729731 UpdateLength ( ) ;
730732 }
731733 /// <summary>
@@ -743,7 +745,7 @@ private void _WriteBits(byte value, int bitCount)
743745 target [ Position ] = ( byte ) (
744746 ( target [ Position ] & ( 0xFF >> offset_inv ) ) | // Bits prior to value (lower)
745747 ( target [ Position ] & ( 0xFF << ( offset + bitCount ) ) ) | // Bits after value (higher)
746- ( value << offset ) // Bits to write
748+ ( value << offset ) // Bits to write
747749 ) ;
748750 if ( bitCount + offset > 8 )
749751 target [ Position + 1 ] = ( byte ) (
@@ -906,15 +908,15 @@ public void WriteUInt64Packed(ulong value)
906908 /// Read an unsigned long (UInt64) from the stream.
907909 /// </summary>
908910 /// <returns>Value read from stream.</returns>
909- public ulong ReadUInt64 ( ) => ( ulong ) (
911+ public ulong ReadUInt64 ( ) => (
910912 _ReadByte ( ) |
911- ( _ReadByte ( ) << 8 ) |
912- ( _ReadByte ( ) << 16 ) |
913- ( _ReadByte ( ) << 24 ) |
914- ( _ReadByte ( ) << 32 ) |
915- ( _ReadByte ( ) << 40 ) |
916- ( _ReadByte ( ) << 48 ) |
917- ( _ReadByte ( ) << 56 )
913+ ( ( ulong ) _ReadByte ( ) << 8 ) |
914+ ( ( ulong ) _ReadByte ( ) << 16 ) |
915+ ( ( ulong ) _ReadByte ( ) << 24 ) |
916+ ( ( ulong ) _ReadByte ( ) << 32 ) |
917+ ( ( ulong ) _ReadByte ( ) << 40 ) |
918+ ( ( ulong ) _ReadByte ( ) << 48 ) |
919+ ( ( ulong ) _ReadByte ( ) << 56 )
918920 ) ;
919921 /// <summary>
920922 /// Read a signed long (Int64) from the stream.
@@ -982,7 +984,7 @@ private void _WriteMisaligned(byte value)
982984 {
983985 int off = ( int ) ( BitPosition & 7 ) ;
984986 int shift1 = 8 - off ;
985- target [ Position + 1 ] = ( byte ) ( ( target [ Position + 1 ] & ( 0xFF >> off ) ) | ( value >> shift1 ) ) ;
987+ target [ Position + 1 ] = ( byte ) ( ( target [ Position + 1 ] & ( 0xFF << off ) ) | ( value >> shift1 ) ) ;
986988 target [ Position ] = ( byte ) ( ( target [ Position ] & ( 0xFF >> shift1 ) ) | ( value << off ) ) ;
987989
988990 BitPosition += 8 ;
@@ -1054,19 +1056,19 @@ public override void WriteByte(byte value)
10541056 /// <param name="count">How many bytes to read. Set to value less than one to read until ReadByte returns -1</param>
10551057 public void CopyFrom ( Stream s , int count = - 1 )
10561058 {
1057- if ( s is BitStream b ) Write ( b . target , 0 , count < 0 ? ( int ) b . Length : count ) ;
1059+ if ( s is BitStream b ) Write ( b . target , 0 , count < 0 ? ( int ) b . Length : count ) ;
10581060 else
10591061 {
10601062 int read ;
10611063 bool readToEnd = count < 0 ;
1062- while ( ( readToEnd || count -- > 0 ) && ( read = s . ReadByte ( ) ) != - 1 )
1064+ while ( ( readToEnd || count -- > 0 ) && ( read = s . ReadByte ( ) ) != - 1 )
10631065 _WriteIntByte ( read ) ;
10641066 UpdateLength ( ) ;
10651067 }
10661068 }
1067-
1069+
10681070 // TODO: Implement CopyFrom() for BitStream with bitCount parameter
1069-
1071+
10701072 /// <summary>
10711073 /// Update length of data considered to be "written" to the stream.
10721074 /// </summary>
0 commit comments