2004-04-08 Bernie Solomon <bernard@ugsolutions.com>
[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 using System;
10
11 namespace Mono.Security
12 {
13         internal sealed class BitConverterLE
14         {
15                 private BitConverterLE ()
16                 {
17                 }
18
19                 unsafe private static byte[] GetUShortBytes (byte *bytes)
20                 {
21                         if (BitConverter.IsLittleEndian)
22                                 return new byte [] { bytes [0], bytes [1] };
23                         else
24                                 return new byte [] { bytes [1], bytes [0] };
25                 }
26
27                 unsafe private static byte[] GetUIntBytes (byte *bytes)
28                 {
29                         if (BitConverter.IsLittleEndian)
30                                 return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3] };
31                         else
32                                 return new byte [] { bytes [3], bytes [2], bytes [1], bytes [0] };
33                 }
34
35                 unsafe private static byte[] GetULongBytes (byte *bytes)
36                 {
37                         if (BitConverter.IsLittleEndian)
38                                 return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3],
39                                                      bytes [4], bytes [5], bytes [6], bytes [7] };
40                         else
41                                 return new byte [] { bytes [7], bytes [6], bytes [5], bytes [4],
42                                                      bytes [3], bytes [2], bytes [1], bytes [0] };
43                 }
44
45                 unsafe internal static byte[] GetBytes (bool value)
46                 {
47                         return new byte [] { value ? (byte)1 : (byte)0 };
48                 }
49
50                 unsafe internal static byte[] GetBytes (char value)
51                 {
52                         return GetUShortBytes ((byte *) &value);
53                 }
54
55                 unsafe internal static byte[] GetBytes (short value)
56                 {
57                         return GetUShortBytes ((byte *) &value);
58                 }
59
60                 unsafe internal static byte[] GetBytes (int value)
61                 {
62                         return GetUIntBytes ((byte *) &value);
63                 }
64
65                 unsafe internal static byte[] GetBytes (long value)
66                 {
67                         return GetULongBytes ((byte *) &value);
68                 }
69
70                 unsafe internal static byte[] GetBytes (ushort value)
71                 {
72                         return GetUShortBytes ((byte *) &value);
73                 }
74
75                 unsafe internal static byte[] GetBytes (uint value)
76                 {
77                         return GetUIntBytes ((byte *) &value);
78                 }
79
80                 unsafe internal static byte[] GetBytes (ulong value)
81                 {
82                         return GetULongBytes ((byte *) &value);
83                 }
84
85                 unsafe internal static byte[] GetBytes (float value)
86                 {
87                         return GetUIntBytes ((byte *) &value);
88                 }
89
90                 unsafe internal static byte[] GetBytes (double value)
91                 {
92                         return GetULongBytes ((byte *) &value);
93                 }
94
95                 unsafe private static void UShortFromBytes (byte *dst, byte[] src, int startIndex)
96                 {
97                         if (BitConverter.IsLittleEndian) {
98                                 dst [0] = src [startIndex];
99                                 dst [1] = src [startIndex + 1];
100                         } else {
101                                 dst [0] = src [startIndex + 1];
102                                 dst [1] = src [startIndex];
103                         }
104                 }
105
106                 unsafe private static void UIntFromBytes (byte *dst, byte[] src, int startIndex)
107                 {
108                         if (BitConverter.IsLittleEndian) {
109                                 dst [0] = src [startIndex];
110                                 dst [1] = src [startIndex + 1];
111                                 dst [2] = src [startIndex + 2];
112                                 dst [3] = src [startIndex + 3];
113                         } else {
114                                 dst [0] = src [startIndex + 3];
115                                 dst [1] = src [startIndex + 2];
116                                 dst [2] = src [startIndex + 1];
117                                 dst [3] = src [startIndex];
118                         }
119                 }
120
121                 unsafe private static void ULongFromBytes (byte *dst, byte[] src, int startIndex)
122                 {
123                         if (BitConverter.IsLittleEndian) {
124                                 for (int i = 0; i < 8; ++i)
125                                         dst [i] = src [startIndex + i];
126                         } else {
127                                 for (int i = 0; i < 8; ++i)
128                                         dst [i] = src [startIndex + (7 - i)];
129                         }
130                 }
131
132                 unsafe internal static bool ToBoolean (byte[] value, int startIndex)
133                 {
134                         return value [startIndex] != 0;
135                 }
136
137                 unsafe internal static char ToChar (byte[] value, int startIndex)
138                 {
139                         char ret;
140
141                         UShortFromBytes ((byte *) &ret, value, startIndex);
142
143                         return ret;
144                 }
145
146                 unsafe internal static short ToInt16 (byte[] value, int startIndex)
147                 {
148                         short ret;
149
150                         UShortFromBytes ((byte *) &ret, value, startIndex);
151
152                         return ret;
153                 }
154
155                 unsafe internal static int ToInt32 (byte[] value, int startIndex)
156                 {
157                         int ret;
158
159                         UIntFromBytes ((byte *) &ret, value, startIndex);
160
161                         return ret;
162                 }
163
164                 unsafe internal static long ToInt64 (byte[] value, int startIndex)
165                 {
166                         long ret;
167
168                         ULongFromBytes ((byte *) &ret, value, startIndex);
169
170                         return ret;
171                 }
172
173                 unsafe internal static ushort ToUInt16 (byte[] value, int startIndex)
174                 {
175                         ushort ret;
176
177                         UShortFromBytes ((byte *) &ret, value, startIndex);
178
179                         return ret;
180                 }
181
182                 unsafe internal static uint ToUInt32 (byte[] value, int startIndex)
183                 {
184                         uint ret;
185
186                         UIntFromBytes ((byte *) &ret, value, startIndex);
187
188                         return ret;
189                 }
190
191                 unsafe internal static ulong ToUInt64 (byte[] value, int startIndex)
192                 {
193                         ulong ret;
194
195                         ULongFromBytes ((byte *) &ret, value, startIndex);
196
197                         return ret;
198                 }
199
200                 unsafe internal static float ToSingle (byte[] value, int startIndex)
201                 {
202                         float ret;
203
204                         UIntFromBytes ((byte *) &ret, value, startIndex);
205
206                         return ret;
207                 }
208
209                 unsafe internal static double ToDouble (byte[] value, int startIndex)
210                 {
211                         double ret;
212
213                         ULongFromBytes ((byte *) &ret, value, startIndex);
214
215                         return ret;
216                 }
217         }
218 }