Ok, here is the patch for the System.Net.NetInformation.PhysicalAddress. This is a big rewrite from the one revision 82491. I've also included a unit test class (as there wasn't one) which passes all tests in both .NET 2.0 and the patched version of PhysicalAddress. During the testing I found some interesting MS behavior which is documented in the asserts of the test (the tests can be refactored if needed, i ran out of time). For what it is worth the GetHashCode also returns the same value in both .NET and the patched file.
Cheers, Jae
Index: System.Net.NetworkInformation/PhysicalAddress.cs =================================================================== --- System.Net.NetworkInformation/PhysicalAddress.cs (revision 82491) +++ System.Net.NetworkInformation/PhysicalAddress.cs (working copy) @@ -32,6 +32,7 @@ namespace System.Net.NetworkInformation { public class PhysicalAddress { public static readonly PhysicalAddress None = new PhysicalAddress (new byte [0]); + private const int numberOfBytes = 6; byte [] bytes; public PhysicalAddress (byte [] address) @@ -44,28 +45,34 @@ if (address == null) return None; - if (address == "") - throw new FormatException ("Invalid physical address."); + if (address == string.Empty) + throw new FormatException("An invalid physical address was specified."); - // MS fails with IndexOutOfRange for something like: "00-0" - int ndashes = 0; - foreach (char c in address) { - if (c == '-') - ndashes++; + string[] addrSplit = address.Split('-'); + + if (addrSplit.Length == 1) { + if (address.Length != numberOfBytes * 2) + throw new FormatException("An invalid physical address was specified."); + + addrSplit = new string[numberOfBytes]; + for (int index = 0; index < addrSplit.Length; index++) { + addrSplit[index] = address.Substring(index * 2, 2); + } } - int len = address.Length; - if (((len - 2) / 3) != ndashes) - throw new FormatException ("Invalid physical address."); + if (addrSplit.Length == numberOfBytes) { + foreach (string str in addrSplit) + if (str.Length != 2) + throw new FormatException("An invalid physical address was specified."); + } + else + throw new FormatException("An invalid physical address was specified."); - byte [] data = new byte [ndashes + 1]; - int idx = 0; - for (int i = 0; i < len; i++) { - byte b = (byte) (GetValue (address [i++]) << 8); - b += GetValue (address [i++]); - if (address [i] != '-') - throw new FormatException ("Invalid physical address."); - data [idx++] = b; + byte[] data = new byte[numberOfBytes]; + for (int i = 0; i < numberOfBytes; i++) { + byte b = (byte)(GetValue(addrSplit[i][0]) << 4); + b += GetValue(addrSplit[i][1]); + data[i] = b; } return new PhysicalAddress (data); @@ -73,7 +80,7 @@ static byte GetValue (char c) { - if (c >= 0 && c <= 9) + if (c >= '0' && c <= '9') return (byte) (c - '0'); if (c >= 'a' && c <= 'f') @@ -91,20 +98,25 @@ if (other == null) return false; - // new byte [0] != new byte [0] - return (bytes == other.bytes); + if (bytes.Length == 0 && other.bytes.Length == 0) + return true; + + if (bytes.Length == other.bytes.Length) + { + for (int index = 0; index < bytes.Length; index++) + { + if (bytes[index] != other.bytes[index]) + return false; + } + return true; + } + else + return false; } public override int GetHashCode () { - if (bytes == null) - return 0; - - int a = 5; - foreach (byte b in bytes) - a = (a << 3) + b; - - return a; + return (bytes[5] << 8) ^ (bytes[4]) ^ (bytes[3] << 24) ^ (bytes[2] << 16) ^ (bytes[1] << 8) ^ (bytes[0]); } public byte [] GetAddressBytes () @@ -119,7 +131,7 @@ StringBuilder sb = new StringBuilder (); foreach (byte b in bytes) - sb.AppendFormat ("{0:2X}", (uint) b); + sb.AppendFormat("{0:X2}", b); return sb.ToString (); } }
#if NET_2_0 using System; using System.Net.NetworkInformation; using NUnit.Framework; namespace MonoTests.System.Net.NetworkInformation { [TestFixture] public class PhysicalAddressTest { [Test] public void CreatePhysicalAddress() { PhysicalAddress phys = new PhysicalAddress(new byte [] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }); bool created = false; try { phys = new PhysicalAddress(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); created = true; } catch (Exception e) {} if (!created) Assert.Fail("MS.NET 2.0 Allows Physical Address to be created if array larger than normal."); created = false; try { phys = new PhysicalAddress(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 }); created = true; } catch (Exception e) {} if (!created) Assert.Fail("MS.NET 2.0 Allows Physical Address to be created if array smaller than normal."); } [Test] public void ParsePhysicalAddress() { try { PhysicalAddress phys = PhysicalAddress.Parse("010203040506"); } catch (Exception e) { Assert.Fail("MS.NET 2.0 Parses without the dash separator"); } bool created = false; try { PhysicalAddress phys = PhysicalAddress.Parse("01020304050"); created = true; } catch (Exception e) { } if (created) Assert.Fail("MS.NET 2.0 Fails parse when too few characters"); created = false; try { PhysicalAddress phys = PhysicalAddress.Parse("0102030405060"); created = true; } catch (Exception e) { } if (created) Assert.Fail("MS.NET 2.0 Fails parse when too many characters"); try { PhysicalAddress phys = PhysicalAddress.Parse("01-02-03-04-05-06"); } catch (Exception e) { Assert.Fail("MS.NET 2.0 Parses with the dash separator"); } created = false; try { PhysicalAddress phys = PhysicalAddress.Parse("01-02-03-04-05-0"); created = true; } catch (Exception e) {} if (created) Assert.Fail("MS.NET 2.0 Fails parse when too few characters"); created = false; try { PhysicalAddress phys = PhysicalAddress.Parse("01-02-03-04-05-060"); created = true; } catch (Exception e) { } if (created) Assert.Fail("MS.NET 2.0 Fails parse when too many characters"); } [Test] public void GetHashCode() { PhysicalAddress phys1 = new PhysicalAddress(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }); PhysicalAddress phys2 = new PhysicalAddress(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }); Assert.AreEqual(phys1.GetHashCode(), phys2.GetHashCode()); } [Test] public void ToString() { PhysicalAddress phys1 = new PhysicalAddress(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }); string strTest = phys1.ToString(); int index = strTest.IndexOfAny(new char [] { '-', ':', ' '}); Assert.AreEqual(-1, index); } [Test] public void Equals() { PhysicalAddress phys1 = new PhysicalAddress(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }); PhysicalAddress phys2 = new PhysicalAddress(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }); Assert.IsTrue(phys1.Equals(phys2)); phys1 = new PhysicalAddress(new byte[] { 0x06, 0x5, 0x04, 0x03, 0x02, 0x01 }); phys2 = new PhysicalAddress(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }); Assert.IsTrue(!phys1.Equals(phys2)); } } }#endif
_______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list