comparison dwtx/dwtxhelper/mangoicu/UDomainName.d @ 89:040da1cb0d76

Add a local copy of the mango ICU binding to work out the utf8 usability. Will hopefully go back into mango.
author Frank Benoit <benoit@tionex.de>
date Sun, 22 Jun 2008 22:57:31 +0200
parents
children 11e8159caf7a
comparison
equal deleted inserted replaced
88:cd18fa3b71f1 89:040da1cb0d76
1 /*******************************************************************************
2
3 @file UDomainName.d
4
5 Copyright (c) 2004 Kris Bell
6
7 This software is provided 'as-is', without any express or implied
8 warranty. In no event will the authors be held liable for damages
9 of any kind arising from the use of this software.
10
11 Permission is hereby granted to anyone to use this software for any
12 purpose, including commercial applications, and to alter it and/or
13 redistribute it freely, subject to the following restrictions:
14
15 1. The origin of this software must not be misrepresented; you must
16 not claim that you wrote the original software. If you use this
17 software in a product, an acknowledgment within documentation of
18 said product would be appreciated but is not required.
19
20 2. Altered source versions must be plainly marked as such, and must
21 not be misrepresented as being the original software.
22
23 3. This notice may not be removed or altered from any distribution
24 of the source.
25
26 4. Derivative works are permitted, but they must carry this notice
27 in full and credit the original source.
28
29
30 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31
32
33 @version Initial version, November 2004
34 @author Kris
35
36 Note that this package and documentation is built around the ICU
37 project (http://oss.software.ibm.com/icu/). Below is the license
38 statement as specified by that software:
39
40
41 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42
43
44 ICU License - ICU 1.8.1 and later
45
46 COPYRIGHT AND PERMISSION NOTICE
47
48 Copyright (c) 1995-2003 International Business Machines Corporation and
49 others.
50
51 All rights reserved.
52
53 Permission is hereby granted, free of charge, to any person obtaining a
54 copy of this software and associated documentation files (the
55 "Software"), to deal in the Software without restriction, including
56 without limitation the rights to use, copy, modify, merge, publish,
57 distribute, and/or sell copies of the Software, and to permit persons
58 to whom the Software is furnished to do so, provided that the above
59 copyright notice(s) and this permission notice appear in all copies of
60 the Software and that both the above copyright notice(s) and this
61 permission notice appear in supporting documentation.
62
63 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
64 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
65 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
66 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
68 INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
69 FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
70 NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
71 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
72
73 Except as contained in this notice, the name of a copyright holder
74 shall not be used in advertising or otherwise to promote the sale, use
75 or other dealings in this Software without prior written authorization
76 of the copyright holder.
77
78 ----------------------------------------------------------------------
79
80 All trademarks and registered trademarks mentioned herein are the
81 property of their respective owners.
82
83 *******************************************************************************/
84
85 module dwtx.dwthelper.mangoicu.UDomainName;
86
87 private import dwtx.dwthelper.mangoicu.ICU,
88 dwtx.dwthelper.mangoicu.UString;
89
90 /*******************************************************************************
91
92 UIDNA API implements the IDNA protocol as defined in the
93 IDNA RFC (http://www.ietf.org/rfc/rfc3490.txt).
94
95 The RFC defines 2 operations: toAscii and toUnicode. Domain
96 labels containing non-ASCII code points are required to be
97 processed by toAscii operation before passing it to resolver
98 libraries. Domain names that are obtained from resolver
99 libraries are required to be processed by toUnicode operation
100 before displaying the domain name to the user. IDNA requires
101 that implementations process input strings with Nameprep
102 (http://www.ietf.org/rfc/rfc3491.txt), which is a profile of
103 Stringprep (http://www.ietf.org/rfc/rfc3454.txt), and then with
104 Punycode (http://www.ietf.org/rfc/rfc3492.txt). Implementations
105 of IDNA MUST fully implement Nameprep and Punycode; neither
106 Nameprep nor Punycode are optional.
107
108 The input and output of toAscii() and ToUnicode() operations are
109 Unicode and are designed to be chainable, i.e., applying toAscii()
110 or toUnicode() operations multiple times to an input string will
111 yield the same result as applying the operation once.
112
113 See <A HREF="http://oss.software.ibm.com/icu/apiref/uidna_8h.html">
114 this page</A> for full details.
115
116 *******************************************************************************/
117
118 class UDomainName : ICU
119 {
120 private UText text;
121 private Handle handle;
122
123 enum Options
124 {
125 Strict,
126 Lenient,
127 Std3
128 }
129
130
131 /***********************************************************************
132
133
134 ***********************************************************************/
135
136 this (UText text)
137 {
138 this.text = text;
139 }
140
141 /***********************************************************************
142
143 This function implements the ToASCII operation as
144 defined in the IDNA RFC.
145
146 This operation is done on single labels before sending
147 it to something that expects ASCII names. A label is an
148 individual part of a domain name. Labels are usually
149 separated by dots; e.g." "www.example.com" is composed
150 of 3 labels "www","example", and "com".
151
152 ***********************************************************************/
153
154 void toAscii (UString dst, Options o = Options.Strict)
155 {
156 uint fmt (wchar* p, uint len, inout Error e)
157 {
158 return uidna_toASCII (text.get.ptr, text.len, p, len, o, null, e);
159 }
160
161 dst.format (&fmt, "failed to convert IDN to ASCII");
162 }
163
164 /***********************************************************************
165
166 This function implements the ToUnicode operation as
167 defined in the IDNA RFC.
168
169 This operation is done on single labels before sending
170 it to something that expects Unicode names. A label is
171 an individual part of a domain name. Labels are usually
172 separated by dots; for e.g." "www.example.com" is composed
173 of 3 labels "www","example", and "com".
174
175 ***********************************************************************/
176
177 void toUnicode (UString dst, Options o = Options.Strict)
178 {
179 uint fmt (wchar* p, uint len, inout Error e)
180 {
181 return uidna_toUnicode (text.get.ptr, text.len, p, len, o, null, e);
182 }
183
184 dst.format (&fmt, "failed to convert IDN to Unicode");
185 }
186
187 /***********************************************************************
188
189 Convenience function that implements the IDNToASCII
190 operation as defined in the IDNA RFC.
191
192 This operation is done on complete domain names, e.g:
193 "www.example.com". It is important to note that this
194 operation can fail. If it fails, then the input domain
195 name cannot be used as an Internationalized Domain Name
196 and the application should have methods defined to deal
197 with the failure.
198
199 Note: IDNA RFC specifies that a conformant application
200 should divide a domain name into separate labels, decide
201 whether to apply allowUnassigned and useSTD3ASCIIRules
202 on each, and then convert. This function does not offer
203 that level of granularity. The options once set will apply
204 to all labels in the domain name
205
206 ***********************************************************************/
207
208 void IdnToAscii (UString dst, Options o = Options.Strict)
209 {
210 uint fmt (wchar* p, uint len, inout Error e)
211 {
212 return uidna_IDNToASCII (text.get.ptr, text.len, p, len, o, null, e);
213 }
214
215 dst.format (&fmt, "failed to convert IDN to ASCII");
216 }
217
218 /***********************************************************************
219
220 Convenience function that implements the IDNToUnicode
221 operation as defined in the IDNA RFC.
222
223 This operation is done on complete domain names, e.g:
224 "www.example.com".
225
226 Note: IDNA RFC specifies that a conformant application
227 should divide a domain name into separate labels, decide
228 whether to apply allowUnassigned and useSTD3ASCIIRules
229 on each, and then convert. This function does not offer
230 that level of granularity. The options once set will apply
231 to all labels in the domain name
232
233 ***********************************************************************/
234
235 void IdnToUnicode (UString dst, Options o = Options.Strict)
236 {
237 uint fmt (wchar* p, uint len, inout Error e)
238 {
239 return uidna_IDNToUnicode (text.get.ptr, text.len, p, len, o, null, e);
240 }
241
242 dst.format (&fmt, "failed to convert IDN to Unicode");
243 }
244
245 /***********************************************************************
246
247 Compare two IDN strings for equivalence.
248
249 This function splits the domain names into labels and
250 compares them. According to IDN RFC, whenever two labels
251 are compared, they are considered equal if and only if
252 their ASCII forms (obtained by applying toASCII) match
253 using an case-insensitive ASCII comparison. Two domain
254 names are considered a match if and only if all labels
255 match regardless of whether label separators match
256
257 ***********************************************************************/
258
259 int compare (UString other, Options o = Options.Strict)
260 {
261 Error e;
262 int i = uidna_compare (text.get.ptr, text.len, other.get.ptr, other.len, o, e);
263 testError (e, "failed to compare IDN strings");
264 return i;
265 }
266
267
268 /***********************************************************************
269
270 Bind the ICU functions from a shared library. This is
271 complicated by the issues regarding D and DLLs on the
272 Windows platform
273
274 ***********************************************************************/
275
276 private static void* library;
277
278 /***********************************************************************
279
280 ***********************************************************************/
281
282 private static extern (C)
283 {
284 uint function (wchar*, uint, wchar*, uint, uint, void*, inout Error) uidna_toASCII;
285 uint function (wchar*, uint, wchar*, uint, uint, void*, inout Error) uidna_toUnicode;
286 uint function (wchar*, uint, wchar*, uint, uint, void*, inout Error) uidna_IDNToASCII;
287 uint function (wchar*, uint, wchar*, uint, uint, void*, inout Error) uidna_IDNToUnicode;
288 int function (wchar*, uint, wchar*, uint, uint, inout Error) uidna_compare;
289 }
290
291 /***********************************************************************
292
293 ***********************************************************************/
294
295 static FunctionLoader.Bind[] targets =
296 [
297 {cast(void**) &uidna_toASCII, "uidna_toASCII"},
298 {cast(void**) &uidna_toUnicode, "uidna_toUnicode"},
299 {cast(void**) &uidna_IDNToASCII, "uidna_IDNToASCII"},
300 {cast(void**) &uidna_IDNToUnicode, "uidna_IDNToUnicode"},
301 {cast(void**) &uidna_compare, "uidna_compare"},
302 ];
303
304 /***********************************************************************
305
306 ***********************************************************************/
307
308 static this ()
309 {
310 library = FunctionLoader.bind (icuuc, targets);
311 }
312
313 /***********************************************************************
314
315 ***********************************************************************/
316
317 static ~this ()
318 {
319 FunctionLoader.unbind (library);
320 }
321 }
322