1
1
using System ;
2
+ using System . Collections ;
2
3
using System . Collections . Concurrent ;
4
+ using System . Collections . Generic ;
3
5
using System . IO ;
4
6
using System . Runtime . CompilerServices ;
7
+ using System . Runtime . InteropServices ;
5
8
using BTDB . Bon ;
9
+ using BTDB . IL ;
6
10
using BTDB . StreamLayer ;
7
11
8
12
namespace BTDB . Serialization ;
@@ -62,7 +66,10 @@ enum BonSerializerCmd : byte
62
66
GetByOffsetAndWriteObject ,
63
67
GetCustomAndWriteObject ,
64
68
InitArray ,
65
- NextArray
69
+ NextArray ,
70
+ InitList ,
71
+ InitHashSet ,
72
+ NextHashSet
66
73
}
67
74
68
75
public ref struct BonSerializerCtx
@@ -237,6 +244,27 @@ public void Generate()
237
244
var elementType = _type . GetElementType ( ) ! ;
238
245
WriteCmdByType ( null , elementType ) ;
239
246
_memWriter . WriteUInt8 ( ( byte ) BonSerializerCmd . NextArray ) ;
247
+ return ;
248
+ }
249
+
250
+ if ( _type . SpecializationOf ( typeof ( List < > ) ) is { } listType )
251
+ {
252
+ _memWriter . WriteUInt8 ( ( byte ) BonSerializerCmd . InitList ) ;
253
+ var elementType = listType . GetGenericArguments ( ) [ 0 ] ;
254
+ WriteCmdByType ( null , elementType ) ;
255
+ _memWriter . WriteUInt8 ( ( byte ) BonSerializerCmd . NextArray ) ;
256
+ return ;
257
+ }
258
+
259
+ if ( _type . SpecializationOf ( typeof ( HashSet < > ) ) is { } hashSetType )
260
+ {
261
+ _memWriter . WriteUInt8 ( ( byte ) BonSerializerCmd . InitHashSet ) ;
262
+ var elementType = hashSetType . GetGenericArguments ( ) [ 0 ] ;
263
+ var layout = RawData . GetHashSetEntriesLayout ( elementType ) ;
264
+ _memWriter . WriteVUInt32 ( layout . Offset ) ;
265
+ WriteCmdByType ( null , elementType ) ;
266
+ _memWriter . WriteUInt8 ( ( byte ) BonSerializerCmd . NextHashSet ) ;
267
+ return ;
240
268
}
241
269
242
270
var classMetadata = ReflectionMetadata . FindByType ( _type ) ;
@@ -245,6 +273,8 @@ public void Generate()
245
273
AddClass ( classMetadata ) ;
246
274
return ;
247
275
}
276
+
277
+ throw new NotSupportedException ( "BonSerialization of " + _type . ToSimpleName ( ) + " is not supported." ) ;
248
278
}
249
279
250
280
public unsafe BonSerialize Build ( )
@@ -259,6 +289,7 @@ public unsafe BonSerialize Build()
259
289
object ? tempObject2 = null ;
260
290
uint offset = 0 ;
261
291
uint offsetDelta = 0 ;
292
+ uint offsetOffset = 0 ;
262
293
uint offsetFinal = 0 ;
263
294
uint offsetLabel = 0 ;
264
295
UInt128 tempBytes = default ;
@@ -590,7 +621,7 @@ public unsafe BonSerialize Build()
590
621
{
591
622
tempObject2 = Unsafe . As < byte , object > ( ref value ) ;
592
623
var count = Unsafe . As < byte , int > ( ref RawData . Ref ( tempObject2 , ( uint ) Unsafe . SizeOf < nint > ( ) ) ) ;
593
- ref var mt = ref RawData . MethodTableRef ( tempObject2 ) ;
624
+ ref readonly var mt = ref RawData . MethodTableRef ( tempObject2 ) ;
594
625
offset = mt . BaseSize - ( uint ) Unsafe . SizeOf < nint > ( ) ;
595
626
offsetDelta = mt . ComponentSize ;
596
627
offsetFinal = offset + offsetDelta * ( uint ) count ;
@@ -613,6 +644,69 @@ public unsafe BonSerialize Build()
613
644
614
645
break ;
615
646
}
647
+ case BonSerializerCmd . InitList :
648
+ {
649
+ tempObject2 = Unsafe . As < byte , object > ( ref value ) ;
650
+ var count = Unsafe . As < ICollection > ( tempObject2 ) . Count ;
651
+ tempObject2 = RawData . ListItems ( Unsafe . As < List < object > > ( tempObject2 ) ) ;
652
+ ref readonly var mt = ref RawData . MethodTableRef ( tempObject2 ) ;
653
+ offset = mt . BaseSize - ( uint ) Unsafe . SizeOf < nint > ( ) ;
654
+ offsetDelta = mt . ComponentSize ;
655
+ offsetFinal = offset + offsetDelta * ( uint ) count ;
656
+ offsetLabel = ( uint ) reader . GetCurrentPositionWithoutController ( ) ;
657
+ ctx . Builder . StartArray ( ) ;
658
+ break ;
659
+ }
660
+ case BonSerializerCmd . InitHashSet :
661
+ {
662
+ tempObject2 = Unsafe . As < byte , object > ( ref value ) ;
663
+ var count = Unsafe . As < byte , int > ( ref RawData . Ref ( tempObject2 ,
664
+ RawData . Align ( 8 + 4 * ( uint ) Unsafe . SizeOf < nint > ( ) , 8 ) ) ) ;
665
+ tempObject2 = RawData . HashSetEntries ( Unsafe . As < HashSet < object > > ( tempObject2 ) ) ;
666
+ offsetOffset = reader . ReadVUInt32 ( ) ;
667
+ ref readonly var mt = ref RawData . MethodTableRef ( tempObject2 ) ;
668
+ offset = mt . BaseSize - ( uint ) Unsafe . SizeOf < nint > ( ) ;
669
+ offsetDelta = mt . ComponentSize ;
670
+ offsetFinal = offset + offsetDelta * ( uint ) count ;
671
+ offsetLabel = ( uint ) reader . GetCurrentPositionWithoutController ( ) ;
672
+ ctx . Builder . StartArray ( ) ;
673
+ while ( offset < offsetFinal )
674
+ {
675
+ if ( Unsafe . As < byte , int > ( ref RawData . Ref ( tempObject2 , offset + 4 ) ) >= - 1 ) break ;
676
+ offset += offsetDelta ;
677
+ }
678
+
679
+ if ( offset >= offsetFinal )
680
+ {
681
+ ctx . Builder . FinishArray ( ) ;
682
+ return ;
683
+ }
684
+
685
+ offset += offsetOffset ;
686
+ break ;
687
+ }
688
+ case BonSerializerCmd . NextHashSet :
689
+ {
690
+ offset += offsetDelta - offsetOffset ;
691
+ while ( offset < offsetFinal )
692
+ {
693
+ if ( Unsafe . As < byte , int > ( ref RawData . Ref ( tempObject2 , offset + 4 ) ) >= - 1 ) break ;
694
+ offset += offsetDelta ;
695
+ }
696
+
697
+ if ( offset < offsetFinal )
698
+ {
699
+ reader . SetCurrentPositionWithoutController ( offsetLabel ) ;
700
+ offset += offsetOffset ;
701
+ }
702
+ else
703
+ {
704
+ ctx . Builder . FinishArray ( ) ;
705
+ return ;
706
+ }
707
+
708
+ break ;
709
+ }
616
710
default :
617
711
throw new InvalidDataException ( "Unknown command in BonSerializer " + ( byte ) cmd + " at " +
618
712
( reader . GetCurrentPosition ( ) - 1 ) ) ;
0 commit comments