@@ -10,6 +10,19 @@ namespace MLAPI.NetworkingManagerComponents.Binary
1010{
1111 public sealed class BitWriter : IDisposable
1212 {
13+ private struct Partial
14+ {
15+ public byte value ;
16+ public byte count ;
17+ public static readonly FieldInfo value_info = typeof ( Partial ) . GetField ( "value" ) ;
18+ public static readonly FieldInfo count_info = typeof ( Partial ) . GetField ( "count" ) ;
19+
20+ public Partial ( byte value , byte count )
21+ {
22+ this . value = value ;
23+ this . count = count ;
24+ }
25+ }
1326 private static readonly Queue < List < object > > listPool = new Queue < List < object > > ( ) ;
1427
1528 private static readonly float [ ] holder_f = new float [ 1 ] ;
@@ -105,10 +118,7 @@ private void Push<T>(T b)
105118 public void WriteShortArray ( short [ ] s , bool known = false ) => PushArray ( s , known ) ;
106119 public void WriteIntArray ( int [ ] i , bool known = false ) => PushArray ( i , known ) ;
107120 public void WriteLongArray ( long [ ] l , bool known = false ) => PushArray ( l , known ) ;
108- public void WriteBits ( byte value , int bits )
109- {
110- for ( int i = 0 ; i < bits ; ++ i ) WriteBool ( ( value & ( 1 << i ) ) != 0 ) ;
111- }
121+ public void WriteBits ( byte value , int bits ) => Push ( new Partial ( ReadNBits ( value , 0 , bits % 8 ) , ( byte ) ( bits % 8 ) ) ) ; // Suggestion: store (bits % 8) result?
112122
113123 private void PushArray < T > ( T [ ] t , bool knownSize = false )
114124 {
@@ -197,6 +207,14 @@ private static void Serialize<T>(T t, byte[] writeTo, ref long bitOffset, ref bo
197207 foreach ( var element in array )
198208 Serialize ( element , writeTo , ref bitOffset , ref isAligned ) ;
199209 }
210+ else if ( type == typeof ( Partial ) )
211+ {
212+ byte count ;
213+ WriteByte ( writeTo , ( byte ) Partial . value_info . GetValue ( t ) , bitOffset , isAligned , count = ( byte ) Partial . count_info . GetValue ( t ) ) ;
214+ bitOffset += count ;
215+ isAligned = bitOffset % 8 == 0 ;
216+ return ;
217+ }
200218 else if ( IsSupportedType ( type ) )
201219 {
202220 long offset = t is bool ? 1 : BytesToRead ( t ) * 8 ;
@@ -230,7 +248,7 @@ private static void Serialize<T>(T t, byte[] writeTo, ref long bitOffset, ref bo
230248
231249 // Since floating point flag bits are seemingly the highest bytes of the floating point values
232250 // and even very small values have them, we swap the endianness in the hopes of reducing the size
233- if ( size ) Serialize ( BinaryHelpers . SwapEndian ( ( uint ) result_holder . GetValue ( 0 ) ) , writeTo , ref bitOffset , ref isAligned ) ;
251+ if ( size ) Serialize ( BinaryHelpers . SwapEndian ( ( uint ) result_holder . GetValue ( 0 ) ) , writeTo , ref bitOffset , ref isAligned ) ;
234252 else Serialize ( BinaryHelpers . SwapEndian ( ( ulong ) result_holder . GetValue ( 0 ) ) , writeTo , ref bitOffset , ref isAligned ) ;
235253 }
236254 }
@@ -338,7 +356,7 @@ private static long GetBitCount<T>(T t)
338356 private static void WriteBit ( byte [ ] b , bool bit , long index )
339357 => b [ index / 8 ] = ( byte ) ( ( b [ index / 8 ] & ~ ( 1 << ( int ) ( index % 8 ) ) ) | ( bit ? 1 << ( int ) ( index % 8 ) : 0 ) ) ;
340358 private static void WriteByte ( byte [ ] b , ulong value , long index , bool isAligned ) => WriteByte ( b , ( byte ) value , index , isAligned ) ;
341- private static void WriteByte ( byte [ ] b , byte value , long index , bool isAligned )
359+ private static void WriteByte ( byte [ ] b , byte value , long index , bool isAligned , byte bits = 8 )
342360 {
343361 if ( isAligned ) b [ index / 8 ] = value ;
344362 else
@@ -348,7 +366,7 @@ private static void WriteByte(byte[] b, byte value, long index, bool isAligned)
348366 byte upper_mask = ( byte ) ( 0xFF << shift ) ;
349367
350368 b [ byteIndex ] = ( byte ) ( ( b [ byteIndex ] & ( byte ) ~ upper_mask ) | ( value << shift ) ) ;
351- b [ byteIndex + 1 ] = ( byte ) ( ( b [ byteIndex + 1 ] & upper_mask ) | ( value >> ( 8 - shift ) ) ) ;
369+ if ( ( 8 - shift ) < bits ) b [ byteIndex + 1 ] = ( byte ) ( ( b [ byteIndex + 1 ] & upper_mask ) | ( value >> ( 8 - shift ) ) ) ;
352370 }
353371 }
354372 private static void WriteDynamic ( byte [ ] b , int value , int byteCount , long index , bool isAligned )
0 commit comments