@@ -9,16 +9,14 @@ namespace MLAPI.NetworkingManagerComponents.Binary
9
9
{
10
10
public sealed class BitStream : Stream
11
11
{
12
- private const long SIGN_BIT = - 9223372036854775808 ;
13
-
14
-
15
12
private readonly double growthFactor ;
16
13
private readonly byte [ ] target ;
17
14
18
15
public BitStream ( byte [ ] target , double growthFactor = 2.0 )
19
16
{
20
17
this . target = target ;
21
18
this . growthFactor = growthFactor <= 1 ? 1.5 : growthFactor ;
19
+ BitLength = ( ulong ) target . LongLength << 3 ;
22
20
}
23
21
24
22
public override bool CanRead => BitPosition < ( ulong ) target . LongLength ;
@@ -27,8 +25,9 @@ public BitStream(byte[] target, double growthFactor = 2.0)
27
25
28
26
public override bool CanWrite => true ;
29
27
30
- public override long Length => ( long ) ( BitLength >> 3 ) ;
28
+ public override long Length => ( long ) ( ( BitLength >> 3 ) + ( ( BitLength & 1UL ) | ( ( BitLength >> 1 ) & 1UL ) | ( ( BitLength >> 2 ) & 1UL ) ) ) ; // Optimized CeilingExact
31
29
30
+ private long BitWriteIndex { get => ( long ) ( ( BitPosition >> 3 ) + ( ( BitPosition & 1UL ) | ( ( BitPosition >> 1 ) & 1UL ) | ( ( BitPosition >> 2 ) & 1UL ) ) ) ; }
32
31
public override long Position { get => ( long ) ( BitPosition >> 3 ) ; set => BitPosition = ( ulong ) value << 3 ; }
33
32
public ulong BitPosition { get ; set ; }
34
33
public ulong BitLength { get ; private set ; }
@@ -60,9 +59,9 @@ public override long Seek(long offset, SeekOrigin origin)
60
59
origin == SeekOrigin . Current ?
61
60
offset > 0 ?
62
61
Math . Min ( BitPosition + ( ( ulong ) offset << 3 ) , ( ulong ) target . Length << 3 ) :
63
- ( offset ^ SIGN_BIT ) > Position ?
62
+ ( offset ^ SIGN_BIT_64 ) > Position ?
64
63
0UL :
65
- BitPosition - ( ulong ) ( ( offset ^ SIGN_BIT ) << 3 ) :
64
+ BitPosition - ( ulong ) ( ( offset ^ SIGN_BIT_64 ) << 3 ) :
66
65
origin == SeekOrigin . Begin ?
67
66
( ulong ) Math . Max ( 0 , offset ) << 3 :
68
67
( ulong ) Math . Max ( target . Length - offset , 0 ) << 3
@@ -93,7 +92,7 @@ public override void Write(byte[] buffer, int offset, int count)
93
92
}
94
93
}
95
94
96
- private void Grow ( int newContent ) => SetLength ( target . LongLength * ( long ) Math . Pow ( growthFactor , CeilingExact ( newContent , target . Length ) ) ) ;
95
+ private void Grow ( int newContent ) => SetLength ( Math . Max ( target . LongLength , 1 ) * ( long ) Math . Pow ( growthFactor , CeilingExact ( newContent , Math . Max ( target . Length , 1 ) ) ) ) ;
97
96
98
97
public void WriteBit ( bool bit )
99
98
{
@@ -138,6 +137,8 @@ public void WriteUInt64(ulong value)
138
137
public void WriteInt64Packed ( long value ) => WriteUInt64 ( ZigZagEncode ( value ) ) ;
139
138
public void WriteUInt64Packed ( ulong value )
140
139
{
140
+ int grow = VarIntSize ( value ) ;
141
+ if ( BitWriteIndex + grow >= target . LongLength ) Grow ( grow ) ;
141
142
if ( value <= 240 ) WriteULongByte ( value ) ;
142
143
else if ( value <= 2287 )
143
144
{
@@ -206,6 +207,7 @@ public ulong ReadUInt64Packed()
206
207
while ( hdr > ++ cmp ) res |= ( ulong ) _ReadByte ( ) << ( cmp << 3 ) ;
207
208
return res ;
208
209
}
210
+ public bool ReadBit ( ) => ( target [ Position ] & ( 1 << ( int ) ( BitPosition ++ & 7 ) ) ) != 0 ;
209
211
210
212
211
213
private void WriteULongByteMisaligned ( ulong value ) => WriteMisaligned ( ( byte ) value ) ;
@@ -222,12 +224,15 @@ private void WriteMisaligned(byte value)
222
224
private void WriteULongByte ( ulong byteValue ) => WriteByte ( ( byte ) byteValue ) ;
223
225
public override void WriteByte ( byte value )
224
226
{
227
+ if ( Position == target . LongLength ) Grow ( 1 ) ;
225
228
if ( BitAligned )
226
229
{
227
230
target [ Position ] = value ;
228
231
++ Position ;
229
232
}
230
233
else WriteMisaligned ( value ) ;
231
234
}
235
+
236
+ public byte [ ] GetBuffer ( ) => target ;
232
237
}
233
238
}
0 commit comments