4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
30 * UTF-8 text preparation functions (PSARC/2007/149, PSARC/2007/458).
32 * Man pages: u8_textprep_open(9F), u8_textprep_buf(9F), u8_textprep_close(9F),
33 * u8_textprep_str(9F), u8_strcmp(9F), and u8_validate(9F). See also
34 * the section 3C man pages.
35 * Interface stability: Committed.
38 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/sysmacros.h>
42 #include <sys/systm.h>
43 #include <sys/debug.h>
46 #include <sys/sunddi.h>
48 #include <sys/u8_textprep.h>
51 #include <sys/byteorder.h>
52 #include <sys/errno.h>
53 #include <sys/u8_textprep_data.h>
56 /* The maximum possible number of bytes in a UTF-8 character. */
57 #define U8_MB_CUR_MAX (4)
60 * The maximum number of bytes needed for a UTF-8 character to cover
61 * U+0000 - U+FFFF, i.e., the coding space of now deprecated UCS-2.
63 #define U8_MAX_BYTES_UCS2 (3)
65 /* The maximum possible number of bytes in a Stream-Safe Text. */
66 #define U8_STREAM_SAFE_TEXT_MAX (128)
69 * The maximum number of characters in a combining/conjoining sequence and
70 * the actual upperbound limit of a combining/conjoining sequence.
72 #define U8_MAX_CHARS_A_SEQ (32)
73 #define U8_UPPER_LIMIT_IN_A_SEQ (31)
75 /* The combining class value for Starter. */
76 #define U8_COMBINING_CLASS_STARTER (0)
79 * Some Hangul related macros at below.
81 * The first and the last of Hangul syllables, Hangul Jamo Leading consonants,
82 * Vowels, and optional Trailing consonants in Unicode scalar values.
84 * Please be noted that the U8_HANGUL_JAMO_T_FIRST is 0x11A7 at below not
85 * the actual U+11A8. This is due to that the trailing consonant is optional
86 * and thus we are doing a pre-calculation of subtracting one.
88 * Each of 19 modern leading consonants has total 588 possible syllables since
89 * Hangul has 21 modern vowels and 27 modern trailing consonants plus 1 for
90 * no trailing consonant case, i.e., 21 x 28 = 588.
92 * We also have bunch of Hangul related macros at below. Please bear in mind
93 * that the U8_HANGUL_JAMO_1ST_BYTE can be used to check whether it is
94 * a Hangul Jamo or not but the value does not guarantee that it is a Hangul
95 * Jamo; it just guarantee that it will be most likely.
97 #define U8_HANGUL_SYL_FIRST (0xAC00U)
98 #define U8_HANGUL_SYL_LAST (0xD7A3U)
100 #define U8_HANGUL_JAMO_L_FIRST (0x1100U)
101 #define U8_HANGUL_JAMO_L_LAST (0x1112U)
102 #define U8_HANGUL_JAMO_V_FIRST (0x1161U)
103 #define U8_HANGUL_JAMO_V_LAST (0x1175U)
104 #define U8_HANGUL_JAMO_T_FIRST (0x11A7U)
105 #define U8_HANGUL_JAMO_T_LAST (0x11C2U)
107 #define U8_HANGUL_V_COUNT (21)
108 #define U8_HANGUL_VT_COUNT (588)
109 #define U8_HANGUL_T_COUNT (28)
111 #define U8_HANGUL_JAMO_1ST_BYTE (0xE1U)
113 #define U8_SAVE_HANGUL_AS_UTF8(s, i, j, k, b) \
114 (s)[(i)] = (uchar_t)(0xE0U | ((uint32_t)(b) & 0xF000U) >> 12); \
115 (s)[(j)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x0FC0U) >> 6); \
116 (s)[(k)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x003FU));
118 #define U8_HANGUL_JAMO_L(u) \
119 ((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_L_LAST)
121 #define U8_HANGUL_JAMO_V(u) \
122 ((u) >= U8_HANGUL_JAMO_V_FIRST && (u) <= U8_HANGUL_JAMO_V_LAST)
124 #define U8_HANGUL_JAMO_T(u) \
125 ((u) > U8_HANGUL_JAMO_T_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
127 #define U8_HANGUL_JAMO(u) \
128 ((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
130 #define U8_HANGUL_SYLLABLE(u) \
131 ((u) >= U8_HANGUL_SYL_FIRST && (u) <= U8_HANGUL_SYL_LAST)
133 #define U8_HANGUL_COMPOSABLE_L_V(s, u) \
134 ((s) == U8_STATE_HANGUL_L && U8_HANGUL_JAMO_V((u)))
136 #define U8_HANGUL_COMPOSABLE_LV_T(s, u) \
137 ((s) == U8_STATE_HANGUL_LV && U8_HANGUL_JAMO_T((u)))
139 /* The types of decomposition mappings. */
140 #define U8_DECOMP_BOTH (0xF5U)
141 #define U8_DECOMP_CANONICAL (0xF6U)
143 /* The indicator for 16-bit table. */
144 #define U8_16BIT_TABLE_INDICATOR (0x8000U)
146 /* The following are some convenience macros. */
147 #define U8_PUT_3BYTES_INTO_UTF32(u, b1, b2, b3) \
148 (u) = ((uint32_t)(b1) & 0x0F) << 12 | ((uint32_t)(b2) & 0x3F) << 6 | \
149 (uint32_t)(b3) & 0x3F;
151 #define U8_SIMPLE_SWAP(a, b, t) \
156 #define U8_ASCII_TOUPPER(c) \
157 (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c))
159 #define U8_ASCII_TOLOWER(c) \
160 (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
162 #define U8_ISASCII(c) (((uchar_t)(c)) < 0x80U)
164 * The following macro assumes that the two characters that are to be
165 * swapped are adjacent to each other and 'a' comes before 'b'.
167 * If the assumptions are not met, then, the macro will fail.
169 #define U8_SWAP_COMB_MARKS(a, b) \
170 for (k = 0; k < disp[(a)]; k++) \
171 u8t[k] = u8s[start[(a)] + k]; \
172 for (k = 0; k < disp[(b)]; k++) \
173 u8s[start[(a)] + k] = u8s[start[(b)] + k]; \
174 start[(b)] = start[(a)] + disp[(b)]; \
175 for (k = 0; k < disp[(a)]; k++) \
176 u8s[start[(b)] + k] = u8t[k]; \
177 U8_SIMPLE_SWAP(comb_class[(a)], comb_class[(b)], tc); \
178 U8_SIMPLE_SWAP(disp[(a)], disp[(b)], tc);
180 /* The possible states during normalization. */
183 U8_STATE_HANGUL_L
= 1,
184 U8_STATE_HANGUL_LV
= 2,
185 U8_STATE_HANGUL_LVT
= 3,
186 U8_STATE_HANGUL_V
= 4,
187 U8_STATE_HANGUL_T
= 5,
188 U8_STATE_COMBINING_MARK
= 6
189 } u8_normalization_states_t
;
192 * The three vectors at below are used to check bytes of a given UTF-8
193 * character are valid and not containing any malformed byte values.
195 * We used to have a quite relaxed UTF-8 binary representation but then there
196 * was some security related issues and so the Unicode Consortium defined
197 * and announced the UTF-8 Corrigendum at Unicode 3.1 and then refined it
198 * one more time at the Unicode 3.2. The following three tables are based on
202 #define U8_ILLEGAL_NEXT_BYTE_COMMON(c) ((c) < 0x80 || (c) > 0xBF)
204 #define I_ U8_ILLEGAL_CHAR
205 #define O_ U8_OUT_OF_RANGE_CHAR
207 const int8_t u8_number_of_bytes
[0x100] = {
208 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
209 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
210 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
211 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
212 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
213 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
214 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
215 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
217 /* 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F */
218 I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
,
220 /* 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F */
221 I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
,
223 /* A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF */
224 I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
,
226 /* B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF */
227 I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
, I_
,
229 /* C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF */
230 I_
, I_
, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
232 /* D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF */
233 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
235 /* E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF */
236 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
238 /* F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF */
239 4, 4, 4, 4, 4, O_
, O_
, O_
, O_
, O_
, O_
, O_
, O_
, O_
, O_
, O_
,
245 const uint8_t u8_valid_min_2nd_byte
[0x100] = {
246 0, 0, 0, 0, 0, 0, 0, 0,
247 0, 0, 0, 0, 0, 0, 0, 0,
248 0, 0, 0, 0, 0, 0, 0, 0,
249 0, 0, 0, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 0,
251 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0,
255 0, 0, 0, 0, 0, 0, 0, 0,
256 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0,
259 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 0, 0, 0, 0,
262 0, 0, 0, 0, 0, 0, 0, 0,
263 0, 0, 0, 0, 0, 0, 0, 0,
264 0, 0, 0, 0, 0, 0, 0, 0,
265 0, 0, 0, 0, 0, 0, 0, 0,
266 0, 0, 0, 0, 0, 0, 0, 0,
267 0, 0, 0, 0, 0, 0, 0, 0,
268 0, 0, 0, 0, 0, 0, 0, 0,
269 0, 0, 0, 0, 0, 0, 0, 0,
270 /* C0 C1 C2 C3 C4 C5 C6 C7 */
271 0, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
272 /* C8 C9 CA CB CC CD CE CF */
273 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
274 /* D0 D1 D2 D3 D4 D5 D6 D7 */
275 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
276 /* D8 D9 DA DB DC DD DE DF */
277 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
278 /* E0 E1 E2 E3 E4 E5 E6 E7 */
279 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
280 /* E8 E9 EA EB EC ED EE EF */
281 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
282 /* F0 F1 F2 F3 F4 F5 F6 F7 */
283 0x90, 0x80, 0x80, 0x80, 0x80, 0, 0, 0,
284 0, 0, 0, 0, 0, 0, 0, 0,
287 const uint8_t u8_valid_max_2nd_byte
[0x100] = {
288 0, 0, 0, 0, 0, 0, 0, 0,
289 0, 0, 0, 0, 0, 0, 0, 0,
290 0, 0, 0, 0, 0, 0, 0, 0,
291 0, 0, 0, 0, 0, 0, 0, 0,
292 0, 0, 0, 0, 0, 0, 0, 0,
293 0, 0, 0, 0, 0, 0, 0, 0,
294 0, 0, 0, 0, 0, 0, 0, 0,
295 0, 0, 0, 0, 0, 0, 0, 0,
296 0, 0, 0, 0, 0, 0, 0, 0,
297 0, 0, 0, 0, 0, 0, 0, 0,
298 0, 0, 0, 0, 0, 0, 0, 0,
299 0, 0, 0, 0, 0, 0, 0, 0,
300 0, 0, 0, 0, 0, 0, 0, 0,
301 0, 0, 0, 0, 0, 0, 0, 0,
302 0, 0, 0, 0, 0, 0, 0, 0,
303 0, 0, 0, 0, 0, 0, 0, 0,
304 0, 0, 0, 0, 0, 0, 0, 0,
305 0, 0, 0, 0, 0, 0, 0, 0,
306 0, 0, 0, 0, 0, 0, 0, 0,
307 0, 0, 0, 0, 0, 0, 0, 0,
308 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0,
312 /* C0 C1 C2 C3 C4 C5 C6 C7 */
313 0, 0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
314 /* C8 C9 CA CB CC CD CE CF */
315 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
316 /* D0 D1 D2 D3 D4 D5 D6 D7 */
317 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
318 /* D8 D9 DA DB DC DD DE DF */
319 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
320 /* E0 E1 E2 E3 E4 E5 E6 E7 */
321 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
322 /* E8 E9 EA EB EC ED EE EF */
323 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x9f, 0xbf, 0xbf,
324 /* F0 F1 F2 F3 F4 F5 F6 F7 */
325 0xbf, 0xbf, 0xbf, 0xbf, 0x8f, 0, 0, 0,
326 0, 0, 0, 0, 0, 0, 0, 0,
331 * The u8_validate() validates on the given UTF-8 character string and
332 * calculate the byte length. It is quite similar to mblen(3C) except that
333 * this will validate against the list of characters if required and
334 * specific to UTF-8 and Unicode.
337 u8_validate(char *u8str
, size_t n
, char **list
, int flag
, int *errnum
)
349 boolean_t no_need_to_validate_entire
;
350 boolean_t check_additional
;
351 boolean_t validate_ucs2_range_only
;
356 ib
= (uchar_t
*)u8str
;
361 no_need_to_validate_entire
= ! (flag
& U8_VALIDATE_ENTIRE
);
362 check_additional
= flag
& U8_VALIDATE_CHECK_ADDITIONAL
;
363 validate_ucs2_range_only
= flag
& U8_VALIDATE_UCS2_RANGE
;
365 while (ib
< ibtail
) {
367 * The first byte of a UTF-8 character tells how many
368 * bytes will follow for the character. If the first byte
369 * is an illegal byte value or out of range value, we just
370 * return -1 with an appropriate error number.
372 sz
= u8_number_of_bytes
[*ib
];
373 if (sz
== U8_ILLEGAL_CHAR
) {
378 if (sz
== U8_OUT_OF_RANGE_CHAR
||
379 (validate_ucs2_range_only
&& sz
> U8_MAX_BYTES_UCS2
)) {
385 * If we don't have enough bytes to check on, that's also
386 * an error. As you can see, we give illegal byte sequence
387 * checking higher priority then EINVAL cases.
389 if ((ibtail
- ib
) < sz
) {
399 * Check on the multi-byte UTF-8 character. For more
400 * details on this, see comment added for the used
401 * data structures at the beginning of the file.
406 for (i
= 1; i
< sz
; i
++) {
408 if (*ib
< u8_valid_min_2nd_byte
[f
] ||
409 *ib
> u8_valid_max_2nd_byte
[f
]) {
414 } else if (U8_ILLEGAL_NEXT_BYTE_COMMON(*ib
)) {
423 if (check_additional
) {
424 for (p
= (uchar_t
**)list
, i
= 0; p
[i
]; i
++) {
428 if (*s1
!= *s2
|| *s2
== '\0')
434 if (s1
>= ib
&& *s2
== '\0') {
441 if (no_need_to_validate_entire
)
449 * The do_case_conv() looks at the mapping tables and returns found
450 * bytes if any. If not found, the input bytes are returned. The function
451 * always terminate the return bytes with a null character assuming that
452 * there are plenty of room to do so.
454 * The case conversions are simple case conversions mapping a character to
455 * another character as specified in the Unicode data. The byte size of
456 * the mapped character could be different from that of the input character.
458 * The return value is the byte length of the returned character excluding
459 * the terminating null byte.
462 do_case_conv(int uv
, uchar_t
*u8s
, uchar_t
*s
, int sz
, boolean_t is_it_toupper
)
475 * At this point, the only possible values for sz are 2, 3, and 4.
476 * The u8s should point to a vector that is well beyond the size of
482 } else if (sz
== 3) {
486 } else if (sz
== 4) {
492 /* This is not possible but just in case as a fallback. */
494 *u8s
= U8_ASCII_TOUPPER(*s
);
496 *u8s
= U8_ASCII_TOLOWER(*s
);
504 * Let's find out if we have a corresponding character.
506 b1
= u8_common_b1_tbl
[uv
][b1
];
507 if (b1
== U8_TBL_ELEMENT_NOT_DEF
)
510 b2
= u8_case_common_b2_tbl
[uv
][b1
][b2
];
511 if (b2
== U8_TBL_ELEMENT_NOT_DEF
)
515 b3_tbl
= u8_toupper_b3_tbl
[uv
][b2
][b3
].tbl_id
;
516 if (b3_tbl
== U8_TBL_ELEMENT_NOT_DEF
)
519 start_id
= u8_toupper_b4_tbl
[uv
][b3_tbl
][b4
];
520 end_id
= u8_toupper_b4_tbl
[uv
][b3_tbl
][b4
+ 1];
522 /* Either there is no match or an error at the table. */
523 if (start_id
>= end_id
|| (end_id
- start_id
) > U8_MB_CUR_MAX
)
526 b3_base
= u8_toupper_b3_tbl
[uv
][b2
][b3
].base
;
528 for (i
= 0; start_id
< end_id
; start_id
++)
529 u8s
[i
++] = u8_toupper_final_tbl
[uv
][b3_base
+ start_id
];
531 b3_tbl
= u8_tolower_b3_tbl
[uv
][b2
][b3
].tbl_id
;
532 if (b3_tbl
== U8_TBL_ELEMENT_NOT_DEF
)
535 start_id
= u8_tolower_b4_tbl
[uv
][b3_tbl
][b4
];
536 end_id
= u8_tolower_b4_tbl
[uv
][b3_tbl
][b4
+ 1];
538 if (start_id
>= end_id
|| (end_id
- start_id
) > U8_MB_CUR_MAX
)
541 b3_base
= u8_tolower_b3_tbl
[uv
][b2
][b3
].base
;
543 for (i
= 0; start_id
< end_id
; start_id
++)
544 u8s
[i
++] = u8_tolower_final_tbl
[uv
][b3_base
+ start_id
];
548 * If i is still zero, that means there is no corresponding character.
559 * The do_case_compare() function compares the two input strings, s1 and s2,
560 * one character at a time doing case conversions if applicable and return
561 * the comparison result as like strcmp().
563 * Since, in empirical sense, most of text data are 7-bit ASCII characters,
564 * we treat the 7-bit ASCII characters as a special case trying to yield
565 * faster processing time.
568 do_case_compare(size_t uv
, uchar_t
*s1
, uchar_t
*s2
, size_t n1
,
569 size_t n2
, boolean_t is_it_toupper
, int *errnum
)
577 uchar_t u8s1
[U8_MB_CUR_MAX
+ 1];
578 uchar_t u8s2
[U8_MB_CUR_MAX
+ 1];
581 while (i1
< n1
&& i2
< n2
) {
583 * Find out what would be the byte length for this UTF-8
584 * character at string s1 and also find out if this is
585 * an illegal start byte or not and if so, issue a proper
586 * error number and yet treat this byte as a character.
588 sz1
= u8_number_of_bytes
[*s1
];
595 * For 7-bit ASCII characters mainly, we do a quick case
596 * conversion right at here.
598 * If we don't have enough bytes for this character, issue
599 * an EINVAL error and use what are available.
601 * If we have enough bytes, find out if there is
602 * a corresponding uppercase character and if so, copy over
603 * the bytes for a comparison later. If there is no
604 * corresponding uppercase character, then, use what we have
605 * for the comparison.
609 u8s1
[0] = U8_ASCII_TOUPPER(*s1
);
611 u8s1
[0] = U8_ASCII_TOLOWER(*s1
);
614 } else if ((i1
+ sz1
) > n1
) {
616 for (j
= 0; (i1
+ j
) < n1
; )
620 (void) do_case_conv(uv
, u8s1
, s1
, sz1
, is_it_toupper
);
624 /* Do the same for the string s2. */
625 sz2
= u8_number_of_bytes
[*s2
];
633 u8s2
[0] = U8_ASCII_TOUPPER(*s2
);
635 u8s2
[0] = U8_ASCII_TOLOWER(*s2
);
638 } else if ((i2
+ sz2
) > n2
) {
640 for (j
= 0; (i2
+ j
) < n2
; )
644 (void) do_case_conv(uv
, u8s2
, s2
, sz2
, is_it_toupper
);
648 /* Now compare the two characters. */
649 if (sz1
== 1 && sz2
== 1) {
655 f
= strcmp((const char *)u8s1
, (const char *)u8s2
);
661 * They were the same. Let's move on to the next
669 * We compared until the end of either or both strings.
671 * If we reached to or went over the ends for the both, that means
674 * If we reached only one of the two ends, that means the other string
675 * has something which then the fact can be used to determine
687 * The combining_class() function checks on the given bytes and find out
688 * the corresponding Unicode combining class value. The return value 0 means
689 * it is a Starter. Any illegal UTF-8 character will also be treated as
693 combining_class(size_t uv
, uchar_t
*s
, size_t sz
)
700 if (sz
== 1 || sz
> 4)
706 } else if (sz
== 3) {
710 } else if (sz
== 4) {
717 b1
= u8_common_b1_tbl
[uv
][b1
];
718 if (b1
== U8_TBL_ELEMENT_NOT_DEF
)
721 b2
= u8_combining_class_b2_tbl
[uv
][b1
][b2
];
722 if (b2
== U8_TBL_ELEMENT_NOT_DEF
)
725 b3
= u8_combining_class_b3_tbl
[uv
][b2
][b3
];
726 if (b3
== U8_TBL_ELEMENT_NOT_DEF
)
729 return (u8_combining_class_b4_tbl
[uv
][b3
][b4
]);
733 * The do_decomp() function finds out a matching decomposition if any
734 * and return. If there is no match, the input bytes are copied and returned.
735 * The function also checks if there is a Hangul, decomposes it if necessary
738 * To save time, a single byte 7-bit ASCII character should be handled by
741 * The function returns the number of bytes returned sans always terminating
742 * the null byte. It will also return a state that will tell if there was
743 * a Hangul character decomposed which then will be used by the caller.
746 do_decomp(size_t uv
, uchar_t
*u8s
, uchar_t
*s
, int sz
,
747 boolean_t canonical_decomposition
, u8_normalization_states_t
*state
)
764 } else if (sz
== 3) {
765 /* Convert it to a Unicode scalar value. */
766 U8_PUT_3BYTES_INTO_UTF32(u1
, s
[0], s
[1], s
[2]);
769 * If this is a Hangul syllable, we decompose it into
770 * a leading consonant, a vowel, and an optional trailing
771 * consonant and then return.
773 if (U8_HANGUL_SYLLABLE(u1
)) {
774 u1
-= U8_HANGUL_SYL_FIRST
;
776 b1
= U8_HANGUL_JAMO_L_FIRST
+ u1
/ U8_HANGUL_VT_COUNT
;
777 b2
= U8_HANGUL_JAMO_V_FIRST
+ (u1
% U8_HANGUL_VT_COUNT
)
779 b3
= u1
% U8_HANGUL_T_COUNT
;
781 U8_SAVE_HANGUL_AS_UTF8(u8s
, 0, 1, 2, b1
);
782 U8_SAVE_HANGUL_AS_UTF8(u8s
, 3, 4, 5, b2
);
784 b3
+= U8_HANGUL_JAMO_T_FIRST
;
785 U8_SAVE_HANGUL_AS_UTF8(u8s
, 6, 7, 8, b3
);
788 *state
= U8_STATE_HANGUL_LVT
;
793 *state
= U8_STATE_HANGUL_LV
;
803 * If this is a Hangul Jamo, we know there is nothing
804 * further that we can decompose.
806 if (U8_HANGUL_JAMO_L(u1
)) {
807 *state
= U8_STATE_HANGUL_L
;
811 if (U8_HANGUL_JAMO_V(u1
)) {
812 if (*state
== U8_STATE_HANGUL_L
)
813 *state
= U8_STATE_HANGUL_LV
;
815 *state
= U8_STATE_HANGUL_V
;
819 if (U8_HANGUL_JAMO_T(u1
)) {
820 if (*state
== U8_STATE_HANGUL_LV
)
821 *state
= U8_STATE_HANGUL_LVT
;
823 *state
= U8_STATE_HANGUL_T
;
826 } else if (sz
== 4) {
834 * This is a fallback and should not happen if the function
835 * was called properly.
839 *state
= U8_STATE_START
;
844 * At this point, this rountine does not know what it would get.
845 * The caller should sort it out if the state isn't a Hangul one.
847 *state
= U8_STATE_START
;
849 /* Try to find matching decomposition mapping byte sequence. */
850 b1
= u8_common_b1_tbl
[uv
][b1
];
851 if (b1
== U8_TBL_ELEMENT_NOT_DEF
)
854 b2
= u8_decomp_b2_tbl
[uv
][b1
][b2
];
855 if (b2
== U8_TBL_ELEMENT_NOT_DEF
)
858 b3_tbl
= u8_decomp_b3_tbl
[uv
][b2
][b3
].tbl_id
;
859 if (b3_tbl
== U8_TBL_ELEMENT_NOT_DEF
)
863 * If b3_tbl is bigger than or equal to U8_16BIT_TABLE_INDICATOR
864 * which is 0x8000, this means we couldn't fit the mappings into
865 * the cardinality of a unsigned byte.
867 if (b3_tbl
>= U8_16BIT_TABLE_INDICATOR
) {
868 b3_tbl
-= U8_16BIT_TABLE_INDICATOR
;
869 start_id
= u8_decomp_b4_16bit_tbl
[uv
][b3_tbl
][b4
];
870 end_id
= u8_decomp_b4_16bit_tbl
[uv
][b3_tbl
][b4
+ 1];
872 start_id
= u8_decomp_b4_tbl
[uv
][b3_tbl
][b4
];
873 end_id
= u8_decomp_b4_tbl
[uv
][b3_tbl
][b4
+ 1];
876 /* This also means there wasn't any matching decomposition. */
877 if (start_id
>= end_id
)
881 * The final table for decomposition mappings has three types of
882 * byte sequences depending on whether a mapping is for compatibility
883 * decomposition, canonical decomposition, or both like the following:
885 * (1) Compatibility decomposition mappings:
887 * +---+---+-...-+---+
888 * | B0| B1| ... | Bm|
889 * +---+---+-...-+---+
891 * The first byte, B0, is always less then 0xF5 (U8_DECOMP_BOTH).
893 * (2) Canonical decomposition mappings:
895 * +---+---+---+-...-+---+
896 * | T | b0| b1| ... | bn|
897 * +---+---+---+-...-+---+
899 * where the first byte, T, is 0xF6 (U8_DECOMP_CANONICAL).
903 * +---+---+---+---+-...-+---+---+---+-...-+---+
904 * | T | D | b0| b1| ... | bn| B0| B1| ... | Bm|
905 * +---+---+---+---+-...-+---+---+---+-...-+---+
907 * where T is 0xF5 (U8_DECOMP_BOTH) and D is a displacement
908 * byte, b0 to bn are canonical mapping bytes and B0 to Bm are
909 * compatibility mapping bytes.
911 * Note that compatibility decomposition means doing recursive
912 * decompositions using both compatibility decomposition mappings and
913 * canonical decomposition mappings. On the other hand, canonical
914 * decomposition means doing recursive decompositions using only
915 * canonical decomposition mappings. Since the table we have has gone
916 * through the recursions already, we do not need to do so during
917 * runtime, i.e., the table has been completely flattened out
921 b3_base
= u8_decomp_b3_tbl
[uv
][b2
][b3
].base
;
923 /* Get the type, T, of the byte sequence. */
924 b1
= u8_decomp_final_tbl
[uv
][b3_base
+ start_id
];
927 * If necessary, adjust start_id, end_id, or both. Note that if
928 * this is compatibility decomposition mapping, there is no
931 if (canonical_decomposition
) {
932 /* Is the mapping only for compatibility decomposition? */
933 if (b1
< U8_DECOMP_BOTH
)
938 if (b1
== U8_DECOMP_BOTH
) {
940 u8_decomp_final_tbl
[uv
][b3_base
+ start_id
];
945 * Unless this is a compatibility decomposition mapping,
946 * we adjust the start_id.
948 if (b1
== U8_DECOMP_BOTH
) {
950 start_id
+= u8_decomp_final_tbl
[uv
][b3_base
+ start_id
];
951 } else if (b1
== U8_DECOMP_CANONICAL
) {
956 for (i
= 0; start_id
< end_id
; start_id
++)
957 u8s
[i
++] = u8_decomp_final_tbl
[uv
][b3_base
+ start_id
];
964 * The find_composition_start() function uses the character bytes given and
965 * find out the matching composition mappings if any and return the address
966 * to the composition mappings as explained in the do_composition().
969 find_composition_start(size_t uv
, uchar_t
*s
, size_t sz
)
982 } else if (sz
== 2) {
985 } else if (sz
== 3) {
989 } else if (sz
== 4) {
996 * This is a fallback and should not happen if the function
997 * was called properly.
1002 b1
= u8_composition_b1_tbl
[uv
][b1
];
1003 if (b1
== U8_TBL_ELEMENT_NOT_DEF
)
1006 b2
= u8_composition_b2_tbl
[uv
][b1
][b2
];
1007 if (b2
== U8_TBL_ELEMENT_NOT_DEF
)
1010 b3_tbl
= u8_composition_b3_tbl
[uv
][b2
][b3
].tbl_id
;
1011 if (b3_tbl
== U8_TBL_ELEMENT_NOT_DEF
)
1014 if (b3_tbl
>= U8_16BIT_TABLE_INDICATOR
) {
1015 b3_tbl
-= U8_16BIT_TABLE_INDICATOR
;
1016 start_id
= u8_composition_b4_16bit_tbl
[uv
][b3_tbl
][b4
];
1017 end_id
= u8_composition_b4_16bit_tbl
[uv
][b3_tbl
][b4
+ 1];
1019 start_id
= u8_composition_b4_tbl
[uv
][b3_tbl
][b4
];
1020 end_id
= u8_composition_b4_tbl
[uv
][b3_tbl
][b4
+ 1];
1023 if (start_id
>= end_id
)
1026 b3_base
= u8_composition_b3_tbl
[uv
][b2
][b3
].base
;
1028 return ((uchar_t
*)&(u8_composition_final_tbl
[uv
][b3_base
+ start_id
]));
1032 * The blocked() function checks on the combining class values of previous
1033 * characters in this sequence and return whether it is blocked or not.
1036 blocked(uchar_t
*comb_class
, size_t last
)
1038 uchar_t my_comb_class
;
1041 my_comb_class
= comb_class
[last
];
1042 for (i
= 1; i
< last
; i
++)
1043 if (comb_class
[i
] >= my_comb_class
||
1044 comb_class
[i
] == U8_COMBINING_CLASS_STARTER
)
1051 * The do_composition() reads the character string pointed by 's' and
1052 * do necessary canonical composition and then copy over the result back to
1055 * The input argument 's' cannot contain more than 32 characters.
1058 do_composition(size_t uv
, uchar_t
*s
, uchar_t
*comb_class
, uchar_t
*start
,
1059 uchar_t
*disp
, size_t last
, uchar_t
**os
, uchar_t
*oslast
)
1061 uchar_t t
[U8_STREAM_SAFE_TEXT_MAX
+ 1];
1062 uchar_t tc
[U8_MB_CUR_MAX
];
1063 uint8_t saved_marks
[U8_MAX_CHARS_A_SEQ
];
1064 size_t saved_marks_count
;
1078 boolean_t match_not_found
= B_TRUE
;
1081 * This should never happen unless the callers are doing some strange
1082 * and unexpected things.
1084 * The "last" is the index pointing to the last character not last + 1.
1086 if (last
>= U8_MAX_CHARS_A_SEQ
)
1087 last
= U8_UPPER_LIMIT_IN_A_SEQ
;
1089 for (i
= l
= 0; i
<= last
; i
++) {
1091 * The last or any non-Starters at the beginning, we don't
1092 * have any chance to do composition and so we just copy them
1093 * to the temporary buffer.
1095 if (i
>= last
|| comb_class
[i
] != U8_COMBINING_CLASS_STARTER
) {
1099 for (k
= 0; k
< size
; k
++)
1105 * If this could be a start of Hangul Jamos, then, we try to
1108 if (s
[start
[i
]] == U8_HANGUL_JAMO_1ST_BYTE
) {
1109 U8_PUT_3BYTES_INTO_UTF32(u1
, s
[start
[i
]],
1110 s
[start
[i
] + 1], s
[start
[i
] + 2]);
1111 U8_PUT_3BYTES_INTO_UTF32(u2
, s
[start
[i
] + 3],
1112 s
[start
[i
] + 4], s
[start
[i
] + 5]);
1114 if (U8_HANGUL_JAMO_L(u1
) && U8_HANGUL_JAMO_V(u2
)) {
1115 u1
-= U8_HANGUL_JAMO_L_FIRST
;
1116 u2
-= U8_HANGUL_JAMO_V_FIRST
;
1117 u1
= U8_HANGUL_SYL_FIRST
+
1118 (u1
* U8_HANGUL_V_COUNT
+ u2
) *
1123 U8_PUT_3BYTES_INTO_UTF32(u2
,
1124 s
[start
[i
]], s
[start
[i
] + 1],
1127 if (U8_HANGUL_JAMO_T(u2
)) {
1129 U8_HANGUL_JAMO_T_FIRST
;
1134 U8_SAVE_HANGUL_AS_UTF8(t
+ l
, 0, 1, 2, u1
);
1142 * Let's then find out if this Starter has composition
1145 p
= find_composition_start(uv
, s
+ start
[i
], disp
[i
]);
1150 * We have a Starter with composition mapping and the next
1151 * character is a non-Starter. Let's try to find out if
1152 * we can do composition.
1158 saved_marks_count
= 0;
1165 * The next for() loop compares the non-Starter pointed by
1166 * 'q' with the possible (joinable) characters pointed by 'p'.
1168 * The composition final table entry pointed by the 'p'
1169 * looks like the following:
1171 * +---+---+---+-...-+---+---+---+---+-...-+---+---+
1172 * | C | b0| b2| ... | bn| F | B0| B1| ... | Bm| F |
1173 * +---+---+---+-...-+---+---+---+---+-...-+---+---+
1175 * where C is the count byte indicating the number of
1176 * mapping pairs where each pair would be look like
1177 * (b0-bn F, B0-Bm F). The b0-bn are the bytes of the second
1178 * character of a canonical decomposition and the B0-Bm are
1179 * the bytes of a matching composite character. The F is
1180 * a filler byte after each character as the separator.
1183 match_not_found
= B_TRUE
;
1185 for (C
= *p
++; C
> 0; C
--) {
1186 for (k
= 0; k
< size
; p
++, k
++)
1190 /* Have we found it? */
1191 if (k
>= size
&& *p
== U8_TBL_ELEMENT_FILLER
) {
1192 match_not_found
= B_FALSE
;
1196 while (*++p
!= U8_TBL_ELEMENT_FILLER
)
1202 /* We didn't find; skip to the next pair. */
1203 if (*p
!= U8_TBL_ELEMENT_FILLER
)
1204 while (*++p
!= U8_TBL_ELEMENT_FILLER
)
1206 while (*++p
!= U8_TBL_ELEMENT_FILLER
)
1212 * If there was no match, we will need to save the combining
1213 * mark for later appending. After that, if the next one
1214 * is a non-Starter and not blocked, then, we try once
1215 * again to do composition with the next non-Starter.
1217 * If there was no match and this was a Starter, then,
1218 * this is a new start.
1220 * If there was a match and a composition done and we have
1221 * more to check on, then, we retrieve a new composition final
1222 * table entry for the composite and then try to do the
1223 * composition again.
1226 if (match_not_found
) {
1227 if (comb_class
[i
] == U8_COMBINING_CLASS_STARTER
) {
1232 saved_marks
[saved_marks_count
++] = i
;
1237 if (blocked(comb_class
, i
+ 1))
1238 saved_marks
[saved_marks_count
++] = ++i
;
1244 goto TRY_THE_NEXT_MARK
;
1246 } else if (i
< last
) {
1247 p
= find_composition_start(uv
, t
+ saved_l
,
1251 goto TRY_THE_NEXT_MARK
;
1256 * There is no more composition possible.
1258 * If there was no composition what so ever then we copy
1259 * over the original Starter and then append any non-Starters
1260 * remaining at the target string sequentially after that.
1264 p
= s
+ start
[saved_i
];
1265 size
= disp
[saved_i
];
1266 for (j
= 0; j
< size
; j
++)
1270 for (k
= 0; k
< saved_marks_count
; k
++) {
1271 p
= s
+ start
[saved_marks
[k
]];
1272 size
= disp
[saved_marks
[k
]];
1273 for (j
= 0; j
< size
; j
++)
1279 * If the last character is a Starter and if we have a character
1280 * (possibly another Starter) that can be turned into a composite,
1281 * we do so and we do so until there is no more of composition
1284 if (comb_class
[last
] == U8_COMBINING_CLASS_STARTER
) {
1286 saved_l
= l
- disp
[last
];
1288 while (p
< oslast
) {
1289 size
= u8_number_of_bytes
[*p
];
1290 if (size
<= 1 || (p
+ size
) > oslast
)
1295 for (i
= 0; i
< size
; i
++)
1298 q
= find_composition_start(uv
, t
+ saved_l
,
1305 match_not_found
= B_TRUE
;
1307 for (C
= *q
++; C
> 0; C
--) {
1308 for (k
= 0; k
< size
; q
++, k
++)
1312 if (k
>= size
&& *q
== U8_TBL_ELEMENT_FILLER
) {
1313 match_not_found
= B_FALSE
;
1317 while (*++q
!= U8_TBL_ELEMENT_FILLER
) {
1319 * This is practically
1320 * impossible but we don't
1321 * want to take any chances.
1324 U8_STREAM_SAFE_TEXT_MAX
) {
1334 if (*q
!= U8_TBL_ELEMENT_FILLER
)
1335 while (*++q
!= U8_TBL_ELEMENT_FILLER
)
1337 while (*++q
!= U8_TBL_ELEMENT_FILLER
)
1342 if (match_not_found
) {
1352 * Now we copy over the temporary string to the target string.
1353 * Since composition always reduces the number of characters or
1354 * the number of characters stay, we don't need to worry about
1355 * the buffer overflow here.
1357 for (i
= 0; i
< l
; i
++)
1365 * The collect_a_seq() function checks on the given string s, collect
1366 * a sequence of characters at u8s, and return the sequence. While it collects
1367 * a sequence, it also applies case conversion, canonical or compatibility
1368 * decomposition, canonical decomposition, or some or all of them and
1371 * The collected sequence cannot be bigger than 32 characters since if
1372 * it is having more than 31 characters, the sequence will be terminated
1373 * with a U+034F COMBINING GRAPHEME JOINER (CGJ) character and turned into
1374 * a Stream-Safe Text. The collected sequence is always terminated with
1375 * a null byte and the return value is the byte length of the sequence
1376 * including 0. The return value does not include the terminating
1380 collect_a_seq(size_t uv
, uchar_t
*u8s
, uchar_t
**source
, uchar_t
*slast
,
1381 boolean_t is_it_toupper
,
1382 boolean_t is_it_tolower
,
1383 boolean_t canonical_decomposition
,
1384 boolean_t compatibility_decomposition
,
1385 boolean_t canonical_composition
,
1386 int *errnum
, u8_normalization_states_t
*state
)
1395 uchar_t comb_class
[U8_MAX_CHARS_A_SEQ
];
1396 uchar_t disp
[U8_MAX_CHARS_A_SEQ
];
1397 uchar_t start
[U8_MAX_CHARS_A_SEQ
];
1398 uchar_t u8t
[U8_MB_CUR_MAX
];
1399 uchar_t uts
[U8_STREAM_SAFE_TEXT_MAX
+ 1];
1406 * Save the source string pointer which we will return a changed
1407 * pointer if we do processing.
1412 * The following is a fallback for just in case callers are not
1413 * checking the string boundaries before the calling.
1422 * As the first thing, let's collect a character and do case
1423 * conversion if necessary.
1426 sz
= u8_number_of_bytes
[*s
];
1441 u8s
[0] = U8_ASCII_TOUPPER(*s
);
1442 else if (is_it_tolower
)
1443 u8s
[0] = U8_ASCII_TOLOWER(*s
);
1448 } else if ((s
+ sz
) > slast
) {
1451 for (i
= 0; s
< slast
; )
1459 if (is_it_toupper
|| is_it_tolower
) {
1460 i
= do_case_conv(uv
, u8s
, s
, sz
, is_it_toupper
);
1464 for (i
= 0; i
< sz
; )
1471 * And then canonical/compatibility decomposition followed by
1472 * an optional canonical composition. Please be noted that
1473 * canonical composition is done only when a decomposition is
1476 if (canonical_decomposition
|| compatibility_decomposition
) {
1478 *state
= U8_STATE_START
;
1488 saved_sz
= do_decomp(uv
, u8s
, u8s
, sz
,
1489 canonical_decomposition
, state
);
1493 for (i
= 0; i
< saved_sz
; ) {
1494 sz
= u8_number_of_bytes
[u8s
[i
]];
1496 comb_class
[last
] = combining_class(uv
,
1506 * Decomposition yields various Hangul related
1507 * states but not on combining marks. We need to
1508 * find out at here by checking on the last
1511 if (*state
== U8_STATE_START
) {
1512 if (comb_class
[last
- 1])
1513 *state
= U8_STATE_COMBINING_MARK
;
1520 sz
= u8_number_of_bytes
[*s
];
1523 * If this is an illegal character, an incomplete
1524 * character, or an 7-bit ASCII Starter character,
1525 * then we have collected a sequence; break and let
1526 * the next call deal with the two cases.
1528 * Note that this is okay only if you are using this
1529 * function with a fixed length string, not on
1530 * a buffer with multiple calls of one chunk at a time.
1534 } else if ((s
+ sz
) > slast
) {
1538 * If the previous character was a Hangul Jamo
1539 * and this character is a Hangul Jamo that
1540 * can be conjoined, we collect the Jamo.
1542 if (*s
== U8_HANGUL_JAMO_1ST_BYTE
) {
1543 U8_PUT_3BYTES_INTO_UTF32(u1
,
1544 *s
, *(s
+ 1), *(s
+ 2));
1546 if (U8_HANGUL_COMPOSABLE_L_V(*state
,
1549 *state
= U8_STATE_HANGUL_LV
;
1550 goto COLLECT_A_HANGUL
;
1553 if (U8_HANGUL_COMPOSABLE_LV_T(*state
,
1556 *state
= U8_STATE_HANGUL_LVT
;
1557 goto COLLECT_A_HANGUL
;
1562 * Regardless of whatever it was, if this is
1563 * a Starter, we don't collect the character
1564 * since that's a new start and we will deal
1565 * with it at the next time.
1567 i
= combining_class(uv
, s
, sz
);
1568 if (i
== U8_COMBINING_CLASS_STARTER
)
1572 * We know the current character is a combining
1573 * mark. If the previous character wasn't
1574 * a Starter (not Hangul) or a combining mark,
1575 * then, we don't collect this combining mark.
1577 if (*state
!= U8_STATE_START
&&
1578 *state
!= U8_STATE_COMBINING_MARK
)
1581 *state
= U8_STATE_COMBINING_MARK
;
1584 * If we collected a Starter and combining
1585 * marks up to 30, i.e., total 31 characters,
1586 * then, we terminate this degenerately long
1587 * combining sequence with a U+034F COMBINING
1588 * GRAPHEME JOINER (CGJ) which is 0xCD 0x8F in
1589 * UTF-8 and turn this into a Stream-Safe
1590 * Text. This will be extremely rare but
1593 * The following will also guarantee that
1594 * we are not writing more than 32 characters
1595 * plus a NULL at u8s[].
1597 if (last
>= U8_UPPER_LIMIT_IN_A_SEQ
) {
1599 *state
= U8_STATE_START
;
1600 comb_class
[last
] = 0;
1601 start
[last
] = saved_sz
;
1605 u8s
[saved_sz
++] = 0xCD;
1606 u8s
[saved_sz
++] = 0x8F;
1612 * Some combining marks also do decompose into
1613 * another combining mark or marks.
1615 if (*state
== U8_STATE_COMBINING_MARK
) {
1618 i
= do_decomp(uv
, uts
, s
, sz
,
1619 canonical_decomposition
, state
);
1620 for (j
= 0; j
< i
; ) {
1621 sz
= u8_number_of_bytes
[uts
[j
]];
1626 start
[last
] = saved_sz
+ j
;
1631 U8_UPPER_LIMIT_IN_A_SEQ
) {
1633 goto TURN_STREAM_SAFE
;
1638 *state
= U8_STATE_COMBINING_MARK
;
1642 for (i
= 0; i
< sz
; i
++)
1643 u8s
[saved_sz
++] = uts
[i
];
1645 comb_class
[last
] = i
;
1646 start
[last
] = saved_sz
;
1650 for (i
= 0; i
< sz
; i
++)
1651 u8s
[saved_sz
++] = *s
++;
1655 * If this is U+0345 COMBINING GREEK
1656 * YPOGEGRAMMENI (0xCD 0x85 in UTF-8), a.k.a.,
1657 * iota subscript, and need to be converted to
1658 * uppercase letter, convert it to U+0399 GREEK
1659 * CAPITAL LETTER IOTA (0xCE 0x99 in UTF-8),
1660 * i.e., convert to capital adscript form as
1661 * specified in the Unicode standard.
1663 * This is the only special case of (ambiguous)
1664 * case conversion at combining marks and
1665 * probably the standard will never have
1666 * anything similar like this in future.
1668 if (is_it_toupper
&& sz
>= 2 &&
1669 u8s
[saved_sz
- 2] == 0xCD &&
1670 u8s
[saved_sz
- 1] == 0x85) {
1671 u8s
[saved_sz
- 2] = 0xCE;
1672 u8s
[saved_sz
- 1] = 0x99;
1678 * Let's try to ensure a canonical ordering for the collected
1679 * combining marks. We do this only if we have collected
1680 * at least one more non-Starter. (The decomposition mapping
1681 * data tables have fully (and recursively) expanded and
1682 * canonically ordered decompositions.)
1684 * The U8_SWAP_COMB_MARKS() convenience macro has some
1685 * assumptions and we are meeting the assumptions.
1688 if (last
>= saved_last
) {
1689 for (i
= 0; i
< last
; i
++)
1690 for (j
= last
; j
> i
; j
--)
1691 if (comb_class
[j
] &&
1692 comb_class
[j
- 1] > comb_class
[j
]) {
1693 U8_SWAP_COMB_MARKS(j
- 1, j
);
1699 if (! canonical_composition
) {
1700 u8s
[saved_sz
] = '\0';
1705 * Now do the canonical composition. Note that we do this
1706 * only after a canonical or compatibility decomposition to
1707 * finish up NFC or NFKC.
1709 sz
= do_composition(uv
, u8s
, comb_class
, start
, disp
, last
,
1715 return ((size_t)sz
);
1719 * The do_norm_compare() function does string comparion based on Unicode
1720 * simple case mappings and Unicode Normalization definitions.
1722 * It does so by collecting a sequence of character at a time and comparing
1723 * the collected sequences from the strings.
1725 * The meanings on the return values are the same as the usual strcmp().
1728 do_norm_compare(size_t uv
, uchar_t
*s1
, uchar_t
*s2
, size_t n1
, size_t n2
,
1729 int flag
, int *errnum
)
1734 uchar_t u8s1
[U8_STREAM_SAFE_TEXT_MAX
+ 1];
1735 uchar_t u8s2
[U8_STREAM_SAFE_TEXT_MAX
+ 1];
1738 boolean_t is_it_toupper
;
1739 boolean_t is_it_tolower
;
1740 boolean_t canonical_decomposition
;
1741 boolean_t compatibility_decomposition
;
1742 boolean_t canonical_composition
;
1743 u8_normalization_states_t state
;
1748 is_it_toupper
= flag
& U8_TEXTPREP_TOUPPER
;
1749 is_it_tolower
= flag
& U8_TEXTPREP_TOLOWER
;
1750 canonical_decomposition
= flag
& U8_CANON_DECOMP
;
1751 compatibility_decomposition
= flag
& U8_COMPAT_DECOMP
;
1752 canonical_composition
= flag
& U8_CANON_COMP
;
1754 while (s1
< s1last
&& s2
< s2last
) {
1756 * If the current character is a 7-bit ASCII and the last
1757 * character, or, if the current character and the next
1758 * character are both some 7-bit ASCII characters then
1759 * we treat the current character as a sequence.
1761 * In any other cases, we need to call collect_a_seq().
1764 if (U8_ISASCII(*s1
) && ((s1
+ 1) >= s1last
||
1765 ((s1
+ 1) < s1last
&& U8_ISASCII(*(s1
+ 1))))) {
1767 u8s1
[0] = U8_ASCII_TOUPPER(*s1
);
1768 else if (is_it_tolower
)
1769 u8s1
[0] = U8_ASCII_TOLOWER(*s1
);
1776 state
= U8_STATE_START
;
1777 sz1
= collect_a_seq(uv
, u8s1
, &s1
, s1last
,
1778 is_it_toupper
, is_it_tolower
,
1779 canonical_decomposition
,
1780 compatibility_decomposition
,
1781 canonical_composition
, errnum
, &state
);
1784 if (U8_ISASCII(*s2
) && ((s2
+ 1) >= s2last
||
1785 ((s2
+ 1) < s2last
&& U8_ISASCII(*(s2
+ 1))))) {
1787 u8s2
[0] = U8_ASCII_TOUPPER(*s2
);
1788 else if (is_it_tolower
)
1789 u8s2
[0] = U8_ASCII_TOLOWER(*s2
);
1796 state
= U8_STATE_START
;
1797 sz2
= collect_a_seq(uv
, u8s2
, &s2
, s2last
,
1798 is_it_toupper
, is_it_tolower
,
1799 canonical_decomposition
,
1800 compatibility_decomposition
,
1801 canonical_composition
, errnum
, &state
);
1805 * Now compare the two characters. If they are the same,
1806 * we move on to the next character sequences.
1808 if (sz1
== 1 && sz2
== 1) {
1814 result
= strcmp((const char *)u8s1
, (const char *)u8s2
);
1821 * We compared until the end of either or both strings.
1823 * If we reached to or went over the ends for the both, that means
1824 * they are the same.
1826 * If we reached only one end, that means the other string has
1827 * something which then can be used to determine the return value.
1838 * The u8_strcmp() function compares two UTF-8 strings quite similar to
1839 * the strcmp(). For the comparison, however, Unicode Normalization specific
1840 * equivalency and Unicode simple case conversion mappings based equivalency
1841 * can be requested and checked against.
1844 u8_strcmp(const char *s1
, const char *s2
, size_t n
, int flag
, size_t uv
,
1854 * Check on the requested Unicode version, case conversion, and
1855 * normalization flag values.
1858 if (uv
> U8_UNICODE_LATEST
) {
1860 uv
= U8_UNICODE_LATEST
;
1864 flag
= U8_STRCMP_CS
;
1866 f
= flag
& (U8_STRCMP_CS
| U8_STRCMP_CI_UPPER
|
1867 U8_STRCMP_CI_LOWER
);
1869 flag
|= U8_STRCMP_CS
;
1870 } else if (f
!= U8_STRCMP_CS
&& f
!= U8_STRCMP_CI_UPPER
&&
1871 f
!= U8_STRCMP_CI_LOWER
) {
1873 flag
= U8_STRCMP_CS
;
1876 f
= flag
& (U8_CANON_DECOMP
| U8_COMPAT_DECOMP
| U8_CANON_COMP
);
1877 if (f
&& f
!= U8_STRCMP_NFD
&& f
!= U8_STRCMP_NFC
&&
1878 f
!= U8_STRCMP_NFKD
&& f
!= U8_STRCMP_NFKC
) {
1880 flag
= U8_STRCMP_CS
;
1884 if (flag
== U8_STRCMP_CS
) {
1885 return (n
== 0 ? strcmp(s1
, s2
) : strncmp(s1
, s2
, n
));
1898 * Simple case conversion can be done much faster and so we do
1899 * them separately here.
1901 if (flag
== U8_STRCMP_CI_UPPER
) {
1902 return (do_case_compare(uv
, (uchar_t
*)s1
, (uchar_t
*)s2
,
1903 n1
, n2
, B_TRUE
, errnum
));
1904 } else if (flag
== U8_STRCMP_CI_LOWER
) {
1905 return (do_case_compare(uv
, (uchar_t
*)s1
, (uchar_t
*)s2
,
1906 n1
, n2
, B_FALSE
, errnum
));
1909 return (do_norm_compare(uv
, (uchar_t
*)s1
, (uchar_t
*)s2
, n1
, n2
,
1914 u8_textprep_str(char *inarray
, size_t *inlen
, char *outarray
, size_t *outlen
,
1915 int flag
, size_t unicode_version
, int *errnum
)
1923 boolean_t do_not_ignore_null
;
1924 boolean_t do_not_ignore_invalid
;
1925 boolean_t is_it_toupper
;
1926 boolean_t is_it_tolower
;
1927 boolean_t canonical_decomposition
;
1928 boolean_t compatibility_decomposition
;
1929 boolean_t canonical_composition
;
1933 uchar_t u8s
[U8_STREAM_SAFE_TEXT_MAX
+ 1];
1934 u8_normalization_states_t state
;
1936 if (unicode_version
> U8_UNICODE_LATEST
) {
1938 return ((size_t)-1);
1941 f
= flag
& (U8_TEXTPREP_TOUPPER
| U8_TEXTPREP_TOLOWER
);
1942 if (f
== (U8_TEXTPREP_TOUPPER
| U8_TEXTPREP_TOLOWER
)) {
1944 return ((size_t)-1);
1947 f
= flag
& (U8_CANON_DECOMP
| U8_COMPAT_DECOMP
| U8_CANON_COMP
);
1948 if (f
&& f
!= U8_TEXTPREP_NFD
&& f
!= U8_TEXTPREP_NFC
&&
1949 f
!= U8_TEXTPREP_NFKD
&& f
!= U8_TEXTPREP_NFKC
) {
1951 return ((size_t)-1);
1954 if (inarray
== NULL
|| *inlen
== 0)
1957 if (outarray
== NULL
) {
1959 return ((size_t)-1);
1962 ib
= (uchar_t
*)inarray
;
1963 ob
= (uchar_t
*)outarray
;
1964 ibtail
= ib
+ *inlen
;
1965 obtail
= ob
+ *outlen
;
1967 do_not_ignore_null
= !(flag
& U8_TEXTPREP_IGNORE_NULL
);
1968 do_not_ignore_invalid
= !(flag
& U8_TEXTPREP_IGNORE_INVALID
);
1969 is_it_toupper
= flag
& U8_TEXTPREP_TOUPPER
;
1970 is_it_tolower
= flag
& U8_TEXTPREP_TOLOWER
;
1975 * If we don't have a normalization flag set, we do the simple case
1976 * conversion based text preparation separately below. Text
1977 * preparation involving Normalization will be done in the false task
1978 * block, again, separately since it will take much more time and
1979 * resource than doing simple case conversions.
1982 while (ib
< ibtail
) {
1983 if (*ib
== '\0' && do_not_ignore_null
)
1986 sz
= u8_number_of_bytes
[*ib
];
1989 if (do_not_ignore_invalid
) {
1991 ret_val
= (size_t)-1;
2002 ret_val
= (size_t)-1;
2007 *ob
= U8_ASCII_TOUPPER(*ib
);
2008 else if (is_it_tolower
)
2009 *ob
= U8_ASCII_TOLOWER(*ib
);
2014 } else if ((ib
+ sz
) > ibtail
) {
2015 if (do_not_ignore_invalid
) {
2017 ret_val
= (size_t)-1;
2021 if ((obtail
- ob
) < (ibtail
- ib
)) {
2023 ret_val
= (size_t)-1;
2028 * We treat the remaining incomplete character
2029 * bytes as a character.
2036 if (is_it_toupper
|| is_it_tolower
) {
2037 i
= do_case_conv(unicode_version
, u8s
,
2038 ib
, sz
, is_it_toupper
);
2040 if ((obtail
- ob
) < i
) {
2042 ret_val
= (size_t)-1;
2048 for (sz
= 0; sz
< i
; sz
++)
2051 if ((obtail
- ob
) < sz
) {
2053 ret_val
= (size_t)-1;
2057 for (i
= 0; i
< sz
; i
++)
2063 canonical_decomposition
= flag
& U8_CANON_DECOMP
;
2064 compatibility_decomposition
= flag
& U8_COMPAT_DECOMP
;
2065 canonical_composition
= flag
& U8_CANON_COMP
;
2067 while (ib
< ibtail
) {
2068 if (*ib
== '\0' && do_not_ignore_null
)
2072 * If the current character is a 7-bit ASCII
2073 * character and it is the last character, or,
2074 * if the current character is a 7-bit ASCII
2075 * character and the next character is also a 7-bit
2076 * ASCII character, then, we copy over this
2077 * character without going through collect_a_seq().
2079 * In any other cases, we need to look further with
2080 * the collect_a_seq() function.
2082 if (U8_ISASCII(*ib
) && ((ib
+ 1) >= ibtail
||
2083 ((ib
+ 1) < ibtail
&& U8_ISASCII(*(ib
+ 1))))) {
2086 ret_val
= (size_t)-1;
2091 *ob
= U8_ASCII_TOUPPER(*ib
);
2092 else if (is_it_tolower
)
2093 *ob
= U8_ASCII_TOLOWER(*ib
);
2100 state
= U8_STATE_START
;
2102 j
= collect_a_seq(unicode_version
, u8s
,
2106 canonical_decomposition
,
2107 compatibility_decomposition
,
2108 canonical_composition
,
2111 if (*errnum
&& do_not_ignore_invalid
) {
2112 ret_val
= (size_t)-1;
2116 if ((obtail
- ob
) < j
) {
2118 ret_val
= (size_t)-1;
2122 for (i
= 0; i
< j
; i
++)
2128 *inlen
= ibtail
- ib
;
2129 *outlen
= obtail
- ob
;