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