1 /* $NetBSD: mapselector.c,v 1.4 2014/12/10 04:37:55 christos Exp $ */
4 static char *rcsid
= "Id: mapselector.c,v 1.1 2003/06/04 00:25:56 marka Exp ";
8 * Copyright (c) 2001,2002 Japan Network Information Center.
11 * By using this file, you agree to the terms and conditions set forth bellow.
13 * LICENSE TERMS AND CONDITIONS
15 * The following License Terms and Conditions apply, unless a different
16 * license is obtained from Japan Network Information Center ("JPNIC"),
17 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
18 * Chiyoda-ku, Tokyo 101-0047, Japan.
20 * 1. Use, Modification and Redistribution (including distribution of any
21 * modified or derived work) in source and/or binary forms is permitted
22 * under this License Terms and Conditions.
24 * 2. Redistribution of source code must retain the copyright notices as they
25 * appear in each source code file, this License Terms and Conditions.
27 * 3. Redistribution in binary form must reproduce the Copyright Notice,
28 * this License Terms and Conditions, in the documentation and/or other
29 * materials provided with the distribution. For the purposes of binary
30 * distribution the "Copyright Notice" refers to the following language:
31 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
33 * 4. The name of JPNIC may not be used to endorse or promote products
34 * derived from this Software without specific prior written approval of
37 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
38 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
40 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
45 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
46 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
56 #include <idn/assert.h>
57 #include <idn/logmacro.h>
58 #include <idn/result.h>
59 #include <idn/mapselector.h>
60 #include <idn/strhash.h>
61 #include <idn/debug.h>
65 struct idn_mapselector
{
66 idn__strhash_t maphash
;
71 * Maximum length of a top level domain name. (e.g. `com', `jp', ...)
73 #define MAPSELECTOR_MAX_TLD_LENGTH 63
75 static void string_ascii_tolower(char *string
);
79 idn_mapselector_getnotld(void) {
80 static const unsigned long notld
[] = {0x002d, 0x0000}; /* "-" */
85 idn_mapselector_getdefaulttld(void) {
86 const static unsigned long defaulttld
[] = {0x002e, 0x0000}; /* "." */
91 idn_mapselector_initialize(void) {
94 TRACE(("idn_mapselector_initialize()\n"));
96 r
= idn_mapper_initialize();
98 TRACE(("idn_mapselector_initialize(): %s\n", idn_result_tostring(r
)));
103 idn_mapselector_create(idn_mapselector_t
*ctxp
) {
104 idn_mapselector_t ctx
= NULL
;
107 assert(ctxp
!= NULL
);
108 TRACE(("idn_mapselector_create()\n"));
110 ctx
= (idn_mapselector_t
)malloc(sizeof(struct idn_mapselector
));
117 ctx
->reference_count
= 1;
119 r
= idn__strhash_create(&(ctx
->maphash
));
120 if (r
!= idn_success
)
127 if (r
!= idn_success
) {
132 TRACE(("idn_mapselector_create(): %s\n", idn_result_tostring(r
)));
137 idn_mapselector_destroy(idn_mapselector_t ctx
) {
140 TRACE(("idn_mapselector_destroy()\n"));
142 ctx
->reference_count
--;
143 if (ctx
->reference_count
<= 0) {
144 TRACE(("idn_mapselector_destroy(): "
145 "the object is destroyed\n"));
146 idn__strhash_destroy(ctx
->maphash
,
147 (idn__strhash_freeproc_t
)&idn_mapper_destroy
);
150 TRACE(("idn_mapselector_destroy(): "
151 "update reference count (%d->%d)\n",
152 ctx
->reference_count
+ 1, ctx
->reference_count
));
157 idn_mapselector_incrref(idn_mapselector_t ctx
) {
160 TRACE(("idn_mapselector_incrref()\n"));
161 TRACE(("idn_mapselector_incrref: update reference count (%d->%d)\n",
162 ctx
->reference_count
, ctx
->reference_count
+ 1));
164 ctx
->reference_count
++;
168 idn_mapselector_add(idn_mapselector_t ctx
, const char *tld
, const char *name
) {
171 char hash_key
[MAPSELECTOR_MAX_TLD_LENGTH
+ 1];
173 assert(ctx
!= NULL
&& tld
!= NULL
);
175 TRACE(("idn_mapselector_add(tld=%s, name=%s)\n", tld
, name
));
177 if (!(tld
[0] == '.' && tld
[1] == '\0')) {
180 if (strchr(tld
, '.') != NULL
) {
181 ERROR(("idn_mapselector_add: "
182 "invalid TLD \"%-.100s\"\n", tld
));
183 r
= idn_invalid_name
;
187 if (strlen(tld
) > MAPSELECTOR_MAX_TLD_LENGTH
) {
188 ERROR(("idn_mapselector_add: "
189 "too long TLD \"%-.100s\"\n", tld
));
190 r
= idn_invalid_name
;
193 strcpy(hash_key
, tld
);
194 string_ascii_tolower(hash_key
);
196 if (idn__strhash_get(ctx
->maphash
, hash_key
, (void **)&mapper
)
198 r
= idn_mapper_create(&mapper
);
199 if (r
!= idn_success
)
202 r
= idn__strhash_put(ctx
->maphash
, hash_key
, mapper
);
203 if (r
!= idn_success
)
207 r
= idn_mapper_add(mapper
, name
);
209 TRACE(("idn_mapselector_add(): %s\n", idn_result_tostring(r
)));
214 idn_mapselector_addall(idn_mapselector_t ctx
, const char *tld
,
215 const char **scheme_names
, int nschemes
) {
219 assert(ctx
!= NULL
&& tld
!= NULL
&& scheme_names
!= NULL
);
221 TRACE(("idn_mapselector_addall(tld=%s, nschemes=%d)\n",
224 for (i
= 0; i
< nschemes
; i
++) {
225 r
= idn_mapselector_add(ctx
, tld
, (const char *)*scheme_names
);
226 if (r
!= idn_success
)
233 TRACE(("idn_mapselector_addall(): %s\n", idn_result_tostring(r
)));
238 idn_mapselector_mapper(idn_mapselector_t ctx
, const char *tld
) {
241 char hash_key
[MAPSELECTOR_MAX_TLD_LENGTH
+ 1];
243 assert(ctx
!= NULL
&& tld
!= NULL
);
245 TRACE(("idn_mapselector_mapper(tld=%s)\n", tld
));
247 if (!(tld
[0] == '.' && tld
[1] == '\0')) {
250 if (strchr(tld
, '.') != NULL
)
253 if (strlen(tld
) > MAPSELECTOR_MAX_TLD_LENGTH
)
255 strcpy(hash_key
, tld
);
256 string_ascii_tolower(hash_key
);
259 r
= idn__strhash_get(ctx
->maphash
, hash_key
, (void **)&mapper
);
260 if (r
!= idn_success
)
263 idn_mapper_incrref(mapper
);
269 idn_mapselector_map(idn_mapselector_t ctx
, const unsigned long *from
,
270 const char *tld
, unsigned long *to
, size_t tolen
) {
272 idn_mapper_t mapper
= NULL
;
273 char hash_key
[MAPSELECTOR_MAX_TLD_LENGTH
+ 1];
276 assert(ctx
!= NULL
&& from
!= NULL
&& to
!= NULL
);
278 TRACE(("idn_mapselector_map(from=\"%s\", tld=\"%s\", tolen=%d)\n",
279 idn__debug_ucs4xstring(from
, 50), idn__debug_xstring(tld
, 50),
282 if (!(tld
[0] == '.' && tld
[1] == '\0')) {
285 if (strchr(tld
, '.') != NULL
) {
286 r
= idn_invalid_name
;
290 if (strlen(tld
) > MAPSELECTOR_MAX_TLD_LENGTH
) {
291 r
= idn_invalid_name
;
294 strcpy(hash_key
, tld
);
295 string_ascii_tolower(hash_key
);
297 fromlen
= idn_ucs4_strlen(from
);
300 * Get mapper for the TLD.
302 if (idn__strhash_get(ctx
->maphash
, hash_key
, (void **)&mapper
)
304 strcpy(hash_key
, IDN_MAPSELECTOR_DEFAULTTLD
);
305 idn__strhash_get(ctx
->maphash
, hash_key
, (void **)&mapper
);
310 * If default mapper has not been registered, copy the string.
312 if (mapper
== NULL
) {
313 TRACE(("idn_mapselector_map(): no mapper\n"));
314 if (fromlen
+ 1 > tolen
) {
315 r
= idn_buffer_overflow
;
318 memcpy(to
, from
, (fromlen
+ 1) * sizeof(*from
));
320 TRACE(("idn_mapselector_map(): tld=%s\n", tld
));
321 r
= idn_mapper_map(mapper
, from
, to
, tolen
);
322 if (r
!= idn_success
)
328 if (r
== idn_success
) {
329 TRACE(("idn_mapselector_map(): succcess (to=\"%s\")\n",
330 idn__debug_ucs4xstring(to
, 50)));
332 TRACE(("idn_mapselector_map(): %s\n", idn_result_tostring(r
)));
338 idn_mapselector_map2(idn_mapselector_t ctx
, const unsigned long *from
,
339 const unsigned long *tld
, unsigned long *to
,
341 char tld_utf8
[MAPSELECTOR_MAX_TLD_LENGTH
+ 1];
344 assert(ctx
!= NULL
&& from
!= NULL
&& to
!= NULL
);
346 TRACE(("idn_mapselector_map2(from=\"%s\", tld=\"%s\")\n",
347 idn__debug_ucs4xstring(from
, 50),
348 idn__debug_ucs4xstring(tld
, 50)));
350 r
= idn_ucs4_ucs4toutf8(tld
, tld_utf8
, sizeof(tld_utf8
));
351 if (r
== idn_buffer_overflow
) {
352 r
= idn_invalid_name
;
354 } else if (r
!= idn_success
) {
358 r
= idn_mapselector_map(ctx
, from
, tld_utf8
, to
, tolen
);
360 if (r
== idn_success
) {
361 TRACE(("idn_mapselector_map2(): success (to=\"%s\")\n",
362 idn__debug_ucs4xstring(to
, 50)));
364 TRACE(("idn_mapselector_map2(): %s\n", idn_result_tostring(r
)));
370 string_ascii_tolower(char *string
) {
373 for (p
= (unsigned char *) string
; *p
!= '\0'; p
++) {
374 if ('A' <= *p
&& *p
<= 'Z')