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

Reply via email to