1
+ #region copyright
2
+ // -----------------------------------------------------------------------
3
+ // <copyright file="ArraySerializerFactory.cs" company="Akka.NET Team">
4
+ // Copyright (C) 2015-2016 AsynkronIT <https://github.com/AsynkronIT>
5
+ // Copyright (C) 2016-2016 Akka.NET Team <https://github.com/akkadotnet>
6
+ // </copyright>
7
+ // -----------------------------------------------------------------------
8
+ #endregion
9
+
10
+ using System ;
11
+ using System . Collections . Concurrent ;
12
+ using System . IO ;
13
+ using System . Linq ;
14
+ using System . Reflection ;
15
+ using Hyperion . Extensions ;
16
+ using Hyperion . ValueSerializers ;
17
+
18
+ namespace Hyperion . SerializerFactories
19
+ {
20
+ /// we don't support 4 dimensional array now
21
+ internal sealed class MultipleDimensionalArraySerialzierFactory : ValueSerializerFactory
22
+ {
23
+ public override bool CanSerialize ( Serializer serializer , Type type ) =>
24
+ /// wo don't support 4 dimensional array now
25
+ type . IsArray && type . GetArrayRank ( ) > 1 && type . GetArrayRank ( ) < 4 ;
26
+
27
+ public override bool CanDeserialize ( Serializer serializer , Type type ) => CanSerialize ( serializer , type ) ;
28
+
29
+ private static void WriteValues ( Array array , Stream stream , Type elementType , ValueSerializer elementSerializer , SerializerSession session )
30
+ {
31
+ for ( var i = 0 ; i < array . Rank ; i ++ )
32
+ {
33
+ Int32Serializer . WriteValueImpl ( stream , array . GetLength ( i ) , session ) ;
34
+ }
35
+ var preserveObjectReferences = session . Serializer . Options . PreserveObjectReferences ;
36
+ foreach ( var value in array )
37
+ {
38
+ stream . WriteObject ( value , elementType , elementSerializer , preserveObjectReferences , session ) ;
39
+ }
40
+ }
41
+
42
+
43
+ private static Array ReadValues2D ( Stream stream , DeserializerSession session , Array array )
44
+ {
45
+ for ( var i = array . GetLowerBound ( 0 ) ; i <= array . GetUpperBound ( 0 ) ; i ++ )
46
+ {
47
+ for ( var j = array . GetLowerBound ( 1 ) ; j <= array . GetUpperBound ( 1 ) ; j ++ )
48
+ {
49
+ var value = stream . ReadObject ( session ) ;
50
+ array . SetValue ( value , i , j ) ;
51
+ }
52
+ }
53
+ return array ;
54
+ }
55
+
56
+ private static Array ReadValues3D ( Stream stream , DeserializerSession session , Array array )
57
+ {
58
+ for ( var i = array . GetLowerBound ( 0 ) ; i <= array . GetUpperBound ( 0 ) ; i ++ )
59
+ {
60
+ for ( var j = array . GetLowerBound ( 1 ) ; j <= array . GetUpperBound ( 1 ) ; j ++ )
61
+ {
62
+ for ( var m = array . GetLowerBound ( 2 ) ; m <= array . GetUpperBound ( 2 ) ; m ++ )
63
+ {
64
+ var value = stream . ReadObject ( session ) ;
65
+ array . SetValue ( value , i , j , m ) ;
66
+ }
67
+
68
+ }
69
+ }
70
+ return array ;
71
+ }
72
+
73
+
74
+ private static ObjectReader CreateReader ( bool preserveObjectReferences , int arrayRank , Type elementType )
75
+ {
76
+ if ( arrayRank == 2 )
77
+ {
78
+ ObjectReader reader = ( stream , session ) =>
79
+ {
80
+ var length1 = stream . ReadInt32 ( session ) ;
81
+ var length2 = stream . ReadInt32 ( session ) ;
82
+ var array = Array . CreateInstance ( elementType , length1 , length2 ) ;
83
+ if ( preserveObjectReferences )
84
+ {
85
+ session . TrackDeserializedObject ( array ) ;
86
+ }
87
+ return ReadValues2D ( stream , session , array ) ;
88
+ } ;
89
+ return reader ;
90
+ }
91
+ if ( arrayRank == 3 )
92
+ {
93
+ ObjectReader reader = ( stream , session ) =>
94
+ {
95
+ var length1 = stream . ReadInt32 ( session ) ;
96
+ var length2 = stream . ReadInt32 ( session ) ;
97
+ var length3 = stream . ReadInt32 ( session ) ;
98
+ var array = Array . CreateInstance ( elementType , length1 , length2 , length3 ) ;
99
+ if ( preserveObjectReferences )
100
+ {
101
+ session . TrackDeserializedObject ( array ) ;
102
+ }
103
+ return ReadValues3D ( stream , session , array ) ;
104
+ } ;
105
+ return reader ;
106
+ }
107
+
108
+ else
109
+ {
110
+ throw new UnsupportedTypeException ( elementType , "we don't support 4 dimensional array now" ) ;
111
+ }
112
+ }
113
+
114
+
115
+ public override ValueSerializer BuildSerializer ( Serializer serializer , Type type ,
116
+ ConcurrentDictionary < Type , ValueSerializer > typeMapping )
117
+ {
118
+ var arraySerializer = new ObjectSerializer ( type ) ;
119
+
120
+ var elementType =
121
+ type . GetTypeInfo ( )
122
+ . GetMethods ( )
123
+ . Where ( methodInfo => methodInfo . Name == "Get" )
124
+ . Select ( methodInfo => methodInfo . ReturnType )
125
+ . FirstOrDefault ( ) ;
126
+
127
+ var elementSerializer = serializer . GetSerializerByType ( elementType ) ;
128
+ var preserveObjectReferences = serializer . Options . PreserveObjectReferences ;
129
+
130
+ var arrayRank = type . GetArrayRank ( ) ;
131
+
132
+ //TODO: code gen this part
133
+ ObjectReader reader = CreateReader ( preserveObjectReferences , arrayRank , elementType ) ;
134
+
135
+ ObjectWriter writer = ( stream , arr , session ) =>
136
+ {
137
+ if ( preserveObjectReferences )
138
+ {
139
+ session . TrackSerializedObject ( arr ) ;
140
+ }
141
+
142
+ WriteValues ( ( Array ) arr , stream , elementType , elementSerializer , session ) ;
143
+ } ;
144
+ arraySerializer . Initialize ( reader , writer ) ;
145
+ typeMapping . TryAdd ( type , arraySerializer ) ;
146
+ return arraySerializer ;
147
+ }
148
+
149
+
150
+ }
151
+ }
0 commit comments