New test.
[mono.git] / mcs / class / corlib / System.Runtime.Serialization.Formatters.Binary / BinaryCommon.cs
1 // BinaryCommon.cs\r
2 //\r
3 // Author:\r
4 //   Lluis Sanchez Gual (lluis@ideary.com)\r
5 //\r
6 // (C) 2003 Lluis Sanchez Gual\r
7 \r
8 //\r
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)\r
10 //\r
11 // Permission is hereby granted, free of charge, to any person obtaining\r
12 // a copy of this software and associated documentation files (the\r
13 // "Software"), to deal in the Software without restriction, including\r
14 // without limitation the rights to use, copy, modify, merge, publish,\r
15 // distribute, sublicense, and/or sell copies of the Software, and to\r
16 // permit persons to whom the Software is furnished to do so, subject to\r
17 // the following conditions:\r
18 // \r
19 // The above copyright notice and this permission notice shall be\r
20 // included in all copies or substantial portions of the Software.\r
21 // \r
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
29 //\r
30 \r
31 using System;\r
32 \r
33 namespace System.Runtime.Serialization.Formatters.Binary\r
34 {\r
35         internal class BinaryCommon\r
36         {\r
37                 // Header present in all binary serializations\r
38                 public static byte[] BinaryHeader = new Byte[] {0,1,0,0,0,255,255,255,255,1,0,0,0,0,0,0,0};\r
39 \r
40                 static Type[] _typeCodesToType;\r
41                 static byte[] _typeCodeMap;\r
42                 public static bool UseReflectionSerialization = false;\r
43 \r
44                 static BinaryCommon()\r
45                 {\r
46                         _typeCodesToType = new Type [19];\r
47                         _typeCodesToType[(int)BinaryTypeCode.Boolean] = typeof (Boolean);\r
48                         _typeCodesToType[(int)BinaryTypeCode.Byte] = typeof (Byte);\r
49                         _typeCodesToType[(int)BinaryTypeCode.Char] = typeof (Char);\r
50                         _typeCodesToType[(int)BinaryTypeCode.TimeSpan] = typeof (TimeSpan);\r
51                         _typeCodesToType[(int)BinaryTypeCode.DateTime] = typeof (DateTime);\r
52                         _typeCodesToType[(int)BinaryTypeCode.Decimal] = typeof (Decimal);\r
53                         _typeCodesToType[(int)BinaryTypeCode.Double] = typeof (Double);\r
54                         _typeCodesToType[(int)BinaryTypeCode.Int16] = typeof (Int16);\r
55                         _typeCodesToType[(int)BinaryTypeCode.Int32] = typeof (Int32);\r
56                         _typeCodesToType[(int)BinaryTypeCode.Int64] = typeof (Int64);\r
57                         _typeCodesToType[(int)BinaryTypeCode.SByte] = typeof (SByte);\r
58                         _typeCodesToType[(int)BinaryTypeCode.Single] = typeof (Single);\r
59                         _typeCodesToType[(int)BinaryTypeCode.UInt16] = typeof (UInt16);\r
60                         _typeCodesToType[(int)BinaryTypeCode.UInt32] = typeof (UInt32);\r
61                         _typeCodesToType[(int)BinaryTypeCode.UInt64] = typeof (UInt64);\r
62                         _typeCodesToType[(int)BinaryTypeCode.Null] = null;\r
63                         _typeCodesToType[(int)BinaryTypeCode.String] = typeof (string);\r
64 \r
65                         _typeCodeMap = new byte[30];\r
66                         _typeCodeMap[(int)TypeCode.Boolean] = (byte) BinaryTypeCode.Boolean;\r
67                         _typeCodeMap[(int)TypeCode.Byte] = (byte) BinaryTypeCode.Byte;\r
68                         _typeCodeMap[(int)TypeCode.Char] = (byte) BinaryTypeCode.Char;\r
69                         _typeCodeMap[(int)TypeCode.DateTime] = (byte) BinaryTypeCode.DateTime;\r
70                         _typeCodeMap[(int)TypeCode.Decimal] = (byte) BinaryTypeCode.Decimal;\r
71                         _typeCodeMap[(int)TypeCode.Double] = (byte) BinaryTypeCode.Double;\r
72                         _typeCodeMap[(int)TypeCode.Int16] = (byte) BinaryTypeCode.Int16;\r
73                         _typeCodeMap[(int)TypeCode.Int32] = (byte) BinaryTypeCode.Int32;\r
74                         _typeCodeMap[(int)TypeCode.Int64] = (byte) BinaryTypeCode.Int64;\r
75                         _typeCodeMap[(int)TypeCode.SByte] = (byte) BinaryTypeCode.SByte;\r
76                         _typeCodeMap[(int)TypeCode.Single] = (byte) BinaryTypeCode.Single;\r
77                         _typeCodeMap[(int)TypeCode.UInt16] = (byte) BinaryTypeCode.UInt16;\r
78                         _typeCodeMap[(int)TypeCode.UInt32] = (byte) BinaryTypeCode.UInt32;\r
79                         _typeCodeMap[(int)TypeCode.UInt64] = (byte) BinaryTypeCode.UInt64;\r
80                         _typeCodeMap[(int)TypeCode.String] = (byte) BinaryTypeCode.String;\r
81 \r
82                         // TimeStamp does not have a TypeCode, so it is managed as a special\r
83                         // case in GetTypeCode()\r
84                         \r
85                         // This environment variable is only for test and benchmarking pourposes.\r
86                         // By default, mono will always use IL generated class serializers.\r
87                         string s = Environment.GetEnvironmentVariable("MONO_REFLECTION_SERIALIZER");\r
88                         if (s == null) s = "no";\r
89                         UseReflectionSerialization = (s != "no");\r
90                 }\r
91 \r
92                 public static bool IsPrimitive (Type type)\r
93                 {\r
94                         return (type.IsPrimitive && type != typeof (IntPtr)) || \r
95                                 type == typeof (DateTime) || \r
96                                 type == typeof (TimeSpan) || \r
97                                 type == typeof (Decimal);\r
98                 }\r
99 \r
100                 public static byte GetTypeCode (Type type)\r
101                 {\r
102                         if (type == typeof(TimeSpan)) return (byte) BinaryTypeCode.TimeSpan;\r
103                         else return _typeCodeMap [(int)Type.GetTypeCode(type)];\r
104                 }\r
105 \r
106                 public static Type GetTypeFromCode (int code)\r
107                 {\r
108                         return _typeCodesToType [code];\r
109                 }\r
110                 \r
111                 public static void CheckSerializable (Type type, ISurrogateSelector selector, StreamingContext context)\r
112                 {\r
113                         if (!type.IsSerializable && !type.IsInterface) \r
114                         {\r
115                                 if (selector != null && selector.GetSurrogate (type, context, out selector) != null)\r
116                                         return;\r
117 \r
118                                 throw new SerializationException ("Type " + type + " is not marked as Serializable.");\r
119                         }\r
120                 }\r
121                 \r
122                 public static void SwapBytes (byte[] byteArray, int size, int dataSize)\r
123                 {\r
124                         byte b;\r
125                         if (dataSize == 8) {\r
126                                 for (int n=0; n<size; n+=8) {\r
127                                         b = byteArray [n]; byteArray [n] = byteArray [n + 7]; byteArray [n + 7] = b;\r
128                                         b = byteArray [n+1]; byteArray [n+1] = byteArray [n + 6]; byteArray [n + 6] = b;\r
129                                         b = byteArray [n+2]; byteArray [n+2] = byteArray [n + 5]; byteArray [n + 5] = b;\r
130                                         b = byteArray [n+3]; byteArray [n+3] = byteArray [n + 4]; byteArray [n + 4] = b;\r
131                                 }\r
132                         } else if (dataSize == 4) {\r
133                                 for (int n=0; n<size; n+=4) {\r
134                                         b = byteArray [n]; byteArray [n] = byteArray [n + 3]; byteArray [n + 3] = b;\r
135                                         b = byteArray [n+1]; byteArray [n+1] = byteArray [n + 2]; byteArray [n + 2] = b;\r
136                                 }\r
137                         } else if (dataSize == 2) {\r
138                                 for (int n=0; n<size; n+=2) {\r
139                                         b = byteArray [n]; byteArray [n] = byteArray [n + 1]; byteArray [n + 1] = b;\r
140                                 }\r
141                         }\r
142                 }\r
143         }\r
144 \r
145         internal enum BinaryElement : byte\r
146         {\r
147                 Header = 0,\r
148                 RefTypeObject = 1,\r
149                 UntypedRuntimeObject = 2,\r
150                 UntypedExternalObject = 3,\r
151                 RuntimeObject = 4,\r
152                 ExternalObject = 5,\r
153                 String = 6,\r
154                 GenericArray = 7,\r
155                 BoxedPrimitiveTypeValue = 8,\r
156                 ObjectReference = 9,\r
157                 NullValue = 10,\r
158                 End = 11,\r
159                 Assembly = 12,\r
160                 ArrayFiller8b = 13,\r
161                 ArrayFiller32b = 14,\r
162                 ArrayOfPrimitiveType = 15,\r
163                 ArrayOfObject = 16,\r
164                 ArrayOfString = 17,\r
165                 Method = 18,\r
166                 _Unknown4 = 19,\r
167                 _Unknown5 = 20,\r
168                 MethodCall = 21,\r
169                 MethodResponse = 22\r
170         }\r
171 \r
172         internal enum TypeTag : byte\r
173         {\r
174                 PrimitiveType = 0,\r
175                 String = 1,\r
176                 ObjectType = 2,\r
177                 RuntimeType = 3,\r
178                 GenericType = 4,\r
179                 ArrayOfObject = 5,\r
180                 ArrayOfString = 6,\r
181                 ArrayOfPrimitiveType = 7\r
182         }\r
183 \r
184         internal enum ArrayStructure : byte\r
185         {\r
186                 SingleDimensional = 0,\r
187                 Jagged = 1,\r
188                 MultiDimensional = 2\r
189         }\r
190 \r
191         internal enum MethodFlags : byte\r
192         {\r
193                 NoArguments = 1,\r
194                 PrimitiveArguments = 2,\r
195                 ArgumentsInSimpleArray = 4,\r
196                 ArgumentsInMultiArray = 8,\r
197                 ExcludeLogicalCallContext = 16,\r
198                 IncludesLogicalCallContext = 64,\r
199                 IncludesSignature = 128,\r
200 \r
201                 FormatMask = 15,\r
202                 NeedsInfoArrayMask = 4 + 8 + 64 + 128\r
203         }\r
204 \r
205         internal enum ReturnTypeTag : byte\r
206         {\r
207                 Null = 2,\r
208                 PrimitiveType = 8,\r
209                 ObjectType = 16,\r
210                 Exception = 32\r
211         }\r
212 \r
213         enum BinaryTypeCode : byte\r
214         {\r
215                 Boolean = 1,\r
216                 Byte = 2,\r
217                 Char = 3,\r
218                 Decimal = 5,\r
219                 Double = 6,\r
220                 Int16 = 7,\r
221                 Int32 = 8,\r
222                 Int64 = 9,\r
223                 SByte = 10,\r
224                 Single = 11,\r
225                 TimeSpan = 12,\r
226                 DateTime = 13,\r
227                 UInt16 = 14,\r
228                 UInt32 = 15,\r
229                 UInt64 = 16,\r
230                 Null = 17,\r
231                 String = 18\r
232         }\r
233 \r
234 }\r