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