* Rewrote IPAddress.Parse method, passing all unit tests
authorLawrence Pit <lawrence@mono-cvs.ximian.com>
Thu, 9 May 2002 10:43:34 +0000 (10:43 -0000)
committerLawrence Pit <lawrence@mono-cvs.ximian.com>
Thu, 9 May 2002 10:43:34 +0000 (10:43 -0000)
svn path=/trunk/mcs/; revision=4439

mcs/class/System/System.Net/IPAddress.cs
mcs/class/System/Test/System.Net/IPAddressTest.cs

index 758e23910a09142d60381eb704b072f4f0e13f46..86041acb8622f85ab2071a5af331627ca53974aa 100755 (executable)
@@ -3,17 +3,18 @@
 //
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
+//   Lawrence Pit (loz@cable.a2000.nl)
 //
 // (C) Ximian, Inc.  http://www.ximian.com
 //
 //
 // Note: the address is stored in host order
 
+using System;
+using System.Globalization;
 using System.Net.Sockets;
 using System.Runtime.InteropServices;
 
-using System;
-
 namespace System.Net {
 
        /// <remarks>
@@ -108,50 +109,52 @@ namespace System.Net {
                        Address = addr;
                }
 
-               public static IPAddress Parse(string ip)
+               public static IPAddress Parse (string ip)
                {
-                       if(ip == null)
-                               throw new ArgumentNullException("null ip string");
-
-                       int pos = 0;
-                       int ndots = 0;
-                       char current;
-                       bool prevDigit = false;
-
-                       while (pos < ip.Length) {
-                               current  = ip [pos++];
-                               if (Char.IsDigit (current))
-                                       prevDigit = true;
-                               else
-                               if (current == '.') {
-                                       // No more than 3 dots. Doesn't allow ending with a dot.
-                                       if (++ndots > 3 || pos == ip.Length || prevDigit == false)
-                                               throw new FormatException ("the string is not a valid ip");
-
-                                       prevDigit = false;
-                               }
-                               else if (!Char.IsDigit (current)) {
-                                       if (!Char.IsWhiteSpace (current))
-                                               throw new FormatException ("the string is not a valid ip");
+                       if (ip == null)
+                               throw new ArgumentNullException ("null ip string");
+                               
+                       if (ip.Length == 0 || ip [0] == ' ')
+                               return new IPAddress (0);
+                               
+                       int pos = ip.IndexOf (' ');
+                       if (pos != -1)
+                               ip = ip.Substring (0, pos);                             
+                       else if (ip [ip.Length - 1] == '.')
+                               throw new FormatException ("An invalid IP address was specified");
 
-                                       // The same as MS does
-                                       if (pos == 1) 
-                                               return new IPAddress (0);
-
-                                       break;
-                               }
-                       }
-
-                       if (ndots != 3)
-                               throw new FormatException ("the string is not a valid ip");
-
-
-                       long a = 0;
                        string [] ips = ip.Split (new char [] {'.'});
+                       if (ips.Length > 4)
+                               throw new FormatException ("An invalid IP address was specified");
+                       
                        // Make the number in network order
-                       for (int i = ips.Length - 1; i >= 0; i--)
-                               a = (a << 8) |  (Byte.Parse(ips [i]));
-                       return (new IPAddress (a));
+                       try {
+                               long a = 0;
+                               byte val = 0;
+                               for (int i = 0; i < ips.Length; i++) {
+                                       string subnet = ips [i];
+                                       if ((3 <= subnet.Length && subnet.Length <= 4) &&
+                                           (subnet [0] == '0') &&
+                                           (subnet [1] == 'x' || subnet [2] == 'X')) {
+                                               if (subnet.Length == 3)
+                                                       val = (byte) Uri.FromHex (subnet [2]);
+                                               else 
+                                                       val = (byte) ((Uri.FromHex (subnet [2]) << 4) | Uri.FromHex (subnet [3]));
+                                       } else if (subnet.Length == 0)
+                                               val = 0;
+                                       else 
+                                               val = Byte.Parse (subnet, NumberStyles.None);
+
+                                       if (ips.Length < 4 && i == (ips.Length - 1)) 
+                                               i = 3;
+
+                                       a |= (long) val << (i << 3);
+                               }
+
+                               return (new IPAddress (a));
+                       } catch (Exception) {
+                               throw new FormatException ("An invalid IP address was specified");
+                       }
                }
                
                public long Address {
index a5ab5d0298d973aabc3047f92df96701f64b6e43..6e82828ad2253e7aec9a002569c27bd430af1e62 100644 (file)
@@ -89,6 +89,9 @@ public class IPAddressTest : TestCase
                ip = IPAddress.Parse ("0xff.0x7f.0x20.0x01");
                Assert ("Parse #1b", ip.ToString () == "255.127.32.1");
 
+               ip = IPAddress.Parse ("0xff.0x7f.0x20.0xf");
+               Assert ("Parse #1c", ip.ToString () == "255.127.32.15");
+
                ip = IPAddress.Parse ("0.0.0.0");
                AssertEquals ("Parse #2", ip, IPAddress.Any);
 
@@ -102,7 +105,6 @@ public class IPAddressTest : TestCase
                ip = IPAddress.Parse ("12.1.1.3 ");
                AssertEquals ("Parse #6", IPAddress.Parse ("12.1.1.3"), ip);
 
-               // These have a strange behavior !?
                ip = IPAddress.Parse (" 12.1.1.1");
                AssertEquals ("Parse #7", IPAddress.Parse ("0.0.0.0"), ip);
 
@@ -116,10 +118,10 @@ public class IPAddressTest : TestCase
                AssertEquals ("Parse #10", IPAddress.Parse ("12.1.0.7"), ip);
 
                ip = IPAddress.Parse ("12.1.8. ");
-               AssertEquals ("Parse #10", IPAddress.Parse ("12.1.8.0"), ip);
+               AssertEquals ("Parse #11", IPAddress.Parse ("12.1.8.0"), ip);
 
                ip = IPAddress.Parse ("12");
-               AssertEquals ("Parse #11", IPAddress.Parse ("0.0.0.12"), ip);   
+               AssertEquals ("Parse #12", IPAddress.Parse ("0.0.0.12"), ip);   
 
                ip = IPAddress.Parse ("12.1 foo.1.2.3.4.5.bar");
                AssertEquals ("Parse #13", IPAddress.Parse ("12.0.0.1"), ip);                   
@@ -129,12 +131,17 @@ public class IPAddressTest : TestCase
 
                ip = IPAddress.Parse ("12.. .");
                AssertEquals ("Parse #15", IPAddress.Parse ("12.0.0.0"), ip);                   
+
+               ip = IPAddress.Parse (" ");
+               AssertEquals ("Parse #16", IPAddress.Parse ("0.0.0.0"), ip);                    
+
+               ip = IPAddress.Parse (" foo");
+               AssertEquals ("Parse #17", IPAddress.Parse ("0.0.0.0"), ip);                    
        }
 
        public void TestParseWrong ()
        {
                IPAddress ip = IPAddress.None;
-
                try {
                        ip = IPAddress.Parse ("12.+1.1.4");
                         Fail("Should raise a FormatException #1");
@@ -171,12 +178,12 @@ public class IPAddressTest : TestCase
                        ip = IPAddress.Parse ("12.");
                        Fail ("ParseWrong #5: Should raise a FormatException");
                } catch (FormatException) {}
-               
+
                try {
                        ip = IPAddress.Parse ("12.1.2.");
                        Fail ("ParseWrong #6: Should raise a FormatException");
                } catch (FormatException) {}            
-               
+
                try {
                        ip = IPAddress.Parse ("12...");
                        Fail ("ParseWrong #7: Should raise a FormatException");