1 //------------------------------------------------------------------------------
2 // <copyright file="altserialization.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6 
7 /*
8  * AltSerialization.cs
9  *
10  * Copyright (c) 1998-2000, Microsoft Corporation
11  *
12  */
13 
14 namespace System.Web.Util {
15     using System;
16     using System.Diagnostics.CodeAnalysis;
17     using System.IO;
18     using System.Runtime.Serialization;
19     using System.Runtime.Serialization.Formatters;
20     using System.Runtime.Serialization.Formatters.Binary;
21     using System.Web.SessionState;
22 
23     internal static class AltSerialization {
24         enum TypeID : byte {
25             String = 1,
26             Int32,
27             Boolean,
28             DateTime,
29             Decimal,
30             Byte,
31             Char,
32             Single,
33             Double,
34             SByte,
35             Int16,
36             Int64,
37             UInt16,
38             UInt32,
39             UInt64,
40             TimeSpan,
41             Guid,
42             IntPtr,
43             UIntPtr,
44             Object,
45             Null,
46         }
47 
48         [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "This method is safe critical (we're allowed to call the SerializationSurrogateSelector property getter).")]
WriteValueToStream(Object value, BinaryWriter writer)49         internal static void WriteValueToStream(Object value, BinaryWriter writer) {
50             if (value == null) {
51                 writer.Write((byte)TypeID.Null);
52             }
53             else if (value is String) {
54                 writer.Write((byte)TypeID.String);
55                 writer.Write((String) value);
56             }
57             else if (value is Int32) {
58                 writer.Write((byte)TypeID.Int32);
59                 writer.Write((Int32) value);
60             }
61             else if (value is Boolean) {
62                 writer.Write((byte)TypeID.Boolean);
63                 writer.Write((Boolean) value);
64             }
65             else if (value is DateTime) {
66                 writer.Write((byte)TypeID.DateTime);
67                 writer.Write(((DateTime) value).Ticks);
68             }
69             else if (value is Decimal) {
70                 writer.Write((byte)TypeID.Decimal);
71                 int[] bits = Decimal.GetBits((Decimal)value);
72                 for (int i = 0; i < 4; i++) {
73                     writer.Write((int)bits[i]);
74                 }
75             }
76             else if (value is Byte) {
77                 writer.Write((byte)TypeID.Byte);
78                 writer.Write((byte) value);
79             }
80             else if (value is Char) {
81                 writer.Write((byte)TypeID.Char);
82                 writer.Write((char) value);
83             }
84             else if (value is Single) {
85                 writer.Write((byte)TypeID.Single);
86                 writer.Write((float) value);
87             }
88             else if (value is Double) {
89                 writer.Write((byte)TypeID.Double);
90                 writer.Write((double) value);
91             }
92             else if (value is SByte) {
93                 writer.Write((byte)TypeID.SByte);
94                 writer.Write((SByte) value);
95             }
96             else if (value is Int16) {
97                 writer.Write((byte)TypeID.Int16);
98                 writer.Write((short) value);
99             }
100             else if (value is Int64) {
101                 writer.Write((byte)TypeID.Int64);
102                 writer.Write((long) value);
103             }
104             else if (value is UInt16) {
105                 writer.Write((byte)TypeID.UInt16);
106                 writer.Write((UInt16) value);
107             }
108             else if (value is UInt32) {
109                 writer.Write((byte)TypeID.UInt32);
110                 writer.Write((UInt32) value);
111             }
112             else if (value is UInt64) {
113                 writer.Write((byte)TypeID.UInt64);
114                 writer.Write((UInt64) value);
115             }
116             else if (value is TimeSpan) {
117                 writer.Write((byte)TypeID.TimeSpan);
118                 writer.Write(((TimeSpan) value).Ticks);
119             }
120             else if (value is Guid) {
121                 writer.Write((byte)TypeID.Guid);
122                 Guid guid = (Guid) value;
123                 byte[] bits = guid.ToByteArray();
124                 writer.Write(bits);
125             }
126             else if (value is IntPtr) {
127                 writer.Write((byte)TypeID.IntPtr);
128                 IntPtr  v = (IntPtr) value;
129                 if (IntPtr.Size == 4) {
130                     writer.Write((Int32)v.ToInt32());
131                 }
132                 else {
133                     Debug.Assert(IntPtr.Size == 8);
134                     writer.Write((Int64)v.ToInt64());
135                 }
136             }
137             else if (value is UIntPtr) {
138                 writer.Write((byte)TypeID.UIntPtr);
139                 UIntPtr  v = (UIntPtr) value;
140                 if (UIntPtr.Size == 4) {
141                     writer.Write((UInt32)v.ToUInt32());
142                 }
143                 else {
144                     Debug.Assert(UIntPtr.Size == 8);
145                     writer.Write((UInt64)v.ToUInt64());
146                 }
147             }
148             else {
149                 writer.Write((byte)TypeID.Object);
150                 BinaryFormatter formatter = new BinaryFormatter();
151                 if (SessionStateUtility.SerializationSurrogateSelector != null) {
152                     formatter.SurrogateSelector = SessionStateUtility.SerializationSurrogateSelector;
153                 }
154                 try {
155                     formatter.Serialize(writer.BaseStream, value);
156                 } catch (Exception innerException) {
157                     HttpException outerException = new HttpException(SR.GetString(SR.Cant_serialize_session_state), innerException);
158                     outerException.SetFormatter(new UseLastUnhandledErrorFormatter(outerException));
159                     throw outerException;
160                 }
161             }
162         }
163 
164         [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "This method is safe critical (we're allowed to call the SerializationSurrogateSelector property getter).")]
ReadValueFromStream(BinaryReader reader)165         internal static Object ReadValueFromStream(BinaryReader reader) {
166             TypeID  id;
167             Object  value = null;
168 
169             id = (TypeID) reader.ReadByte();
170             switch (id) {
171                 case TypeID.String:
172                     value = reader.ReadString();
173                     break;
174 
175                 case TypeID.Int32:
176                     value = reader.ReadInt32();
177                     break;
178 
179                 case TypeID.Boolean:
180                     value = reader.ReadBoolean();
181                     break;
182 
183                 case TypeID.DateTime:
184                     value = new DateTime(reader.ReadInt64());
185                     break;
186 
187                 case TypeID.Decimal:
188                     {
189                         int[] bits = new int[4];
190                         for (int i = 0; i < 4; i++) {
191                             bits[i] = reader.ReadInt32();
192                         }
193 
194                         value = new Decimal(bits);
195                     }
196                     break;
197 
198                 case TypeID.Byte:
199                     value = reader.ReadByte();
200                     break;
201 
202                 case TypeID.Char:
203                     value = reader.ReadChar();
204                     break;
205 
206                 case TypeID.Single:
207                     value = reader.ReadSingle();
208                     break;
209 
210                 case TypeID.Double:
211                     value = reader.ReadDouble();
212                     break;
213 
214                 case TypeID.SByte:
215                     value = reader.ReadSByte();
216                     break;
217 
218                 case TypeID.Int16:
219                     value = reader.ReadInt16();
220                     break;
221 
222                 case TypeID.Int64:
223                     value = reader.ReadInt64();
224                     break;
225 
226                 case TypeID.UInt16:
227                     value = reader.ReadUInt16();
228                     break;
229 
230                 case TypeID.UInt32:
231                     value = reader.ReadUInt32();
232                     break;
233 
234                 case TypeID.UInt64:
235                     value = reader.ReadUInt64();
236                     break;
237 
238                 case TypeID.TimeSpan:
239                     value = new TimeSpan(reader.ReadInt64());
240                     break;
241 
242                 case TypeID.Guid:
243                     {
244                         byte[] bits = reader.ReadBytes(16);
245                         value = new Guid(bits);
246                     }
247                     break;
248 
249                 case TypeID.IntPtr:
250                     if (IntPtr.Size == 4) {
251                         value = new IntPtr(reader.ReadInt32());
252                     }
253                     else {
254                         Debug.Assert(IntPtr.Size == 8);
255                         value = new IntPtr(reader.ReadInt64());
256                     }
257                     break;
258 
259                 case TypeID.UIntPtr:
260                     if (UIntPtr.Size == 4) {
261                         value = new UIntPtr(reader.ReadUInt32());
262                     }
263                     else {
264                         Debug.Assert(UIntPtr.Size == 8);
265                         value = new UIntPtr(reader.ReadUInt64());
266                     }
267                     break;
268 
269                 case TypeID.Object:
270                     BinaryFormatter formatter = new BinaryFormatter();
271                     if (SessionStateUtility.SerializationSurrogateSelector != null) {
272                         formatter.SurrogateSelector = SessionStateUtility.SerializationSurrogateSelector;
273                     }
274                     value = formatter.Deserialize(reader.BaseStream);
275                     break;
276 
277                 case TypeID.Null:
278                     value = null;
279                     break;
280             }
281 
282             return value;
283         }
284     }
285 }
286 
287