2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / Mono.Security / BitConverterLE.cs
1 //
2 // Mono.Security.BitConverterLE.cs
3 //  Like System.BitConverter but always little endian
4 //
5 // Author:
6 //   Bernie Solomon
7 //
8
9 //
10 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System;
33
34 namespace Mono.Security
35 {
36         internal sealed class BitConverterLE
37         {
38                 private BitConverterLE ()
39                 {
40                 }
41
42                 unsafe private static byte[] GetUShortBytes (byte *bytes)
43                 {
44                         if (BitConverter.IsLittleEndian)
45                                 return new byte [] { bytes [0], bytes [1] };
46                         else
47                                 return new byte [] { bytes [1], bytes [0] };
48                 }
49
50                 unsafe private static byte[] GetUIntBytes (byte *bytes)
51                 {
52                         if (BitConverter.IsLittleEndian)
53                                 return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3] };
54                         else
55                                 return new byte [] { bytes [3], bytes [2], bytes [1], bytes [0] };
56                 }
57
58                 unsafe private static byte[] GetULongBytes (byte *bytes)
59                 {
60                         if (BitConverter.IsLittleEndian)
61                                 return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3],
62                                                      bytes [4], bytes [5], bytes [6], bytes [7] };
63                         else
64                                 return new byte [] { bytes [7], bytes [6], bytes [5], bytes [4],
65                                                      bytes [3], bytes [2], bytes [1], bytes [0] };
66                 }
67
68                 unsafe internal static byte[] GetBytes (bool value)
69                 {
70                         return new byte [] { value ? (byte)1 : (byte)0 };
71                 }
72
73                 unsafe internal static byte[] GetBytes (char value)
74                 {
75                         return GetUShortBytes ((byte *) &value);
76                 }
77
78                 unsafe internal static byte[] GetBytes (short value)
79                 {
80                         return GetUShortBytes ((byte *) &value);
81                 }
82
83                 unsafe internal static byte[] GetBytes (int value)
84                 {
85                         return GetUIntBytes ((byte *) &value);
86                 }
87
88                 unsafe internal static byte[] GetBytes (long value)
89                 {
90                         return GetULongBytes ((byte *) &value);
91                 }
92
93                 unsafe internal static byte[] GetBytes (ushort value)
94                 {
95                         return GetUShortBytes ((byte *) &value);
96                 }
97
98                 unsafe internal static byte[] GetBytes (uint value)
99                 {
100                         return GetUIntBytes ((byte *) &value);
101                 }
102
103                 unsafe internal static byte[] GetBytes (ulong value)
104                 {
105                         return GetULongBytes ((byte *) &value);
106                 }
107
108                 unsafe internal static byte[] GetBytes (float value)
109                 {
110                         return GetUIntBytes ((byte *) &value);
111                 }
112
113                 unsafe internal static byte[] GetBytes (double value)
114                 {
115                         return GetULongBytes ((byte *) &value);
116                 }
117
118                 unsafe private static void UShortFromBytes (byte *dst, byte[] src, int startIndex)
119                 {
120                         if (BitConverter.IsLittleEndian) {
121                                 dst [0] = src [startIndex];
122                                 dst [1] = src [startIndex + 1];
123                         } else {
124                                 dst [0] = src [startIndex + 1];
125                                 dst [1] = src [startIndex];
126                         }
127                 }
128
129                 unsafe private static void UIntFromBytes (byte *dst, byte[] src, int startIndex)
130                 {
131                         if (BitConverter.IsLittleEndian) {
132                                 dst [0] = src [startIndex];
133                                 dst [1] = src [startIndex + 1];
134                                 dst [2] = src [startIndex + 2];
135                                 dst [3] = src [startIndex + 3];
136                         } else {
137                                 dst [0] = src [startIndex + 3];
138                                 dst [1] = src [startIndex + 2];
139                                 dst [2] = src [startIndex + 1];
140                                 dst [3] = src [startIndex];
141                         }
142                 }
143
144                 unsafe private static void ULongFromBytes (byte *dst, byte[] src, int startIndex)
145                 {
146                         if (BitConverter.IsLittleEndian) {
147                                 for (int i = 0; i < 8; ++i)
148                                         dst [i] = src [startIndex + i];
149                         } else {
150                                 for (int i = 0; i < 8; ++i)
151                                         dst [i] = src [startIndex + (7 - i)];
152                         }
153                 }
154
155                 unsafe internal static bool ToBoolean (byte[] value, int startIndex)
156                 {
157                         return value [startIndex] != 0;
158                 }
159
160                 unsafe internal static char ToChar (byte[] value, int startIndex)
161                 {
162                         char ret;
163
164                         UShortFromBytes ((byte *) &ret, value, startIndex);
165
166                         return ret;
167                 }
168
169                 unsafe internal static short ToInt16 (byte[] value, int startIndex)
170                 {
171                         short ret;
172
173                         UShortFromBytes ((byte *) &ret, value, startIndex);
174
175                         return ret;
176                 }
177
178                 unsafe internal static int ToInt32 (byte[] value, int startIndex)
179                 {
180                         int ret;
181
182                         UIntFromBytes ((byte *) &ret, value, startIndex);
183
184                         return ret;
185                 }
186
187                 unsafe internal static long ToInt64 (byte[] value, int startIndex)
188                 {
189                         long ret;
190
191                         ULongFromBytes ((byte *) &ret, value, startIndex);
192
193                         return ret;
194                 }
195
196                 unsafe internal static ushort ToUInt16 (byte[] value, int startIndex)
197                 {
198                         ushort ret;
199
200                         UShortFromBytes ((byte *) &ret, value, startIndex);
201
202                         return ret;
203                 }
204
205                 unsafe internal static uint ToUInt32 (byte[] value, int startIndex)
206                 {
207                         uint ret;
208
209                         UIntFromBytes ((byte *) &ret, value, startIndex);
210
211                         return ret;
212                 }
213
214                 unsafe internal static ulong ToUInt64 (byte[] value, int startIndex)
215                 {
216                         ulong ret;
217
218                         ULongFromBytes ((byte *) &ret, value, startIndex);
219
220                         return ret;
221                 }
222
223                 unsafe internal static float ToSingle (byte[] value, int startIndex)
224                 {
225                         float ret;
226
227                         UIntFromBytes ((byte *) &ret, value, startIndex);
228
229                         return ret;
230                 }
231
232                 unsafe internal static double ToDouble (byte[] value, int startIndex)
233                 {
234                         double ret;
235
236                         ULongFromBytes ((byte *) &ret, value, startIndex);
237
238                         return ret;
239                 }
240         }
241 }