[Mono.Security]: Add 'MonoTlsProvider.SupportsCleanShutdown' and 'MonoTlsSettings...
[mono.git] / mcs / class / System / System.Net / IPv6Address.cs
1 //\r
2 // System.Net.IPv6AddressFormatter.cs\r
3 //\r
4 // Author:\r
5 //   Lawrence Pit (loz@cable.a2000.nl)\r
6 //\r
7 // Permission is hereby granted, free of charge, to any person obtaining\r
8 // a copy of this software and associated documentation files (the\r
9 // "Software"), to deal in the Software without restriction, including\r
10 // without limitation the rights to use, copy, modify, merge, publish,\r
11 // distribute, sublicense, and/or sell copies of the Software, and to\r
12 // permit persons to whom the Software is furnished to do so, subject to\r
13 // the following conditions:\r
14 // \r
15 // The above copyright notice and this permission notice shall be\r
16 // included in all copies or substantial portions of the Software.\r
17 // \r
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
19 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
23 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
24 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
25 //\r
26 \r
27 using System.Globalization;\r
28 using System.Text;\r
29 \r
30 namespace System.Net {\r
31 \r
32         struct IPv6AddressFormatter\r
33         {\r
34                 ushort [] address;\r
35                 long scopeId;\r
36 \r
37                 public IPv6AddressFormatter (ushort[] addr, long scopeId)\r
38                 {\r
39                         this.address = addr;\r
40                         this.scopeId = scopeId;\r
41                 }\r
42 \r
43                 static ushort SwapUShort (ushort number)\r
44                 {\r
45                         return (ushort) ( ((number >> 8) & 0xFF) + ((number << 8) & 0xFF00) );\r
46                 }\r
47 \r
48                 // Convert the address into a format expected by the IPAddress (long) ctor\r
49                 // This needs to be unsigned to satisfy the '> 1' test in IsIPv4Compatible()\r
50                 uint AsIPv4Int ()\r
51                 {\r
52                         return (uint)(SwapUShort (address [7]) << 16) + SwapUShort (address [6]);\r
53                 }                       \r
54 \r
55                 bool IsIPv4Compatible ()\r
56                 {\r
57                         for (int i = 0; i < 6; i++) \r
58                                 if (address [i] != 0)\r
59                                         return false;\r
60                         /* MS .net only seems to format the last 4\r
61                          * bytes as an IPv4 address if address[6] is\r
62                          * non-zero\r
63                          */\r
64                         if (address[6] == 0)\r
65                                 return false;\r
66                         return (AsIPv4Int () > 1);\r
67                 }\r
68                 \r
69                 bool IsIPv4Mapped ()\r
70                 {\r
71                         for (int i = 0; i < 5; i++) \r
72                                 if (address [i] != 0)\r
73                                         return false;\r
74                         /* MS .net only seems to format the last 4\r
75                          * bytes as an IPv4 address if address[6] is\r
76                          * non-zero\r
77                          */\r
78                         if (address[6] == 0)\r
79                                 return false;\r
80                         \r
81                         return address [5] == 0xffff;\r
82                 }\r
83                 \r
84                 public override string ToString ()\r
85                 {\r
86                         StringBuilder s = new StringBuilder ();\r
87 \r
88 \r
89                         if(IsIPv4Compatible() || IsIPv4Mapped())\r
90                         {\r
91                                 s.Append("::");\r
92 \r
93                                 if(IsIPv4Mapped())\r
94                                         s.Append("ffff:");\r
95 \r
96                                 s.Append(new IPAddress( AsIPv4Int ()).ToString ());\r
97 \r
98                                 return s.ToString ();\r
99                         }\r
100                         \r
101                         int bestChStart = -1; // Best chain start\r
102                         int bestChLen = 0; // Best chain length\r
103                         int currChLen = 0; // Current chain length\r
104 \r
105                         // Looks for the longest zero chain\r
106                         for (int i=0; i<8; i++)\r
107                         {\r
108                                 if (address[i] != 0)\r
109                                 {\r
110                                         if ((currChLen > bestChLen) \r
111                                                 && (currChLen > 1))\r
112                                         {\r
113                                                 bestChLen = currChLen;\r
114                                                 bestChStart = i - currChLen;\r
115                                         }\r
116                                         currChLen = 0;\r
117                                 }\r
118                                 else\r
119                                         currChLen++;\r
120                         }\r
121                         if ((currChLen > bestChLen) \r
122                                 && (currChLen > 1))\r
123                         {\r
124                                 bestChLen = currChLen;\r
125                                 bestChStart = 8 - currChLen;\r
126                         }\r
127 \r
128                         // makes the string\r
129                         if (bestChStart == 0)\r
130                                 s.Append(":");\r
131                         for (int i=0; i<8; i++)\r
132                         {\r
133                                 if (i == bestChStart)\r
134                                 {\r
135                                         s.Append (":");\r
136                                         i += (bestChLen - 1);\r
137                                         continue;\r
138                                 }\r
139                                 s.AppendFormat("{0:x}", address [i]);\r
140                                 if (i < 7) s.Append (':');\r
141                         }\r
142                         \r
143                         if (scopeId != 0)\r
144                                 s.Append ('%').Append (scopeId);\r
145                         return s.ToString ();\r
146                 }\r
147         }\r
148 }\r