1 /* $NetBSD: delimitermap.c,v 1.4 2014/12/10 04:37:55 christos Exp $ */
4 static char *rcsid
= "Id: delimitermap.c,v 1.1 2003/06/04 00:25:52 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/result.h>
57 #include <idn/assert.h>
58 #include <idn/logmacro.h>
59 #include <idn/delimitermap.h>
61 #include <idn/debug.h>
67 struct idn_delimitermap
{
70 unsigned long *delimiters
;
74 #define DELIMITERMAP_INITIAL_DELIMITER_SIZE 4
75 #define UNICODE_MAX 0x10ffff
76 #define IS_SURROGATE_HIGH(v) (0xd800 <= (v) && (v) <= 0xdbff)
77 #define IS_SURROGATE_LOW(v) (0xdc00 <= (v) && (v) <= 0xdfff)
80 idn_delimitermap_create(idn_delimitermap_t
*ctxp
) {
81 idn_delimitermap_t ctx
= NULL
;
85 TRACE(("idn_delimitermap_create()\n"));
87 ctx
= (idn_delimitermap_t
) malloc(sizeof(struct idn_delimitermap
));
89 WARNING(("idn_mapper_create: malloc failed\n"));
94 ctx
->delimiters
= (unsigned long *) malloc(sizeof(unsigned long)
95 * DELIMITERMAP_INITIAL_DELIMITER_SIZE
);
96 if (ctx
->delimiters
== NULL
) {
100 ctx
->ndelimiters
= 0;
101 ctx
->delimiter_size
= DELIMITERMAP_INITIAL_DELIMITER_SIZE
;
102 ctx
->reference_count
= 1;
107 if (r
!= idn_success
)
109 TRACE(("idn_delimitermap_create(): %s\n", idn_result_tostring(r
)));
114 idn_delimitermap_destroy(idn_delimitermap_t ctx
) {
117 TRACE(("idn_delimitermap_destroy()\n"));
119 ctx
->reference_count
--;
120 if (ctx
->reference_count
<= 0) {
121 TRACE(("idn_mapper_destroy(): the object is destroyed\n"));
122 free(ctx
->delimiters
);
125 TRACE(("idn_delimitermap_destroy(): "
126 "update reference count (%d->%d)\n",
127 ctx
->reference_count
+ 1, ctx
->reference_count
));
132 idn_delimitermap_incrref(idn_delimitermap_t ctx
) {
135 TRACE(("idn_delimitermap_incrref()\n"));
136 TRACE(("idn_delimitermap_incrref: update reference count (%d->%d)\n",
137 ctx
->reference_count
, ctx
->reference_count
+ 1));
139 ctx
->reference_count
++;
143 idn_delimitermap_add(idn_delimitermap_t ctx
, unsigned long delimiter
) {
146 assert(ctx
!= NULL
&& ctx
->ndelimiters
<= ctx
->delimiter_size
);
147 TRACE(("idn_delimitermap_add(delimiter=\\x%04lx)\n", delimiter
));
149 if (delimiter
== 0 || delimiter
> UNICODE_MAX
||
150 IS_SURROGATE_HIGH(delimiter
) || IS_SURROGATE_LOW(delimiter
)) {
151 r
= idn_invalid_codepoint
;
155 if (ctx
->ndelimiters
== ctx
->delimiter_size
) {
156 unsigned long *new_delimiters
;
158 new_delimiters
= (unsigned long *) realloc(ctx
->delimiters
,
159 sizeof(unsigned long) * ctx
->delimiter_size
* 2);
160 if (new_delimiters
== NULL
) {
164 ctx
->delimiters
= new_delimiters
;
165 ctx
->delimiter_size
*= 2;
168 ctx
->delimiters
[ctx
->ndelimiters
] = delimiter
;
173 TRACE(("idn_delimitermap_add(): %s\n", idn_result_tostring(r
)));
178 idn_delimitermap_addall(idn_delimitermap_t ctx
, unsigned long *delimiters
,
183 assert(ctx
!= NULL
&& delimiters
!= NULL
);
185 TRACE(("idn_delimitermap_addall(ndelimiters=%d)\n", ndelimiters
));
187 for (i
= 0; i
< ndelimiters
; i
++) {
188 r
= idn_delimitermap_add(ctx
, *delimiters
);
189 if (r
!= idn_success
)
196 TRACE(("idn_delimitermap_addall(): %s\n", idn_result_tostring(r
)));
201 idn_delimitermap_map(idn_delimitermap_t ctx
, const unsigned long *from
,
202 unsigned long *to
, size_t tolen
) {
204 /* default delimiters (label separators) from IDNA specification */
205 static const unsigned long default_delimiters
[] =
206 { 0x002e, /* full stop */
207 0x3002, /* ideographic full stop */
208 0xff0e, /* fullwidth full stop */
209 0xff61, /* halfwidth ideographic full stop */
212 unsigned long *to_org
= to
;
217 assert(ctx
!= NULL
&& from
!= NULL
&& to
!= NULL
);
219 TRACE(("idn_delimitermap_map(from=\"%s\", tolen=%d)\n",
220 idn__debug_ucs4xstring(from
, 50), (int)tolen
));
225 while (*from
!= '\0') {
228 r
= idn_buffer_overflow
;
231 for (j
= 0; default_delimiters
[j
] != 0x0000; j
++) {
232 if (default_delimiters
[j
] == *from
) {
238 for (i
= 0; i
< ctx
->ndelimiters
; i
++) {
239 if (ctx
->delimiters
[i
] == *from
) {
255 r
= idn_buffer_overflow
;
262 if (r
== idn_success
) {
263 TRACE(("idn_delimitermap_map(): success (to=\"%s\")\n",
264 idn__debug_ucs4xstring(to_org
, 50)));
266 TRACE(("idn_delimitermap_map(): %s\n",
267 idn_result_tostring(r
)));