[API] Add a couple of .NET 4.5 methods, from pull request 641, had to apply manually
authorMiguel de Icaza <miguel@gnome.org>
Wed, 23 Sep 2015 19:29:12 +0000 (15:29 -0400)
committerMiguel de Icaza <miguel@gnome.org>
Wed, 23 Sep 2015 19:31:00 +0000 (15:31 -0400)
mcs/class/System/System.Net/IPAddress.cs
mcs/class/System/Test/System.Net/IPAddressTest.cs

index 89fb47563b59af70715583545fe050662c7fea2f..04bf42eb87ba4edc50fdde571452482fe4b81cad 100644 (file)
@@ -257,7 +257,7 @@ namespace System.Net {
                                        if (i == (ips.Length - 1)) {
                                                if (i != 0  && val >= (256 << ((3 - i) * 8)))
                                                        return null;
-                                               else if (val > 0x3fffffffe) // this is the last number that parses correctly with MS
+                                               else if (val > 0xffffffff)
                                                        return null;
                                                i = 3;
                                        } else if (val >= 0x100)
@@ -378,8 +378,47 @@ namespace System.Net {
                                return m_Family;
                        }
                }
-               
-               
+
+#if NET_4_5
+
+               public IPAddress MapToIPv4 ()
+               {
+                       if (AddressFamily == AddressFamily.InterNetwork)
+                               return this;
+                       if (AddressFamily != AddressFamily.InterNetworkV6)
+                               throw new Exception ("Only AddressFamily.InterNetworkV6 can be converted to IPv4");
+
+                       //Test for 0000 0000 0000 0000 0000 FFFF xxxx xxxx
+                       for (int i = 0; i < 5; i++) {
+                               if (m_Numbers [i] != 0x0000)
+                                       throw new Exception ("Address does not have the ::FFFF prefix");
+                       }
+                       if (m_Numbers [5] != 0xFFFF)
+                               throw new Exception ("Address does not have the ::FFFF prefix");
+
+                       //We've got an IPv4 address
+                       byte [] ipv4Bytes = new byte [4];
+                       Buffer.BlockCopy (m_Numbers, 12, ipv4Bytes, 0, 4);
+                       return new IPAddress (ipv4Bytes);
+               }
+
+               public IPAddress MapToIPv6 ()
+               {
+                       if (AddressFamily == AddressFamily.InterNetworkV6)
+                               return this;
+                       if (AddressFamily != AddressFamily.InterNetwork)
+                               throw new Exception ("Only AddressFamily.InterNetworkV4 can be converted to IPv6");
+
+                       byte [] ipv4Bytes = GetAddressBytes ();
+                       byte [] ipv6Bytes = new byte [16] {
+                               0,0, 0,0, 0,0, 0,0, 0,0, 0xFF,0xFF,
+                               ipv4Bytes [0], ipv4Bytes [1], ipv4Bytes [2], ipv4Bytes [3]
+                       };
+                       return new IPAddress (ipv6Bytes);
+               }
+
+#endif
+
                /// <summary>
                ///   Used to tell whether an address is a loopback.
                ///   All IP addresses of the form 127.X.Y.Z, where X, Y, and Z are in 
index 39866f384b6993f4f824505b373a9980f32936c5..db5d86eef2e765c21bb923d81842d834f2ec128c 100644 (file)
@@ -160,7 +160,6 @@ public class IPAddressTest
                "20.65535", "20.0.255.255",
                "0313.027035210", "203.92.58.136", // bug #411920
                "0313.0134.035210", "203.92.58.136", // too
-               "7848198702", "211.202.2.46", // too
                "1434328179", "85.126.28.115", // too
                "3397943208", "202.136.127.168", // too
        };
@@ -186,9 +185,12 @@ public class IPAddressTest
                "12.",
                "12.1.2.",
                "12...",
-               "  "
+               "  ",
+               "7848198702",
        };
 
+       static byte [] ipv4MappedIPv6Prefix = new byte [] { 0,0, 0,0, 0,0, 0,0, 0,0, 0xFF,0xFF };
+
        [Test]
        public void PublicFields ()
        {
@@ -639,6 +641,56 @@ public class IPAddressTest
                        }
                }
        }
+
+#if NET_4_5
+
+       [Test]
+       public void MapToIPv6 ()
+       {
+               for (int i = 0; i < ipv4ParseOk.Length / 2; i++) {
+                       IPAddress v4 = IPAddress.Parse (ipv4ParseOk [i * 2]);
+                       byte [] v4bytes = v4.GetAddressBytes ();
+                       IPAddress v6 = v4.MapToIPv6 ();
+                       byte [] v6bytes = v6.GetAddressBytes ();
+                       IPAddress v4back = v6.MapToIPv4 ();
+
+                       Assert.IsTrue (StartsWith (v6bytes, ipv4MappedIPv6Prefix), "MapToIPv6 #" + i + ".1");
+                       Assert.IsTrue (v6bytes [12] == v4bytes [0], "MapToIPv6 #" + i + ".2");
+                       Assert.IsTrue (v6bytes [13] == v4bytes [1], "MapToIPv6 #" + i + ".3");
+                       Assert.IsTrue (v6bytes [14] == v4bytes [2], "MapToIPv6 #" + i + ".4");
+                       Assert.IsTrue (v6bytes [15] == v4bytes [3], "MapToIPv6 #" + i + ".5");
+                       Assert.IsTrue (v4.Equals (v4back), "MapToIPv4 #" + i);
+               }
+
+               //TODO: Test using MapToIPv4/6 with anything other than IPv4/6 addresses.
+               //Currently it is not possible to do with the IPAddress implementation.
+       }
+
+       static bool StartsWith (byte [] a, byte [] b)
+       {
+               if (a.Length < b.Length)
+                       return false;
+               for (int i = 0; i < b.Length; i++)
+               {
+                       if (a [i] != b [i])
+                               return false;
+               }
+               return true;
+       }
+
+#endif
+
+       [Test]
+       public void EqualsFromBytes ()
+       {
+               for (int i = 0; i < ipv4ParseOk.Length / 2; i++) {
+                       IPAddress ip = IPAddress.Parse (ipv4ParseOk [i * 2]);
+                       IPAddress ipFromBytes = new IPAddress (ip.GetAddressBytes ());
+                       Assert.IsTrue (ip.Equals (ipFromBytes), "EqualsFromBytes #" + i);
+               }
+
+       }
+
 }
 }