2 // System.BitConverter.cs
5 // Matt Kimball (matt@kimball.net)
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
33 public sealed class BitConverter
35 public static readonly bool IsLittleEndian
= AmILittleEndian ();
37 private BitConverter ()
41 static bool AmILittleEndian ()
43 byte[] one
= GetBytes ((int) 1);
44 return (one
[0] == 1);
47 public static long DoubleToInt64Bits (double value)
49 return ToInt64 (GetBytes (value), 0);
52 public static double Int64BitsToDouble (long value)
54 return ToDouble (GetBytes (value), 0);
57 unsafe static byte[] GetBytes (byte *ptr
, int count
)
59 byte [] ret
= new byte [count
];
61 for (int i
= 0; i
< count
; i
++) {
68 unsafe public static byte[] GetBytes (bool value)
70 return GetBytes ((byte *) &value, 1);
73 unsafe public static byte[] GetBytes (char value)
75 return GetBytes ((byte *) &value, 2);
78 unsafe public static byte[] GetBytes (short value)
80 return GetBytes ((byte *) &value, 2);
83 unsafe public static byte[] GetBytes (int value)
85 return GetBytes ((byte *) &value, 4);
88 unsafe public static byte[] GetBytes (long value)
90 return GetBytes ((byte *) &value, 8);
93 [CLSCompliant (false)]
94 unsafe public static byte[] GetBytes (ushort value)
96 return GetBytes ((byte *) &value, 2);
99 [CLSCompliant (false)]
100 unsafe public static byte[] GetBytes (uint value)
102 return GetBytes ((byte *) &value, 4);
105 [CLSCompliant (false)]
106 unsafe public static byte[] GetBytes (ulong value)
108 return GetBytes ((byte *) &value, 8);
111 unsafe public static byte[] GetBytes (float value)
113 return GetBytes ((byte *) &value, 4);
116 unsafe public static byte[] GetBytes (double value)
118 return GetBytes ((byte *) &value, 8);
121 unsafe static void PutBytes (byte *dst
, byte[] src
, int start_index
, int count
)
124 throw new ArgumentNullException ("value"); // gets called from methods with value params
128 throw new ArgumentOutOfRangeException ("startIndex < 0");
130 // avoid integer overflow (with large pos/neg start_index values)
131 if (src
.Length
- count
< start_index
) {
132 throw new ArgumentOutOfRangeException (Locale
.GetText (
133 "Value is too big to return the requested type."), "startIndex");
136 for (int i
= 0; i
< count
; i
++) {
137 dst
[i
] = src
[i
+ start_index
];
141 unsafe public static bool ToBoolean (byte[] value, int startIndex
)
144 throw new ArgumentNullException ("value");
147 throw new ArgumentOutOfRangeException ("startIndex < 0");
149 // avoid integer overflow (with large pos/neg start_index values)
150 if (value.Length
- 1 < startIndex
)
151 throw new ArgumentOutOfRangeException (Locale
.GetText (
152 "Value is too big to return the requested type."), "startIndex");
154 if (value [startIndex
] != 0)
160 unsafe public static char ToChar (byte[] value, int startIndex
)
164 PutBytes ((byte *) &ret
, value, startIndex
, 2);
169 unsafe public static short ToInt16 (byte[] value, int startIndex
)
173 PutBytes ((byte *) &ret
, value, startIndex
, 2);
178 unsafe public static int ToInt32 (byte[] value, int startIndex
)
182 PutBytes ((byte *) &ret
, value, startIndex
, 4);
187 unsafe public static long ToInt64 (byte[] value, int startIndex
)
191 PutBytes ((byte *) &ret
, value, startIndex
, 8);
196 [CLSCompliant (false)]
197 unsafe public static ushort ToUInt16 (byte[] value, int startIndex
)
201 PutBytes ((byte *) &ret
, value, startIndex
, 2);
206 [CLSCompliant (false)]
207 unsafe public static uint ToUInt32 (byte[] value, int startIndex
)
211 PutBytes ((byte *) &ret
, value, startIndex
, 4);
216 [CLSCompliant (false)]
217 unsafe public static ulong ToUInt64 (byte[] value, int startIndex
)
221 PutBytes ((byte *) &ret
, value, startIndex
, 8);
226 unsafe public static float ToSingle (byte[] value, int startIndex
)
230 PutBytes ((byte *) &ret
, value, startIndex
, 4);
235 unsafe public static double ToDouble (byte[] value, int startIndex
)
239 PutBytes ((byte *) &ret
, value, startIndex
, 8);
244 public static string ToString (byte[] value)
247 throw new ArgumentNullException ("value");
250 return ToString (value, 0, value.Length
);
253 public static string ToString (byte[] value, int startIndex
)
256 throw new ArgumentNullException ("value");
257 if (startIndex
< 0 || startIndex
> value.Length
- 1)
258 throw new ArgumentOutOfRangeException ("startIndex");
260 return ToString (value, startIndex
, value.Length
- startIndex
);
263 public static string ToString (byte[] value, int startIndex
, int length
)
266 throw new ArgumentNullException ("value");
269 // The 4th and last clause (start_index >= value.Length)
270 // was added as a small fix to a very obscure bug.
271 // It makes a small difference when start_index is
272 // outside the range and length==0.
273 if (startIndex
< 0 || length
< 0 || startIndex
>= value.Length
)
274 throw new ArgumentOutOfRangeException ("startIndex");
275 // note: re-ordered to avoid possible integer overflow
276 if (startIndex
> value.Length
- length
)
277 throw new ArgumentException ("startIndex + length > value.Length");
280 int end
= startIndex
+ length
;
282 for (int i
= startIndex
; i
< end
; i
++) {
286 char high
= (char)((value[i
] >> 4) & 0x0f);
287 char low
= (char)(value[i
] & 0x0f);
302 ret
= ret
+ high
+ low
;