44
55namespace ServiceStack . Redis . Support
66{
7- /// <summary>
8- /// Optimized <see cref="ISerializer"/> implementation. Primitive types are manually serialized, the rest are serialized using binary serializer />.
9- /// </summary>
10- public class OptimizedObjectSerializer : ObjectSerializer
11- {
12- internal const ushort RawDataFlag = 0xfa52 ;
13- internal static readonly byte [ ] EmptyArray = new byte [ 0 ] ;
7+ /// <summary>
8+ /// Optimized <see cref="ISerializer"/> implementation. Primitive types are manually serialized, the rest are serialized using binary serializer />.
9+ /// </summary>
10+ public class OptimizedObjectSerializer : ObjectSerializer
11+ {
12+ internal const ushort RawDataFlag = 0xfa52 ;
13+ internal static readonly byte [ ] EmptyArray = new byte [ 0 ] ;
1414
1515 /// <summary>
1616 ///
@@ -33,204 +33,204 @@ public override object Deserialize(byte[] someBytes)
3333 var temp = ( SerializedObjectWrapper ) base . Deserialize ( someBytes ) ;
3434 return Unwrap ( temp ) ;
3535 }
36-
36+
3737 /// <summary>
3838 /// serialize value and wrap with <see cref="SerializedObjectWrapper"/>
3939 /// </summary>
4040 /// <param name="value"></param>
4141 /// <returns></returns>
42- SerializedObjectWrapper SerializeToWrapper ( object value )
43- {
44- // raw data is a special case when some1 passes in a buffer (byte[] or ArraySegment<byte>)
45- if ( value is ArraySegment < byte > )
46- {
47- // ArraySegment<byte> is only passed in when a part of buffer is being
48- // serialized, usually from a MemoryStream (To avoid duplicating arrays
49- // the byte[] returned by MemoryStream.GetBuffer is placed into an ArraySegment.)
50- //
51- return new SerializedObjectWrapper ( RawDataFlag , ( ArraySegment < byte > ) value ) ;
52- }
53-
54- byte [ ] tmpByteArray = value as byte [ ] ;
55-
56- // - or we just received a byte[]. No further processing is needed.
57- if ( tmpByteArray != null )
58- {
59- return new SerializedObjectWrapper ( RawDataFlag , new ArraySegment < byte > ( tmpByteArray ) ) ;
60- }
61-
62- TypeCode code = value == null ? TypeCode . DBNull : Type . GetTypeCode ( value . GetType ( ) ) ;
63-
64- byte [ ] data ;
65- int length = - 1 ;
66-
67- switch ( code )
68- {
69- case TypeCode . DBNull :
70- data = EmptyArray ;
71- length = 0 ;
72- break ;
73-
74- case TypeCode . String :
75- data = Encoding . UTF8 . GetBytes ( ( string ) value ) ;
76- break ;
77-
78- case TypeCode . Boolean :
79- data = BitConverter . GetBytes ( ( bool ) value ) ;
80- break ;
81-
82- case TypeCode . Int16 :
83- data = BitConverter . GetBytes ( ( short ) value ) ;
84- break ;
85-
86- case TypeCode . Int32 :
87- data = BitConverter . GetBytes ( ( int ) value ) ;
88- break ;
89-
90- case TypeCode . Int64 :
91- data = BitConverter . GetBytes ( ( long ) value ) ;
92- break ;
93-
94- case TypeCode . UInt16 :
95- data = BitConverter . GetBytes ( ( ushort ) value ) ;
96- break ;
97-
98- case TypeCode . UInt32 :
99- data = BitConverter . GetBytes ( ( uint ) value ) ;
100- break ;
101-
102- case TypeCode . UInt64 :
103- data = BitConverter . GetBytes ( ( ulong ) value ) ;
104- break ;
105-
106- case TypeCode . Char :
107- data = BitConverter . GetBytes ( ( char ) value ) ;
108- break ;
109-
110- case TypeCode . DateTime :
111- data = BitConverter . GetBytes ( ( ( DateTime ) value ) . ToBinary ( ) ) ;
112- break ;
113-
114- case TypeCode . Double :
115- data = BitConverter . GetBytes ( ( double ) value ) ;
116- break ;
117-
118- case TypeCode . Single :
119- data = BitConverter . GetBytes ( ( float ) value ) ;
120- break ;
121-
122- default :
123- using ( var ms = new MemoryStream ( ) )
124- {
125- bf . Serialize ( ms , value ) ;
126-
127- code = TypeCode . Object ;
128- data = ms . GetBuffer ( ) ;
129- length = ( int ) ms . Length ;
130- }
131- break ;
132- }
133-
134- if ( length < 0 )
135- length = data . Length ;
136-
137- return new SerializedObjectWrapper ( ( ushort ) ( ( ushort ) code | 0x0100 ) , new ArraySegment < byte > ( data , 0 , length ) ) ;
138- }
42+ SerializedObjectWrapper SerializeToWrapper ( object value )
43+ {
44+ // raw data is a special case when some1 passes in a buffer (byte[] or ArraySegment<byte>)
45+ if ( value is ArraySegment < byte > )
46+ {
47+ // ArraySegment<byte> is only passed in when a part of buffer is being
48+ // serialized, usually from a MemoryStream (To avoid duplicating arrays
49+ // the byte[] returned by MemoryStream.GetBuffer is placed into an ArraySegment.)
50+ //
51+ return new SerializedObjectWrapper ( RawDataFlag , ( ArraySegment < byte > ) value ) ;
52+ }
53+
54+ byte [ ] tmpByteArray = value as byte [ ] ;
55+
56+ // - or we just received a byte[]. No further processing is needed.
57+ if ( tmpByteArray != null )
58+ {
59+ return new SerializedObjectWrapper ( RawDataFlag , new ArraySegment < byte > ( tmpByteArray ) ) ;
60+ }
61+
62+ TypeCode code = value == null ? TypeCode . DBNull : Type . GetTypeCode ( value . GetType ( ) ) ;
63+
64+ byte [ ] data ;
65+ int length = - 1 ;
66+
67+ switch ( code )
68+ {
69+ case TypeCode . DBNull :
70+ data = EmptyArray ;
71+ length = 0 ;
72+ break ;
73+
74+ case TypeCode . String :
75+ data = Encoding . UTF8 . GetBytes ( ( string ) value ) ;
76+ break ;
77+
78+ case TypeCode . Boolean :
79+ data = BitConverter . GetBytes ( ( bool ) value ) ;
80+ break ;
81+
82+ case TypeCode . Int16 :
83+ data = BitConverter . GetBytes ( ( short ) value ) ;
84+ break ;
85+
86+ case TypeCode . Int32 :
87+ data = BitConverter . GetBytes ( ( int ) value ) ;
88+ break ;
89+
90+ case TypeCode . Int64 :
91+ data = BitConverter . GetBytes ( ( long ) value ) ;
92+ break ;
93+
94+ case TypeCode . UInt16 :
95+ data = BitConverter . GetBytes ( ( ushort ) value ) ;
96+ break ;
97+
98+ case TypeCode . UInt32 :
99+ data = BitConverter . GetBytes ( ( uint ) value ) ;
100+ break ;
101+
102+ case TypeCode . UInt64 :
103+ data = BitConverter . GetBytes ( ( ulong ) value ) ;
104+ break ;
105+
106+ case TypeCode . Char :
107+ data = BitConverter . GetBytes ( ( char ) value ) ;
108+ break ;
109+
110+ case TypeCode . DateTime :
111+ data = BitConverter . GetBytes ( ( ( DateTime ) value ) . ToBinary ( ) ) ;
112+ break ;
113+
114+ case TypeCode . Double :
115+ data = BitConverter . GetBytes ( ( double ) value ) ;
116+ break ;
117+
118+ case TypeCode . Single :
119+ data = BitConverter . GetBytes ( ( float ) value ) ;
120+ break ;
121+
122+ default :
123+ using ( var ms = new MemoryStream ( ) )
124+ {
125+ bf . Serialize ( ms , value ) ;
126+
127+ code = TypeCode . Object ;
128+ data = ms . GetBuffer ( ) ;
129+ length = ( int ) ms . Length ;
130+ }
131+ break ;
132+ }
133+
134+ if ( length < 0 )
135+ length = data . Length ;
136+
137+ return new SerializedObjectWrapper ( ( ushort ) ( ( ushort ) code | 0x0100 ) , new ArraySegment < byte > ( data , 0 , length ) ) ;
138+ }
139139
140140 /// <summary>
141141 /// Unwrap object wrapped in <see cref="SerializedObjectWrapper"/>
142142 /// </summary>
143143 /// <param name="item"></param>
144144 /// <returns></returns>
145145 object Unwrap ( SerializedObjectWrapper item )
146- {
147- if ( item . Data . Array == null )
148- return null ;
146+ {
147+ if ( item . Data . Array == null )
148+ return null ;
149149
150- if ( item . Flags == RawDataFlag )
151- {
152- ArraySegment < byte > tmp = item . Data ;
150+ if ( item . Flags == RawDataFlag )
151+ {
152+ ArraySegment < byte > tmp = item . Data ;
153153
154- if ( tmp . Count == tmp . Array . Length )
155- return tmp . Array ;
154+ if ( tmp . Count == tmp . Array . Length )
155+ return tmp . Array ;
156156
157- // we should never arrive here, but it's better to be safe than sorry
158- var retval = new byte [ tmp . Count ] ;
157+ // we should never arrive here, but it's better to be safe than sorry
158+ var retval = new byte [ tmp . Count ] ;
159159
160- Array . Copy ( tmp . Array , tmp . Offset , retval , 0 , tmp . Count ) ;
160+ Array . Copy ( tmp . Array , tmp . Offset , retval , 0 , tmp . Count ) ;
161161
162- return retval ;
163- }
162+ return retval ;
163+ }
164164
165- var code = ( TypeCode ) ( item . Flags & 0x00ff ) ;
165+ var code = ( TypeCode ) ( item . Flags & 0x00ff ) ;
166166
167- byte [ ] data = item . Data . Array ;
168- int offset = item . Data . Offset ;
169- int count = item . Data . Count ;
167+ byte [ ] data = item . Data . Array ;
168+ int offset = item . Data . Offset ;
169+ int count = item . Data . Count ;
170170
171- switch ( code )
172- {
173- // incrementing a non-existing key then getting it
174- // returns as a string, but the flag will be 0
175- // so treat all 0 flagged items as string
176- // this may help inter-client data management as well
177- //
178- // however we store 'null' as Empty + an empty array,
179- // so this must special-cased for compatibilty with
180- // earlier versions. we introduced DBNull as null marker in emc2.6
181- case TypeCode . Empty :
182- return ( data == null || count == 0 )
183- ? null
184- : Encoding . UTF8 . GetString ( data , offset , count ) ;
171+ switch ( code )
172+ {
173+ // incrementing a non-existing key then getting it
174+ // returns as a string, but the flag will be 0
175+ // so treat all 0 flagged items as string
176+ // this may help inter-client data management as well
177+ //
178+ // however we store 'null' as Empty + an empty array,
179+ // so this must special-cased for compatibilty with
180+ // earlier versions. we introduced DBNull as null marker in emc2.6
181+ case TypeCode . Empty :
182+ return ( data == null || count == 0 )
183+ ? null
184+ : Encoding . UTF8 . GetString ( data , offset , count ) ;
185185
186- case TypeCode . DBNull :
187- return null ;
186+ case TypeCode . DBNull :
187+ return null ;
188188
189- case TypeCode . String :
190- return Encoding . UTF8 . GetString ( data , offset , count ) ;
189+ case TypeCode . String :
190+ return Encoding . UTF8 . GetString ( data , offset , count ) ;
191191
192- case TypeCode . Boolean :
193- return BitConverter . ToBoolean ( data , offset ) ;
192+ case TypeCode . Boolean :
193+ return BitConverter . ToBoolean ( data , offset ) ;
194194
195- case TypeCode . Int16 :
196- return BitConverter . ToInt16 ( data , offset ) ;
195+ case TypeCode . Int16 :
196+ return BitConverter . ToInt16 ( data , offset ) ;
197197
198- case TypeCode . Int32 :
199- return BitConverter . ToInt32 ( data , offset ) ;
198+ case TypeCode . Int32 :
199+ return BitConverter . ToInt32 ( data , offset ) ;
200200
201- case TypeCode . Int64 :
202- return BitConverter . ToInt64 ( data , offset ) ;
201+ case TypeCode . Int64 :
202+ return BitConverter . ToInt64 ( data , offset ) ;
203203
204- case TypeCode . UInt16 :
205- return BitConverter . ToUInt16 ( data , offset ) ;
204+ case TypeCode . UInt16 :
205+ return BitConverter . ToUInt16 ( data , offset ) ;
206206
207- case TypeCode . UInt32 :
208- return BitConverter . ToUInt32 ( data , offset ) ;
207+ case TypeCode . UInt32 :
208+ return BitConverter . ToUInt32 ( data , offset ) ;
209209
210- case TypeCode . UInt64 :
211- return BitConverter . ToUInt64 ( data , offset ) ;
210+ case TypeCode . UInt64 :
211+ return BitConverter . ToUInt64 ( data , offset ) ;
212212
213- case TypeCode . Char :
214- return BitConverter . ToChar ( data , offset ) ;
213+ case TypeCode . Char :
214+ return BitConverter . ToChar ( data , offset ) ;
215215
216- case TypeCode . DateTime :
217- return DateTime . FromBinary ( BitConverter . ToInt64 ( data , offset ) ) ;
216+ case TypeCode . DateTime :
217+ return DateTime . FromBinary ( BitConverter . ToInt64 ( data , offset ) ) ;
218218
219- case TypeCode . Double :
220- return BitConverter . ToDouble ( data , offset ) ;
219+ case TypeCode . Double :
220+ return BitConverter . ToDouble ( data , offset ) ;
221221
222- case TypeCode . Single :
223- return BitConverter . ToSingle ( data , offset ) ;
222+ case TypeCode . Single :
223+ return BitConverter . ToSingle ( data , offset ) ;
224224
225- case TypeCode . Object :
226- using ( var ms = new MemoryStream ( data , offset , count ) )
227- {
228- return bf . Deserialize ( ms ) ;
229- }
225+ case TypeCode . Object :
226+ using ( var ms = new MemoryStream ( data , offset , count ) )
227+ {
228+ return bf . Deserialize ( ms ) ;
229+ }
230230
231- default : throw new InvalidOperationException ( "Unknown TypeCode was returned: " + code ) ;
232- }
233- }
234- }
231+ default : throw new InvalidOperationException ( "Unknown TypeCode was returned: " + code ) ;
232+ }
233+ }
234+ }
235235}
236236
0 commit comments