@@ -67,7 +67,7 @@ public BitStream(byte[] target)
67
67
{
68
68
this . target = target ;
69
69
Resizable = false ;
70
- BitLength = ( ulong ) ( target . Length << 3 ) ;
70
+ BitLength = ( ulong ) ( target . Length << 3 ) ;
71
71
}
72
72
73
73
/// <summary>
@@ -99,15 +99,16 @@ public BitStream(byte[] target)
99
99
/// <summary>
100
100
/// 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.
101
101
/// </summary>
102
- public long Capacity {
102
+ public long Capacity
103
+ {
103
104
get => target . LongLength ; // Optimized CeilingExact
104
105
set
105
106
{
106
107
if ( value < Length ) throw new ArgumentOutOfRangeException ( "New capcity too small!" ) ;
107
108
SetCapacity ( value ) ;
108
109
}
109
110
}
110
-
111
+
111
112
/// <summary>
112
113
/// The current length of data considered to be "written" to the buffer.
113
114
/// </summary>
@@ -116,7 +117,7 @@ public long Capacity {
116
117
/// <summary>
117
118
/// The index that will be written to when any call to write data is made to this stream.
118
119
/// </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 ; }
120
121
121
122
/// <summary>
122
123
/// Bit offset into the buffer that new data will be written to.
@@ -146,7 +147,7 @@ public override void Flush() { } // NOP
146
147
private byte ReadByteMisaligned ( )
147
148
{
148
149
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 ) ) ) ;
150
151
}
151
152
/// <summary>
152
153
/// 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)
224
225
public override void SetLength ( long value )
225
226
{
226
227
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 ) ;
228
229
BitLength = ( ulong ) value << 3 ;
230
+ BitPosition = Math . Min ( ( ulong ) value << 3 , BitPosition ) ;
229
231
}
230
232
231
233
/// <summary>
@@ -271,7 +273,7 @@ public void WriteBit(bool bit)
271
273
{
272
274
if ( BitAligned && Position == target . Length ) Grow ( 1 ) ;
273
275
int offset = ( int ) ( BitPosition & 7 ) ;
274
- ulong pos = BitPosition >> 3 ;
276
+ long pos = Position ;
275
277
++ BitPosition ;
276
278
target [ pos ] = ( byte ) ( bit ? ( target [ pos ] & ~ ( 1 << offset ) ) | ( 1 << offset ) : ( target [ pos ] & ~ ( 1 << offset ) ) ) ;
277
279
UpdateLength ( ) ;
@@ -313,7 +315,7 @@ public void WriteDouble(double value)
313
315
/// <param name="value">Value to write</param>
314
316
public void WriteSinglePacked ( float value )
315
317
{
316
- lock ( holder_f )
318
+ lock ( holder_f )
317
319
lock ( holder_i )
318
320
{
319
321
holder_f [ 0 ] = value ;
@@ -470,8 +472,8 @@ public void WriteRangedSingle(float value, float minValue, float maxValue, int b
470
472
{
471
473
if ( bytes < 1 || bytes > 4 ) throw new ArgumentOutOfRangeException ( "Result must occupy between 1 and 4 bytes!" ) ;
472
474
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 ) ) ) ;
475
477
}
476
478
477
479
/// <summary>
@@ -485,7 +487,7 @@ public void WriteRangedDouble(double value, double minValue, double maxValue, in
485
487
{
486
488
if ( bytes < 1 || bytes > 8 ) throw new ArgumentOutOfRangeException ( "Result must occupy between 1 and 8 bytes!" ) ;
487
489
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 ) ) ;
489
491
for ( int i = 0 ; i < bytes ; ++ i ) _WriteByte ( ( byte ) ( result >> ( i << 3 ) ) ) ;
490
492
}
491
493
@@ -497,7 +499,7 @@ public void WriteRangedDouble(double value, double minValue, double maxValue, in
497
499
public void WriteRotation ( Quaternion rotation , int bytesPerAngle )
498
500
{
499
501
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 ) ;
501
503
else
502
504
{
503
505
Vector3 rot = rotation . eulerAngles ;
@@ -539,15 +541,15 @@ public double ReadDouble()
539
541
return holder_d [ 0 ] ;
540
542
}
541
543
}
542
-
544
+
543
545
/// <summary>
544
546
/// Read a single-precision floating point value from the stream from a varint
545
547
/// </summary>
546
548
/// <returns>The read value</returns>
547
549
public float ReadSinglePacked ( )
548
550
{
549
551
uint read = ReadUInt32Packed ( ) ;
550
- lock ( holder_f )
552
+ lock ( holder_f )
551
553
lock ( holder_i )
552
554
{
553
555
holder_i [ 0 ] = BinaryHelpers . SwapEndian ( read ) ;
@@ -700,7 +702,7 @@ public void WriteNibble(byte value)
700
702
value &= 0x0F ;
701
703
int offset = ( int ) ( BitPosition & 7 ) , offset_inv = 8 - offset ;
702
704
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 ) ) ;
704
706
BitPosition += 4 ;
705
707
}
706
708
UpdateLength ( ) ;
@@ -719,13 +721,13 @@ public void WriteNibble(byte value)
719
721
/// <param name="bitCount">Amount of bits to write</param>
720
722
public void WriteBits ( ulong value , int bitCount )
721
723
{
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 ) ) ;
723
725
if ( bitCount > 64 ) throw new ArgumentOutOfRangeException ( "Cannot read more than 64 bits from a 64-bit value!" ) ;
724
726
if ( bitCount < 0 ) throw new ArgumentOutOfRangeException ( "Cannot read fewer than 0 bits!" ) ;
725
727
int count = - 8 ;
726
- while ( bitCount > ( count += 8 ) ) _WriteULongByte ( value >> count ) ;
728
+ while ( bitCount > ( count += 8 ) ) _WriteULongByte ( value >> count ) ;
727
729
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 ) ;
729
731
UpdateLength ( ) ;
730
732
}
731
733
/// <summary>
@@ -743,7 +745,7 @@ private void _WriteBits(byte value, int bitCount)
743
745
target [ Position ] = ( byte ) (
744
746
( target [ Position ] & ( 0xFF >> offset_inv ) ) | // Bits prior to value (lower)
745
747
( target [ Position ] & ( 0xFF << ( offset + bitCount ) ) ) | // Bits after value (higher)
746
- ( value << offset ) // Bits to write
748
+ ( value << offset ) // Bits to write
747
749
) ;
748
750
if ( bitCount + offset > 8 )
749
751
target [ Position + 1 ] = ( byte ) (
@@ -906,15 +908,15 @@ public void WriteUInt64Packed(ulong value)
906
908
/// Read an unsigned long (UInt64) from the stream.
907
909
/// </summary>
908
910
/// <returns>Value read from stream.</returns>
909
- public ulong ReadUInt64 ( ) => ( ulong ) (
911
+ public ulong ReadUInt64 ( ) => (
910
912
_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 )
918
920
) ;
919
921
/// <summary>
920
922
/// Read a signed long (Int64) from the stream.
@@ -982,7 +984,7 @@ private void _WriteMisaligned(byte value)
982
984
{
983
985
int off = ( int ) ( BitPosition & 7 ) ;
984
986
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 ) ) ;
986
988
target [ Position ] = ( byte ) ( ( target [ Position ] & ( 0xFF >> shift1 ) ) | ( value << off ) ) ;
987
989
988
990
BitPosition += 8 ;
@@ -1054,19 +1056,19 @@ public override void WriteByte(byte value)
1054
1056
/// <param name="count">How many bytes to read. Set to value less than one to read until ReadByte returns -1</param>
1055
1057
public void CopyFrom ( Stream s , int count = - 1 )
1056
1058
{
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 ) ;
1058
1060
else
1059
1061
{
1060
1062
int read ;
1061
1063
bool readToEnd = count < 0 ;
1062
- while ( ( readToEnd || count -- > 0 ) && ( read = s . ReadByte ( ) ) != - 1 )
1064
+ while ( ( readToEnd || count -- > 0 ) && ( read = s . ReadByte ( ) ) != - 1 )
1063
1065
_WriteIntByte ( read ) ;
1064
1066
UpdateLength ( ) ;
1065
1067
}
1066
1068
}
1067
-
1069
+
1068
1070
// TODO: Implement CopyFrom() for BitStream with bitCount parameter
1069
-
1071
+
1070
1072
/// <summary>
1071
1073
/// Update length of data considered to be "written" to the stream.
1072
1074
/// </summary>
0 commit comments