1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Linq; 6 using System.Text; 7 using Xunit; 8 9 namespace System.Tests 10 { 11 public static partial class BitConverterTests 12 { 13 [Fact] IsLittleEndian()14 public static unsafe void IsLittleEndian() 15 { 16 short s = 1; 17 Assert.Equal(BitConverter.IsLittleEndian, *((byte*)&s) == 1); 18 } 19 20 [Fact] ValueArgumentNull()21 public static void ValueArgumentNull() 22 { 23 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToBoolean(null, 0)); 24 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToChar(null, 0)); 25 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToDouble(null, 0)); 26 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToInt16(null, 0)); 27 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToInt32(null, 0)); 28 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToInt64(null, 0)); 29 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToSingle(null, 0)); 30 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToUInt16(null, 0)); 31 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToUInt32(null, 0)); 32 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToUInt64(null, 0)); 33 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToString(null)); 34 AssertExtensions.Throws<ArgumentNullException>("value", () => BitConverter.ToString(null, 0)); 35 AssertExtensions.Throws<ArgumentNullException>("value", null /* param name varies in NETFX */, () => BitConverter.ToString(null, 0, 0)); 36 } 37 38 [Fact] StartIndexBeyondLength()39 public static void StartIndexBeyondLength() 40 { 41 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToBoolean(new byte[1], -1)); 42 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToBoolean(new byte[1], 1)); 43 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToBoolean(new byte[1], 2)); 44 45 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToChar(new byte[2], -1)); 46 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToChar(new byte[2], 2)); 47 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToChar(new byte[2], 3)); 48 49 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToDouble(new byte[8], -1)); 50 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToDouble(new byte[8], 8)); 51 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToDouble(new byte[8], 9)); 52 53 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToInt16(new byte[2], -1)); 54 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToInt16(new byte[2], 2)); 55 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToInt16(new byte[2], 3)); 56 57 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToInt32(new byte[4], -1)); 58 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToInt32(new byte[4], 4)); 59 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToInt32(new byte[4], 5)); 60 61 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToInt64(new byte[8], -1)); 62 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToInt64(new byte[8], 8)); 63 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToInt64(new byte[8], 9)); 64 65 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToSingle(new byte[4], -1)); 66 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToSingle(new byte[4], 4)); 67 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToSingle(new byte[4], 5)); 68 69 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToUInt16(new byte[2], -1)); 70 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToUInt16(new byte[2], 2)); 71 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToUInt16(new byte[2], 3)); 72 73 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToUInt32(new byte[4], -1)); 74 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToUInt32(new byte[4], 4)); 75 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToUInt32(new byte[4], 5)); 76 77 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToUInt64(new byte[8], -1)); 78 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToUInt64(new byte[8], 8)); 79 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToUInt64(new byte[8], 9)); 80 81 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToString(new byte[1], -1)); 82 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToString(new byte[1], 1)); 83 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToString(new byte[1], 2)); 84 85 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToString(new byte[1], -1, 0)); 86 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToString(new byte[1], 1, 0)); 87 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToString(new byte[1], 2, 0)); 88 89 AssertExtensions.Throws<ArgumentOutOfRangeException>("length", () => BitConverter.ToString(new byte[1], 0, -1)); 90 } 91 92 [Fact] StartIndexPlusNeededLengthTooLong()93 public static void StartIndexPlusNeededLengthTooLong() 94 { 95 AssertExtensions.Throws<ArgumentOutOfRangeException>("startIndex", () => BitConverter.ToBoolean(new byte[0], 0)); 96 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToChar(new byte[2], 1)); 97 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToDouble(new byte[8], 1)); 98 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToInt16(new byte[2], 1)); 99 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToInt32(new byte[4], 1)); 100 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToInt64(new byte[8], 1)); 101 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToSingle(new byte[4], 1)); 102 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToUInt16(new byte[2], 1)); 103 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToUInt32(new byte[4], 1)); 104 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToUInt64(new byte[8], 1)); 105 AssertExtensions.Throws<ArgumentException>("value", null, () => BitConverter.ToString(new byte[2], 1, 2)); 106 } 107 108 [Fact] DoubleToInt64Bits()109 public static void DoubleToInt64Bits() 110 { 111 double input = 123456.3234; 112 long result = BitConverter.DoubleToInt64Bits(input); 113 Assert.Equal(4683220267154373240L, result); 114 double roundtripped = BitConverter.Int64BitsToDouble(result); 115 Assert.Equal(input, roundtripped); 116 } 117 118 [Fact] RoundtripBoolean()119 public static void RoundtripBoolean() 120 { 121 byte[] bytes = BitConverter.GetBytes(true); 122 Assert.Equal(1, bytes.Length); 123 Assert.Equal(1, bytes[0]); 124 Assert.True(BitConverter.ToBoolean(bytes, 0)); 125 126 bytes = BitConverter.GetBytes(false); 127 Assert.Equal(1, bytes.Length); 128 Assert.Equal(0, bytes[0]); 129 Assert.False(BitConverter.ToBoolean(bytes, 0)); 130 } 131 132 [Fact] RoundtripChar()133 public static void RoundtripChar() 134 { 135 char input = 'A'; 136 byte[] expected = { 0x41, 0 }; 137 VerifyRoundtrip(BitConverter.GetBytes, BitConverter.ToChar, input, expected); 138 } 139 140 [Fact] RoundtripDouble()141 public static void RoundtripDouble() 142 { 143 double input = 123456.3234; 144 byte[] expected = { 0x78, 0x7a, 0xa5, 0x2c, 0x05, 0x24, 0xfe, 0x40 }; 145 VerifyRoundtrip(BitConverter.GetBytes, BitConverter.ToDouble, input, expected); 146 } 147 148 [Fact] RoundtripSingle()149 public static void RoundtripSingle() 150 { 151 float input = 8392.34f; 152 byte[] expected = { 0x5c, 0x21, 0x03, 0x46 }; 153 VerifyRoundtrip(BitConverter.GetBytes, BitConverter.ToSingle, input, expected); 154 } 155 156 [Fact] RoundtripInt16()157 public static void RoundtripInt16() 158 { 159 short input = 0x1234; 160 byte[] expected = { 0x34, 0x12 }; 161 VerifyRoundtrip(BitConverter.GetBytes, BitConverter.ToInt16, input, expected); 162 } 163 164 [Fact] RoundtripInt32()165 public static void RoundtripInt32() 166 { 167 int input = 0x12345678; 168 byte[] expected = { 0x78, 0x56, 0x34, 0x12 }; 169 VerifyRoundtrip(BitConverter.GetBytes, BitConverter.ToInt32, input, expected); 170 } 171 172 [Fact] RoundtripInt64()173 public static void RoundtripInt64() 174 { 175 long input = 0x0123456789abcdef; 176 byte[] expected = { 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01 }; 177 VerifyRoundtrip(BitConverter.GetBytes, BitConverter.ToInt64, input, expected); 178 } 179 180 [Fact] RoundtripUInt16()181 public static void RoundtripUInt16() 182 { 183 ushort input = 0x1234; 184 byte[] expected = { 0x34, 0x12 }; 185 VerifyRoundtrip(BitConverter.GetBytes, BitConverter.ToUInt16, input, expected); 186 } 187 188 [Fact] RoundtripUInt32()189 public static void RoundtripUInt32() 190 { 191 uint input = 0x12345678; 192 byte[] expected = { 0x78, 0x56, 0x34, 0x12 }; 193 VerifyRoundtrip(BitConverter.GetBytes, BitConverter.ToUInt32, input, expected); 194 } 195 196 [Fact] RoundtripUInt64()197 public static void RoundtripUInt64() 198 { 199 ulong input = 0x0123456789abcdef; 200 byte[] expected = { 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01 }; 201 VerifyRoundtrip(BitConverter.GetBytes, BitConverter.ToUInt64, input, expected); 202 } 203 204 [Fact] RoundtripString()205 public static void RoundtripString() 206 { 207 byte[] bytes = { 0x12, 0x34, 0x56, 0x78, 0x9a }; 208 209 Assert.Equal("12-34-56-78-9A", BitConverter.ToString(bytes)); 210 Assert.Equal("56-78-9A", BitConverter.ToString(bytes, 2)); 211 Assert.Equal("56", BitConverter.ToString(bytes, 2, 1)); 212 213 Assert.Same(string.Empty, BitConverter.ToString(new byte[0])); 214 Assert.Same(string.Empty, BitConverter.ToString(new byte[3], 1, 0)); 215 } 216 217 [Fact] ToString_ByteArray_Long()218 public static void ToString_ByteArray_Long() 219 { 220 byte[] bytes = Enumerable.Range(0, 256 * 4).Select(i => unchecked((byte)i)).ToArray(); 221 222 string expected = string.Join("-", bytes.Select(b => b.ToString("X2"))); 223 224 Assert.Equal(expected, BitConverter.ToString(bytes)); 225 Assert.Equal(expected.Substring(3, expected.Length - 6), BitConverter.ToString(bytes, 1, bytes.Length - 2)); 226 } 227 228 [Fact] ToString_ByteArrayTooLong_Throws()229 public static void ToString_ByteArrayTooLong_Throws() 230 { 231 byte[] arr; 232 try 233 { 234 arr = new byte[int.MaxValue / 3 + 1]; 235 } 236 catch (OutOfMemoryException) 237 { 238 // Exit out of the test if we don't have an enough contiguous memory 239 // available to create a big enough array. 240 return; 241 } 242 243 AssertExtensions.Throws<ArgumentOutOfRangeException>("length", () => BitConverter.ToString(arr)); 244 } 245 VerifyRoundtrip(Func<TInput, Byte[]> getBytes, Func<Byte[], int, TInput> convertBack, TInput input, Byte[] expectedBytes)246 private static void VerifyRoundtrip<TInput>(Func<TInput, Byte[]> getBytes, Func<Byte[], int, TInput> convertBack, TInput input, Byte[] expectedBytes) 247 { 248 byte[] bytes = getBytes(input); 249 Assert.Equal(expectedBytes.Length, bytes.Length); 250 251 if (!BitConverter.IsLittleEndian) 252 { 253 Array.Reverse(expectedBytes); 254 } 255 256 Assert.Equal(expectedBytes, bytes); 257 Assert.Equal(input, convertBack(bytes, 0)); 258 259 // Also try unaligned startIndex 260 byte[] longerBytes = new byte[bytes.Length + 1]; 261 longerBytes[0] = 0; 262 Array.Copy(bytes, 0, longerBytes, 1, bytes.Length); 263 Assert.Equal(input, convertBack(longerBytes, 1)); 264 } 265 } 266 } 267