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 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include "zfs_config.h"
32 * UTF-8 text preparation functions (PSARC/2007/149, PSARC/2007/458).
34 * Man pages: u8_textprep_open(9F), u8_textprep_buf(9F), u8_textprep_close(9F),
35 * u8_textprep_str(9F), u8_strcmp(9F), and u8_validate(9F). See also
36 * the section 3C man pages.
37 * Interface stability: Committed.
40 #include <sys/types.h>
42 #include <sys/param.h>
43 #include <sys/sysmacros.h>
44 #include <sys/systm.h>
45 #include <sys/debug.h>
48 #include <sys/sunddi.h>
50 #include <sys/u8_textprep.h>
53 #include <sys/byteorder.h>
54 #include <sys/errno.h>
55 #include <sys/u8_textprep_data.h>
59 /* The maximum possible number of bytes in a UTF-8 character. */
60 #define U8_MB_CUR_MAX (4)
63 * The maximum number of bytes needed for a UTF-8 character to cover
64 * U+0000 - U+FFFF, i.e., the coding space of now deprecated UCS-2.
66 #define U8_MAX_BYTES_UCS2 (3)
68 /* The maximum possible number of bytes in a Stream-Safe Text. */
69 #define U8_STREAM_SAFE_TEXT_MAX (128)
72 * The maximum number of characters in a combining/conjoining sequence and
73 * the actual upperbound limit of a combining/conjoining sequence.
75 #define U8_MAX_CHARS_A_SEQ (32)
76 #define U8_UPPER_LIMIT_IN_A_SEQ (31)
78 /* The combining class value for Starter. */
79 #define U8_COMBINING_CLASS_STARTER (0)
82 * Some Hangul related macros at below.
84 * The first and the last of Hangul syllables, Hangul Jamo Leading consonants,
85 * Vowels, and optional Trailing consonants in Unicode scalar values.
87 * Please be noted that the U8_HANGUL_JAMO_T_FIRST is 0x11A7 at below not
88 * the actual U+11A8. This is due to that the trailing consonant is optional
89 * and thus we are doing a pre-calculation of subtracting one.
91 * Each of 19 modern leading consonants has total 588 possible syllables since
92 * Hangul has 21 modern vowels and 27 modern trailing consonants plus 1 for
93 * no trailing consonant case, i.e., 21 x 28 = 588.
95 * We also have bunch of Hangul related macros at below. Please bear in mind
96 * that the U8_HANGUL_JAMO_1ST_BYTE can be used to check whether it is
97 * a Hangul Jamo or not but the value does not guarantee that it is a Hangul
98 * Jamo; it just guarantee that it will be most likely.
100 #define U8_HANGUL_SYL_FIRST (0xAC00U)
101 #define U8_HANGUL_SYL_LAST (0xD7A3U)
103 #define U8_HANGUL_JAMO_L_FIRST (0x1100U)
104 #define U8_HANGUL_JAMO_L_LAST (0x1112U)
105 #define U8_HANGUL_JAMO_V_FIRST (0x1161U)
106 #define U8_HANGUL_JAMO_V_LAST (0x1175U)
107 #define U8_HANGUL_JAMO_T_FIRST (0x11A7U)
108 #define U8_HANGUL_JAMO_T_LAST (0x11C2U)
110 #define U8_HANGUL_V_COUNT (21)
111 #define U8_HANGUL_VT_COUNT (588)
112 #define U8_HANGUL_T_COUNT (28)
114 #define U8_HANGUL_JAMO_1ST_BYTE (0xE1U)
116 #define U8_SAVE_HANGUL_AS_UTF8(s, i, j, k, b) \
117 (s)[(i)] = (uchar_t)(0xE0U | ((uint32_t)(b) & 0xF000U) >> 12); \
118 (s)[(j)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x0FC0U) >> 6); \
119 (s)[(k)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x003FU));
121 #define U8_HANGUL_JAMO_L(u) \
122 ((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_L_LAST)
124 #define U8_HANGUL_JAMO_V(u) \
125 ((u) >= U8_HANGUL_JAMO_V_FIRST && (u) <= U8_HANGUL_JAMO_V_LAST)
127 #define U8_HANGUL_JAMO_T(u) \
128 ((u) > U8_HANGUL_JAMO_T_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
130 #define U8_HANGUL_JAMO(u) \
131 ((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
133 #define U8_HANGUL_SYLLABLE(u) \
134 ((u) >= U8_HANGUL_SYL_FIRST && (u) <= U8_HANGUL_SYL_LAST)
136 #define U8_HANGUL_COMPOSABLE_L_V(s, u) \
137 ((s) == U8_STATE_HANGUL_L && U8_HANGUL_JAMO_V((u)))
139 #define U8_HANGUL_COMPOSABLE_LV_T(s, u) \
140 ((s) == U8_STATE_HANGUL_LV && U8_HANGUL_JAMO_T((u)))
142 /* The types of decomposition mappings. */
143 #define U8_DECOMP_BOTH (0xF5U)
144 #define U8_DECOMP_CANONICAL (0xF6U)
146 /* The indicator for 16-bit table. */
147 #define U8_16BIT_TABLE_INDICATOR (0x8000U)
149 /* The following are some convenience macros. */
150 #define U8_PUT_3BYTES_INTO_UTF32(u, b1, b2, b3) \
151 (u) = ((uint32_t)(b1) & 0x0F) << 12 | ((uint32_t)(b2) & 0x3F) << 6 | \
152 (uint32_t)(b3) & 0x3F;
154 #define U8_SIMPLE_SWAP(a, b, t) \
159 #define U8_ASCII_TOUPPER(c) \
160 (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c))
162 #define U8_ASCII_TOLOWER(c) \
163 (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
165 #define U8_ISASCII(c) (((uchar_t)(c)) < 0x80U)
167 * The following macro assumes that the two characters that are to be
168 * swapped are adjacent to each other and 'a' comes before 'b'.
170 * If the assumptions are not met, then, the macro will fail.
172 #define U8_SWAP_COMB_MARKS(a, b) \
173 for (k = 0; k < disp[(a)]; k++) \
174 u8t[k] = u8s[start[(a)] + k]; \
175 for (k = 0; k < disp[(b)]; k++) \
176 u8s[start[(a)] + k] = u8s[start[(b)] + k]; \
177 start[(b)] = start[(a)] + disp[(b)]; \
178 for (k = 0; k < disp[(a)]; k++) \
179 u8s[start[(b)] + k] = u8t[k]; \
180 U8_SIMPLE_SWAP(comb_class[(a)], comb_class[(b)], tc); \
181 U8_SIMPLE_SWAP(disp[(a)], disp[(b)], tc);
183 /* The possible states during normalization. */
186 U8_STATE_HANGUL_L = 1,
187 U8_STATE_HANGUL_LV = 2,
188 U8_STATE_HANGUL_LVT = 3,
189 U8_STATE_HANGUL_V = 4,
190 U8_STATE_HANGUL_T = 5,
191 U8_STATE_COMBINING_MARK = 6
192 } u8_normalization_states_t;
195 * The three vectors at below are used to check bytes of a given UTF-8
196 * character are valid and not containing any malformed byte values.
198 * We used to have a quite relaxed UTF-8 binary representation but then there
199 * was some security related issues and so the Unicode Consortium defined
200 * and announced the UTF-8 Corrigendum at Unicode 3.1 and then refined it
201 * one more time at the Unicode 3.2. The following three tables are based on
205 #define U8_ILLEGAL_NEXT_BYTE_COMMON(c) ((c) < 0x80 || (c) > 0xBF)
207 #define I_ U8_ILLEGAL_CHAR
208 #define O_ U8_OUT_OF_RANGE_CHAR
210 const int8_t u8_number_of_bytes[0x100] = {
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,
216 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
217 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
218 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
220 /* 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F */
221 I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
223 /* 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F */
224 I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
226 /* A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF */
227 I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
229 /* B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF */
230 I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
232 /* C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF */
233 I_, I_, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
235 /* D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF */
236 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
238 /* E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF */
239 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
241 /* F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF */
242 4, 4, 4, 4, 4, O_, O_, O_, O_, O_, O_, O_, O_, O_, O_, O_,
248 const uint8_t u8_valid_min_2nd_byte[0x100] = {
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 0, 0, 0, 0, 0, 0, 0, 0,
271 0, 0, 0, 0, 0, 0, 0, 0,
272 0, 0, 0, 0, 0, 0, 0, 0,
273 /* C0 C1 C2 C3 C4 C5 C6 C7 */
274 0, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
275 /* C8 C9 CA CB CC CD CE CF */
276 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
277 /* D0 D1 D2 D3 D4 D5 D6 D7 */
278 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
279 /* D8 D9 DA DB DC DD DE DF */
280 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
281 /* E0 E1 E2 E3 E4 E5 E6 E7 */
282 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
283 /* E8 E9 EA EB EC ED EE EF */
284 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
285 /* F0 F1 F2 F3 F4 F5 F6 F7 */
286 0x90, 0x80, 0x80, 0x80, 0x80, 0, 0, 0,
287 0, 0, 0, 0, 0, 0, 0, 0,
290 const uint8_t u8_valid_max_2nd_byte[0x100] = {
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 0, 0, 0, 0, 0, 0, 0, 0,
313 0, 0, 0, 0, 0, 0, 0, 0,
314 0, 0, 0, 0, 0, 0, 0, 0,
315 /* C0 C1 C2 C3 C4 C5 C6 C7 */
316 0, 0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
317 /* C8 C9 CA CB CC CD CE CF */
318 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
319 /* D0 D1 D2 D3 D4 D5 D6 D7 */
320 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
321 /* D8 D9 DA DB DC DD DE DF */
322 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
323 /* E0 E1 E2 E3 E4 E5 E6 E7 */
324 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
325 /* E8 E9 EA EB EC ED EE EF */
326 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x9f, 0xbf, 0xbf,
327 /* F0 F1 F2 F3 F4 F5 F6 F7 */
328 0xbf, 0xbf, 0xbf, 0xbf, 0x8f, 0, 0, 0,
329 0, 0, 0, 0, 0, 0, 0, 0,
334 * The u8_validate() validates on the given UTF-8 character string and
335 * calculate the byte length. It is quite similar to mblen(3C) except that
336 * this will validate against the list of characters if required and
337 * specific to UTF-8 and Unicode.
340 u8_validate(char *u8str, size_t n, char **list, int flag, int *errno)
352 boolean_t no_need_to_validate_entire;
353 boolean_t check_additional;
354 boolean_t validate_ucs2_range_only;
359 ib = (uchar_t *)u8str;
364 no_need_to_validate_entire = ! (flag & U8_VALIDATE_ENTIRE);
365 check_additional = flag & U8_VALIDATE_CHECK_ADDITIONAL;
366 validate_ucs2_range_only = flag & U8_VALIDATE_UCS2_RANGE;
368 while (ib < ibtail) {
370 * The first byte of a UTF-8 character tells how many
371 * bytes will follow for the character. If the first byte
372 * is an illegal byte value or out of range value, we just
373 * return -1 with an appropriate error number.
375 sz = u8_number_of_bytes[*ib];
376 if (sz == U8_ILLEGAL_CHAR) {
381 if (sz == U8_OUT_OF_RANGE_CHAR ||
382 (validate_ucs2_range_only && sz > U8_MAX_BYTES_UCS2)) {
388 * If we don't have enough bytes to check on, that's also
389 * an error. As you can see, we give illegal byte sequence
390 * checking higher priority then EINVAL cases.
392 if ((ibtail - ib) < sz) {
402 * Check on the multi-byte UTF-8 character. For more
403 * details on this, see comment added for the used
404 * data structures at the beginning of the file.
409 for (i = 1; i < sz; i++) {
411 if (*ib < u8_valid_min_2nd_byte[f] ||
412 *ib > u8_valid_max_2nd_byte[f]) {
417 } else if (U8_ILLEGAL_NEXT_BYTE_COMMON(*ib)) {
426 if (check_additional) {
427 for (p = (uchar_t **)list, i = 0; p[i]; i++) {
431 if (*s1 != *s2 || *s2 == '\0')
437 if (s1 >= ib && *s2 == '\0') {
444 if (no_need_to_validate_entire)
452 * The do_case_conv() looks at the mapping tables and returns found
453 * bytes if any. If not found, the input bytes are returned. The function
454 * always terminate the return bytes with a null character assuming that
455 * there are plenty of room to do so.
457 * The case conversions are simple case conversions mapping a character to
458 * another character as specified in the Unicode data. The byte size of
459 * the mapped character could be different from that of the input character.
461 * The return value is the byte length of the returned character excluding
462 * the terminating null byte.
465 do_case_conv(int uv, uchar_t *u8s, uchar_t *s, int sz, boolean_t is_it_toupper)
478 * At this point, the only possible values for sz are 2, 3, and 4.
479 * The u8s should point to a vector that is well beyond the size of
485 } else if (sz == 3) {
489 } else if (sz == 4) {
495 /* This is not possible but just in case as a fallback. */
497 *u8s = U8_ASCII_TOUPPER(*s);
499 *u8s = U8_ASCII_TOLOWER(*s);
507 * Let's find out if we have a corresponding character.
509 b1 = u8_common_b1_tbl[uv][b1];
510 if (b1 == U8_TBL_ELEMENT_NOT_DEF)
513 b2 = u8_case_common_b2_tbl[uv][b1][b2];
514 if (b2 == U8_TBL_ELEMENT_NOT_DEF)
518 b3_tbl = u8_toupper_b3_tbl[uv][b2][b3].tbl_id;
519 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
522 start_id = u8_toupper_b4_tbl[uv][b3_tbl][b4];
523 end_id = u8_toupper_b4_tbl[uv][b3_tbl][b4 + 1];
525 /* Either there is no match or an error at the table. */
526 if (start_id >= end_id || (end_id - start_id) > U8_MB_CUR_MAX)
529 b3_base = u8_toupper_b3_tbl[uv][b2][b3].base;
531 for (i = 0; start_id < end_id; start_id++)
532 u8s[i++] = u8_toupper_final_tbl[uv][b3_base + start_id];
534 b3_tbl = u8_tolower_b3_tbl[uv][b2][b3].tbl_id;
535 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
538 start_id = u8_tolower_b4_tbl[uv][b3_tbl][b4];
539 end_id = u8_tolower_b4_tbl[uv][b3_tbl][b4 + 1];
541 if (start_id >= end_id || (end_id - start_id) > U8_MB_CUR_MAX)
544 b3_base = u8_tolower_b3_tbl[uv][b2][b3].base;
546 for (i = 0; start_id < end_id; start_id++)
547 u8s[i++] = u8_tolower_final_tbl[uv][b3_base + start_id];
551 * If i is still zero, that means there is no corresponding character.
562 * The do_case_compare() function compares the two input strings, s1 and s2,
563 * one character at a time doing case conversions if applicable and return
564 * the comparison result as like strcmp().
566 * Since, in empirical sense, most of text data are 7-bit ASCII characters,
567 * we treat the 7-bit ASCII characters as a special case trying to yield
568 * faster processing time.
571 do_case_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1,
572 size_t n2, boolean_t is_it_toupper, int *errno)
580 uchar_t u8s1[U8_MB_CUR_MAX + 1];
581 uchar_t u8s2[U8_MB_CUR_MAX + 1];
584 while (i1 < n1 && i2 < n2) {
586 * Find out what would be the byte length for this UTF-8
587 * character at string s1 and also find out if this is
588 * an illegal start byte or not and if so, issue a proper
589 * errno and yet treat this byte as a character.
591 sz1 = u8_number_of_bytes[*s1];
598 * For 7-bit ASCII characters mainly, we do a quick case
599 * conversion right at here.
601 * If we don't have enough bytes for this character, issue
602 * an EINVAL error and use what are available.
604 * If we have enough bytes, find out if there is
605 * a corresponding uppercase character and if so, copy over
606 * the bytes for a comparison later. If there is no
607 * corresponding uppercase character, then, use what we have
608 * for the comparison.
612 u8s1[0] = U8_ASCII_TOUPPER(*s1);
614 u8s1[0] = U8_ASCII_TOLOWER(*s1);
617 } else if ((i1 + sz1) > n1) {
619 for (j = 0; (i1 + j) < n1; )
623 (void) do_case_conv(uv, u8s1, s1, sz1, is_it_toupper);
627 /* Do the same for the string s2. */
628 sz2 = u8_number_of_bytes[*s2];
636 u8s2[0] = U8_ASCII_TOUPPER(*s2);
638 u8s2[0] = U8_ASCII_TOLOWER(*s2);
641 } else if ((i2 + sz2) > n2) {
643 for (j = 0; (i2 + j) < n2; )
647 (void) do_case_conv(uv, u8s2, s2, sz2, is_it_toupper);
651 /* Now compare the two characters. */
652 if (sz1 == 1 && sz2 == 1) {
658 f = strcmp((const char *)u8s1, (const char *)u8s2);
664 * They were the same. Let's move on to the next
672 * We compared until the end of either or both strings.
674 * If we reached to or went over the ends for the both, that means
677 * If we reached only one of the two ends, that means the other string
678 * has something which then the fact can be used to determine
690 * The combining_class() function checks on the given bytes and find out
691 * the corresponding Unicode combining class value. The return value 0 means
692 * it is a Starter. Any illegal UTF-8 character will also be treated as
696 combining_class(size_t uv, uchar_t *s, size_t sz)
703 if (sz == 1 || sz > 4)
709 } else if (sz == 3) {
713 } else if (sz == 4) {
720 b1 = u8_common_b1_tbl[uv][b1];
721 if (b1 == U8_TBL_ELEMENT_NOT_DEF)
724 b2 = u8_combining_class_b2_tbl[uv][b1][b2];
725 if (b2 == U8_TBL_ELEMENT_NOT_DEF)
728 b3 = u8_combining_class_b3_tbl[uv][b2][b3];
729 if (b3 == U8_TBL_ELEMENT_NOT_DEF)
732 return (u8_combining_class_b4_tbl[uv][b3][b4]);
736 * The do_decomp() function finds out a matching decomposition if any
737 * and return. If there is no match, the input bytes are copied and returned.
738 * The function also checks if there is a Hangul, decomposes it if necessary
741 * To save time, a single byte 7-bit ASCII character should be handled by
744 * The function returns the number of bytes returned sans always terminating
745 * the null byte. It will also return a state that will tell if there was
746 * a Hangul character decomposed which then will be used by the caller.
749 do_decomp(size_t uv, uchar_t *u8s, uchar_t *s, int sz,
750 boolean_t canonical_decomposition, u8_normalization_states_t *state)
767 } else if (sz == 3) {
768 /* Convert it to a Unicode scalar value. */
769 U8_PUT_3BYTES_INTO_UTF32(u1, s[0], s[1], s[2]);
772 * If this is a Hangul syllable, we decompose it into
773 * a leading consonant, a vowel, and an optional trailing
774 * consonant and then return.
776 if (U8_HANGUL_SYLLABLE(u1)) {
777 u1 -= U8_HANGUL_SYL_FIRST;
779 b1 = U8_HANGUL_JAMO_L_FIRST + u1 / U8_HANGUL_VT_COUNT;
780 b2 = U8_HANGUL_JAMO_V_FIRST + (u1 % U8_HANGUL_VT_COUNT)
782 b3 = u1 % U8_HANGUL_T_COUNT;
784 U8_SAVE_HANGUL_AS_UTF8(u8s, 0, 1, 2, b1);
785 U8_SAVE_HANGUL_AS_UTF8(u8s, 3, 4, 5, b2);
787 b3 += U8_HANGUL_JAMO_T_FIRST;
788 U8_SAVE_HANGUL_AS_UTF8(u8s, 6, 7, 8, b3);
791 *state = U8_STATE_HANGUL_LVT;
796 *state = U8_STATE_HANGUL_LV;
806 * If this is a Hangul Jamo, we know there is nothing
807 * further that we can decompose.
809 if (U8_HANGUL_JAMO_L(u1)) {
810 *state = U8_STATE_HANGUL_L;
814 if (U8_HANGUL_JAMO_V(u1)) {
815 if (*state == U8_STATE_HANGUL_L)
816 *state = U8_STATE_HANGUL_LV;
818 *state = U8_STATE_HANGUL_V;
822 if (U8_HANGUL_JAMO_T(u1)) {
823 if (*state == U8_STATE_HANGUL_LV)
824 *state = U8_STATE_HANGUL_LVT;
826 *state = U8_STATE_HANGUL_T;
829 } else if (sz == 4) {
837 * This is a fallback and should not happen if the function
838 * was called properly.
842 *state = U8_STATE_START;
847 * At this point, this rountine does not know what it would get.
848 * The caller should sort it out if the state isn't a Hangul one.
850 *state = U8_STATE_START;
852 /* Try to find matching decomposition mapping byte sequence. */
853 b1 = u8_common_b1_tbl[uv][b1];
854 if (b1 == U8_TBL_ELEMENT_NOT_DEF)
857 b2 = u8_decomp_b2_tbl[uv][b1][b2];
858 if (b2 == U8_TBL_ELEMENT_NOT_DEF)
861 b3_tbl = u8_decomp_b3_tbl[uv][b2][b3].tbl_id;
862 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
866 * If b3_tbl is bigger than or equal to U8_16BIT_TABLE_INDICATOR
867 * which is 0x8000, this means we couldn't fit the mappings into
868 * the cardinality of a unsigned byte.
870 if (b3_tbl >= U8_16BIT_TABLE_INDICATOR) {
871 b3_tbl -= U8_16BIT_TABLE_INDICATOR;
872 start_id = u8_decomp_b4_16bit_tbl[uv][b3_tbl][b4];
873 end_id = u8_decomp_b4_16bit_tbl[uv][b3_tbl][b4 + 1];
875 start_id = u8_decomp_b4_tbl[uv][b3_tbl][b4];
876 end_id = u8_decomp_b4_tbl[uv][b3_tbl][b4 + 1];
879 /* This also means there wasn't any matching decomposition. */
880 if (start_id >= end_id)
884 * The final table for decomposition mappings has three types of
885 * byte sequences depending on whether a mapping is for compatibility
886 * decomposition, canonical decomposition, or both like the following:
888 * (1) Compatibility decomposition mappings:
890 * +---+---+-...-+---+
891 * | B0| B1| ... | Bm|
892 * +---+---+-...-+---+
894 * The first byte, B0, is always less then 0xF5 (U8_DECOMP_BOTH).
896 * (2) Canonical decomposition mappings:
898 * +---+---+---+-...-+---+
899 * | T | b0| b1| ... | bn|
900 * +---+---+---+-...-+---+
902 * where the first byte, T, is 0xF6 (U8_DECOMP_CANONICAL).
906 * +---+---+---+---+-...-+---+---+---+-...-+---+
907 * | T | D | b0| b1| ... | bn| B0| B1| ... | Bm|
908 * +---+---+---+---+-...-+---+---+---+-...-+---+
910 * where T is 0xF5 (U8_DECOMP_BOTH) and D is a displacement
911 * byte, b0 to bn are canonical mapping bytes and B0 to Bm are
912 * compatibility mapping bytes.
914 * Note that compatibility decomposition means doing recursive
915 * decompositions using both compatibility decomposition mappings and
916 * canonical decomposition mappings. On the other hand, canonical
917 * decomposition means doing recursive decompositions using only
918 * canonical decomposition mappings. Since the table we have has gone
919 * through the recursions already, we do not need to do so during
920 * runtime, i.e., the table has been completely flattened out
924 b3_base = u8_decomp_b3_tbl[uv][b2][b3].base;
926 /* Get the type, T, of the byte sequence. */
927 b1 = u8_decomp_final_tbl[uv][b3_base + start_id];
930 * If necessary, adjust start_id, end_id, or both. Note that if
931 * this is compatibility decomposition mapping, there is no
934 if (canonical_decomposition) {
935 /* Is the mapping only for compatibility decomposition? */
936 if (b1 < U8_DECOMP_BOTH)
941 if (b1 == U8_DECOMP_BOTH) {
943 u8_decomp_final_tbl[uv][b3_base + start_id];
948 * Unless this is a compatibility decomposition mapping,
949 * we adjust the start_id.
951 if (b1 == U8_DECOMP_BOTH) {
953 start_id += u8_decomp_final_tbl[uv][b3_base + start_id];
954 } else if (b1 == U8_DECOMP_CANONICAL) {
959 for (i = 0; start_id < end_id; start_id++)
960 u8s[i++] = u8_decomp_final_tbl[uv][b3_base + start_id];
967 * The find_composition_start() function uses the character bytes given and
968 * find out the matching composition mappings if any and return the address
969 * to the composition mappings as explained in the do_composition().
972 find_composition_start(size_t uv, uchar_t *s, size_t sz)
985 } else if (sz == 2) {
988 } else if (sz == 3) {
992 } else if (sz == 4) {
999 * This is a fallback and should not happen if the function
1000 * was called properly.
1005 b1 = u8_composition_b1_tbl[uv][b1];
1006 if (b1 == U8_TBL_ELEMENT_NOT_DEF)
1009 b2 = u8_composition_b2_tbl[uv][b1][b2];
1010 if (b2 == U8_TBL_ELEMENT_NOT_DEF)
1013 b3_tbl = u8_composition_b3_tbl[uv][b2][b3].tbl_id;
1014 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
1017 if (b3_tbl >= U8_16BIT_TABLE_INDICATOR) {
1018 b3_tbl -= U8_16BIT_TABLE_INDICATOR;
1019 start_id = u8_composition_b4_16bit_tbl[uv][b3_tbl][b4];
1020 end_id = u8_composition_b4_16bit_tbl[uv][b3_tbl][b4 + 1];
1022 start_id = u8_composition_b4_tbl[uv][b3_tbl][b4];
1023 end_id = u8_composition_b4_tbl[uv][b3_tbl][b4 + 1];
1026 if (start_id >= end_id)
1029 b3_base = u8_composition_b3_tbl[uv][b2][b3].base;
1031 return ((uchar_t *)&(u8_composition_final_tbl[uv][b3_base + start_id]));
1035 * The blocked() function checks on the combining class values of previous
1036 * characters in this sequence and return whether it is blocked or not.
1039 blocked(uchar_t *comb_class, size_t last)
1041 uchar_t my_comb_class;
1044 my_comb_class = comb_class[last];
1045 for (i = 1; i < last; i++)
1046 if (comb_class[i] >= my_comb_class ||
1047 comb_class[i] == U8_COMBINING_CLASS_STARTER)
1054 * The do_composition() reads the character string pointed by 's' and
1055 * do necessary canonical composition and then copy over the result back to
1058 * The input argument 's' cannot contain more than 32 characters.
1061 do_composition(size_t uv, uchar_t *s, uchar_t *comb_class, uchar_t *start,
1062 uchar_t *disp, size_t last, uchar_t **os, uchar_t *oslast)
1064 uchar_t t[U8_STREAM_SAFE_TEXT_MAX + 1];
1065 uchar_t tc[U8_MB_CUR_MAX];
1066 uint8_t saved_marks[U8_MAX_CHARS_A_SEQ];
1067 size_t saved_marks_count;
1081 boolean_t match_not_found = B_TRUE;
1084 * This should never happen unless the callers are doing some strange
1085 * and unexpected things.
1087 * The "last" is the index pointing to the last character not last + 1.
1089 if (last >= U8_MAX_CHARS_A_SEQ)
1090 last = U8_UPPER_LIMIT_IN_A_SEQ;
1092 for (i = l = 0; i <= last; i++) {
1094 * The last or any non-Starters at the beginning, we don't
1095 * have any chance to do composition and so we just copy them
1096 * to the temporary buffer.
1098 if (i >= last || comb_class[i] != U8_COMBINING_CLASS_STARTER) {
1102 for (k = 0; k < size; k++)
1108 * If this could be a start of Hangul Jamos, then, we try to
1111 if (s[start[i]] == U8_HANGUL_JAMO_1ST_BYTE) {
1112 U8_PUT_3BYTES_INTO_UTF32(u1, s[start[i]],
1113 s[start[i] + 1], s[start[i] + 2]);
1114 U8_PUT_3BYTES_INTO_UTF32(u2, s[start[i] + 3],
1115 s[start[i] + 4], s[start[i] + 5]);
1117 if (U8_HANGUL_JAMO_L(u1) && U8_HANGUL_JAMO_V(u2)) {
1118 u1 -= U8_HANGUL_JAMO_L_FIRST;
1119 u2 -= U8_HANGUL_JAMO_V_FIRST;
1120 u1 = U8_HANGUL_SYL_FIRST +
1121 (u1 * U8_HANGUL_V_COUNT + u2) *
1126 U8_PUT_3BYTES_INTO_UTF32(u2,
1127 s[start[i]], s[start[i] + 1],
1130 if (U8_HANGUL_JAMO_T(u2)) {
1132 U8_HANGUL_JAMO_T_FIRST;
1137 U8_SAVE_HANGUL_AS_UTF8(t + l, 0, 1, 2, u1);
1145 * Let's then find out if this Starter has composition
1148 p = find_composition_start(uv, s + start[i], disp[i]);
1153 * We have a Starter with composition mapping and the next
1154 * character is a non-Starter. Let's try to find out if
1155 * we can do composition.
1161 saved_marks_count = 0;
1168 * The next for() loop compares the non-Starter pointed by
1169 * 'q' with the possible (joinable) characters pointed by 'p'.
1171 * The composition final table entry pointed by the 'p'
1172 * looks like the following:
1174 * +---+---+---+-...-+---+---+---+---+-...-+---+---+
1175 * | C | b0| b2| ... | bn| F | B0| B1| ... | Bm| F |
1176 * +---+---+---+-...-+---+---+---+---+-...-+---+---+
1178 * where C is the count byte indicating the number of
1179 * mapping pairs where each pair would be look like
1180 * (b0-bn F, B0-Bm F). The b0-bn are the bytes of the second
1181 * character of a canonical decomposition and the B0-Bm are
1182 * the bytes of a matching composite character. The F is
1183 * a filler byte after each character as the separator.
1186 match_not_found = B_TRUE;
1188 for (C = *p++; C > 0; C--) {
1189 for (k = 0; k < size; p++, k++)
1193 /* Have we found it? */
1194 if (k >= size && *p == U8_TBL_ELEMENT_FILLER) {
1195 match_not_found = B_FALSE;
1199 while (*++p != U8_TBL_ELEMENT_FILLER)
1205 /* We didn't find; skip to the next pair. */
1206 if (*p != U8_TBL_ELEMENT_FILLER)
1207 while (*++p != U8_TBL_ELEMENT_FILLER)
1209 while (*++p != U8_TBL_ELEMENT_FILLER)
1215 * If there was no match, we will need to save the combining
1216 * mark for later appending. After that, if the next one
1217 * is a non-Starter and not blocked, then, we try once
1218 * again to do composition with the next non-Starter.
1220 * If there was no match and this was a Starter, then,
1221 * this is a new start.
1223 * If there was a match and a composition done and we have
1224 * more to check on, then, we retrieve a new composition final
1225 * table entry for the composite and then try to do the
1226 * composition again.
1229 if (match_not_found) {
1230 if (comb_class[i] == U8_COMBINING_CLASS_STARTER) {
1235 saved_marks[saved_marks_count++] = i;
1240 if (blocked(comb_class, i + 1))
1241 saved_marks[saved_marks_count++] = ++i;
1247 goto TRY_THE_NEXT_MARK;
1249 } else if (i < last) {
1250 p = find_composition_start(uv, t + saved_l,
1254 goto TRY_THE_NEXT_MARK;
1259 * There is no more composition possible.
1261 * If there was no composition what so ever then we copy
1262 * over the original Starter and then append any non-Starters
1263 * remaining at the target string sequentially after that.
1267 p = s + start[saved_i];
1268 size = disp[saved_i];
1269 for (j = 0; j < size; j++)
1273 for (k = 0; k < saved_marks_count; k++) {
1274 p = s + start[saved_marks[k]];
1275 size = disp[saved_marks[k]];
1276 for (j = 0; j < size; j++)
1282 * If the last character is a Starter and if we have a character
1283 * (possibly another Starter) that can be turned into a composite,
1284 * we do so and we do so until there is no more of composition
1287 if (comb_class[last] == U8_COMBINING_CLASS_STARTER) {
1289 saved_l = l - disp[last];
1291 while (p < oslast) {
1292 size = u8_number_of_bytes[*p];
1293 if (size <= 1 || (p + size) > oslast)
1298 for (i = 0; i < size; i++)
1301 q = find_composition_start(uv, t + saved_l,
1308 match_not_found = B_TRUE;
1310 for (C = *q++; C > 0; C--) {
1311 for (k = 0; k < size; q++, k++)
1315 if (k >= size && *q == U8_TBL_ELEMENT_FILLER) {
1316 match_not_found = B_FALSE;
1320 while (*++q != U8_TBL_ELEMENT_FILLER) {
1322 * This is practically
1323 * impossible but we don't
1324 * want to take any chances.
1327 U8_STREAM_SAFE_TEXT_MAX) {
1337 if (*q != U8_TBL_ELEMENT_FILLER)
1338 while (*++q != U8_TBL_ELEMENT_FILLER)
1340 while (*++q != U8_TBL_ELEMENT_FILLER)
1345 if (match_not_found) {
1355 * Now we copy over the temporary string to the target string.
1356 * Since composition always reduces the number of characters or
1357 * the number of characters stay, we don't need to worry about
1358 * the buffer overflow here.
1360 for (i = 0; i < l; i++)
1368 * The collect_a_seq() function checks on the given string s, collect
1369 * a sequence of characters at u8s, and return the sequence. While it collects
1370 * a sequence, it also applies case conversion, canonical or compatibility
1371 * decomposition, canonical decomposition, or some or all of them and
1374 * The collected sequence cannot be bigger than 32 characters since if
1375 * it is having more than 31 characters, the sequence will be terminated
1376 * with a U+034F COMBINING GRAPHEME JOINER (CGJ) character and turned into
1377 * a Stream-Safe Text. The collected sequence is always terminated with
1378 * a null byte and the return value is the byte length of the sequence
1379 * including 0. The return value does not include the terminating
1383 collect_a_seq(size_t uv, uchar_t *u8s, uchar_t **source, uchar_t *slast,
1384 boolean_t is_it_toupper,
1385 boolean_t is_it_tolower,
1386 boolean_t canonical_decomposition,
1387 boolean_t compatibility_decomposition,
1388 boolean_t canonical_composition,
1389 int *errno, u8_normalization_states_t *state)
1398 uchar_t comb_class[U8_MAX_CHARS_A_SEQ];
1399 uchar_t disp[U8_MAX_CHARS_A_SEQ];
1400 uchar_t start[U8_MAX_CHARS_A_SEQ];
1401 uchar_t u8t[U8_MB_CUR_MAX];
1402 uchar_t uts[U8_STREAM_SAFE_TEXT_MAX + 1];
1409 * Save the source string pointer which we will return a changed
1410 * pointer if we do processing.
1415 * The following is a fallback for just in case callers are not
1416 * checking the string boundaries before the calling.
1425 * As the first thing, let's collect a character and do case
1426 * conversion if necessary.
1429 sz = u8_number_of_bytes[*s];
1444 u8s[0] = U8_ASCII_TOUPPER(*s);
1445 else if (is_it_tolower)
1446 u8s[0] = U8_ASCII_TOLOWER(*s);
1451 } else if ((s + sz) > slast) {
1454 for (i = 0; s < slast; )
1462 if (is_it_toupper || is_it_tolower) {
1463 i = do_case_conv(uv, u8s, s, sz, is_it_toupper);
1467 for (i = 0; i < sz; )
1474 * And then canonical/compatibility decomposition followed by
1475 * an optional canonical composition. Please be noted that
1476 * canonical composition is done only when a decomposition is
1479 if (canonical_decomposition || compatibility_decomposition) {
1481 *state = U8_STATE_START;
1491 saved_sz = do_decomp(uv, u8s, u8s, sz,
1492 canonical_decomposition, state);
1496 for (i = 0; i < saved_sz; ) {
1497 sz = u8_number_of_bytes[u8s[i]];
1499 comb_class[last] = combining_class(uv,
1509 * Decomposition yields various Hangul related
1510 * states but not on combining marks. We need to
1511 * find out at here by checking on the last
1514 if (*state == U8_STATE_START) {
1515 if (comb_class[last - 1])
1516 *state = U8_STATE_COMBINING_MARK;
1523 sz = u8_number_of_bytes[*s];
1526 * If this is an illegal character, an incomplete
1527 * character, or an 7-bit ASCII Starter character,
1528 * then we have collected a sequence; break and let
1529 * the next call deal with the two cases.
1531 * Note that this is okay only if you are using this
1532 * function with a fixed length string, not on
1533 * a buffer with multiple calls of one chunk at a time.
1537 } else if ((s + sz) > slast) {
1541 * If the previous character was a Hangul Jamo
1542 * and this character is a Hangul Jamo that
1543 * can be conjoined, we collect the Jamo.
1545 if (*s == U8_HANGUL_JAMO_1ST_BYTE) {
1546 U8_PUT_3BYTES_INTO_UTF32(u1,
1547 *s, *(s + 1), *(s + 2));
1549 if (U8_HANGUL_COMPOSABLE_L_V(*state,
1552 *state = U8_STATE_HANGUL_LV;
1553 goto COLLECT_A_HANGUL;
1556 if (U8_HANGUL_COMPOSABLE_LV_T(*state,
1559 *state = U8_STATE_HANGUL_LVT;
1560 goto COLLECT_A_HANGUL;
1565 * Regardless of whatever it was, if this is
1566 * a Starter, we don't collect the character
1567 * since that's a new start and we will deal
1568 * with it at the next time.
1570 i = combining_class(uv, s, sz);
1571 if (i == U8_COMBINING_CLASS_STARTER)
1575 * We know the current character is a combining
1576 * mark. If the previous character wasn't
1577 * a Starter (not Hangul) or a combining mark,
1578 * then, we don't collect this combining mark.
1580 if (*state != U8_STATE_START &&
1581 *state != U8_STATE_COMBINING_MARK)
1584 *state = U8_STATE_COMBINING_MARK;
1587 * If we collected a Starter and combining
1588 * marks up to 30, i.e., total 31 characters,
1589 * then, we terminate this degenerately long
1590 * combining sequence with a U+034F COMBINING
1591 * GRAPHEME JOINER (CGJ) which is 0xCD 0x8F in
1592 * UTF-8 and turn this into a Stream-Safe
1593 * Text. This will be extremely rare but
1596 * The following will also guarantee that
1597 * we are not writing more than 32 characters
1598 * plus a NULL at u8s[].
1600 if (last >= U8_UPPER_LIMIT_IN_A_SEQ) {
1602 *state = U8_STATE_START;
1603 comb_class[last] = 0;
1604 start[last] = saved_sz;
1608 u8s[saved_sz++] = 0xCD;
1609 u8s[saved_sz++] = 0x8F;
1615 * Some combining marks also do decompose into
1616 * another combining mark or marks.
1618 if (*state == U8_STATE_COMBINING_MARK) {
1621 i = do_decomp(uv, uts, s, sz,
1622 canonical_decomposition, state);
1623 for (j = 0; j < i; ) {
1624 sz = u8_number_of_bytes[uts[j]];
1629 start[last] = saved_sz + j;
1634 U8_UPPER_LIMIT_IN_A_SEQ) {
1636 goto TURN_STREAM_SAFE;
1641 *state = U8_STATE_COMBINING_MARK;
1645 for (i = 0; i < sz; i++)
1646 u8s[saved_sz++] = uts[i];
1648 comb_class[last] = i;
1649 start[last] = saved_sz;
1653 for (i = 0; i < sz; i++)
1654 u8s[saved_sz++] = *s++;
1658 * If this is U+0345 COMBINING GREEK
1659 * YPOGEGRAMMENI (0xCD 0x85 in UTF-8), a.k.a.,
1660 * iota subscript, and need to be converted to
1661 * uppercase letter, convert it to U+0399 GREEK
1662 * CAPITAL LETTER IOTA (0xCE 0x99 in UTF-8),
1663 * i.e., convert to capital adscript form as
1664 * specified in the Unicode standard.
1666 * This is the only special case of (ambiguous)
1667 * case conversion at combining marks and
1668 * probably the standard will never have
1669 * anything similar like this in future.
1671 if (is_it_toupper && sz >= 2 &&
1672 u8s[saved_sz - 2] == 0xCD &&
1673 u8s[saved_sz - 1] == 0x85) {
1674 u8s[saved_sz - 2] = 0xCE;
1675 u8s[saved_sz - 1] = 0x99;
1681 * Let's try to ensure a canonical ordering for the collected
1682 * combining marks. We do this only if we have collected
1683 * at least one more non-Starter. (The decomposition mapping
1684 * data tables have fully (and recursively) expanded and
1685 * canonically ordered decompositions.)
1687 * The U8_SWAP_COMB_MARKS() convenience macro has some
1688 * assumptions and we are meeting the assumptions.
1691 if (last >= saved_last) {
1692 for (i = 0; i < last; i++)
1693 for (j = last; j > i; j--)
1694 if (comb_class[j] &&
1695 comb_class[j - 1] > comb_class[j]) {
1696 U8_SWAP_COMB_MARKS(j - 1, j);
1702 if (! canonical_composition) {
1703 u8s[saved_sz] = '\0';
1708 * Now do the canonical composition. Note that we do this
1709 * only after a canonical or compatibility decomposition to
1710 * finish up NFC or NFKC.
1712 sz = do_composition(uv, u8s, comb_class, start, disp, last,
1718 return ((size_t)sz);
1722 * The do_norm_compare() function does string comparion based on Unicode
1723 * simple case mappings and Unicode Normalization definitions.
1725 * It does so by collecting a sequence of character at a time and comparing
1726 * the collected sequences from the strings.
1728 * The meanings on the return values are the same as the usual strcmp().
1731 do_norm_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, size_t n2,
1732 int flag, int *errno)
1737 uchar_t u8s1[U8_STREAM_SAFE_TEXT_MAX + 1];
1738 uchar_t u8s2[U8_STREAM_SAFE_TEXT_MAX + 1];
1741 boolean_t is_it_toupper;
1742 boolean_t is_it_tolower;
1743 boolean_t canonical_decomposition;
1744 boolean_t compatibility_decomposition;
1745 boolean_t canonical_composition;
1746 u8_normalization_states_t state;
1751 is_it_toupper = flag & U8_TEXTPREP_TOUPPER;
1752 is_it_tolower = flag & U8_TEXTPREP_TOLOWER;
1753 canonical_decomposition = flag & U8_CANON_DECOMP;
1754 compatibility_decomposition = flag & U8_COMPAT_DECOMP;
1755 canonical_composition = flag & U8_CANON_COMP;
1757 while (s1 < s1last && s2 < s2last) {
1759 * If the current character is a 7-bit ASCII and the last
1760 * character, or, if the current character and the next
1761 * character are both some 7-bit ASCII characters then
1762 * we treat the current character as a sequence.
1764 * In any other cases, we need to call collect_a_seq().
1767 if (U8_ISASCII(*s1) && ((s1 + 1) >= s1last ||
1768 ((s1 + 1) < s1last && U8_ISASCII(*(s1 + 1))))) {
1770 u8s1[0] = U8_ASCII_TOUPPER(*s1);
1771 else if (is_it_tolower)
1772 u8s1[0] = U8_ASCII_TOLOWER(*s1);
1779 state = U8_STATE_START;
1780 sz1 = collect_a_seq(uv, u8s1, &s1, s1last,
1781 is_it_toupper, is_it_tolower,
1782 canonical_decomposition,
1783 compatibility_decomposition,
1784 canonical_composition, errno, &state);
1787 if (U8_ISASCII(*s2) && ((s2 + 1) >= s2last ||
1788 ((s2 + 1) < s2last && U8_ISASCII(*(s2 + 1))))) {
1790 u8s2[0] = U8_ASCII_TOUPPER(*s2);
1791 else if (is_it_tolower)
1792 u8s2[0] = U8_ASCII_TOLOWER(*s2);
1799 state = U8_STATE_START;
1800 sz2 = collect_a_seq(uv, u8s2, &s2, s2last,
1801 is_it_toupper, is_it_tolower,
1802 canonical_decomposition,
1803 compatibility_decomposition,
1804 canonical_composition, errno, &state);
1808 * Now compare the two characters. If they are the same,
1809 * we move on to the next character sequences.
1811 if (sz1 == 1 && sz2 == 1) {
1817 result = strcmp((const char *)u8s1, (const char *)u8s2);
1824 * We compared until the end of either or both strings.
1826 * If we reached to or went over the ends for the both, that means
1827 * they are the same.
1829 * If we reached only one end, that means the other string has
1830 * something which then can be used to determine the return value.
1841 * The u8_strcmp() function compares two UTF-8 strings quite similar to
1842 * the strcmp(). For the comparison, however, Unicode Normalization specific
1843 * equivalency and Unicode simple case conversion mappings based equivalency
1844 * can be requested and checked against.
1847 u8_strcmp(const char *s1, const char *s2, size_t n, int flag, size_t uv,
1857 * Check on the requested Unicode version, case conversion, and
1858 * normalization flag values.
1861 if (uv > U8_UNICODE_LATEST) {
1863 uv = U8_UNICODE_LATEST;
1867 flag = U8_STRCMP_CS;
1869 f = flag & (U8_STRCMP_CS | U8_STRCMP_CI_UPPER |
1870 U8_STRCMP_CI_LOWER);
1872 flag |= U8_STRCMP_CS;
1873 } else if (f != U8_STRCMP_CS && f != U8_STRCMP_CI_UPPER &&
1874 f != U8_STRCMP_CI_LOWER) {
1876 flag = U8_STRCMP_CS;
1879 f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP);
1880 if (f && f != U8_STRCMP_NFD && f != U8_STRCMP_NFC &&
1881 f != U8_STRCMP_NFKD && f != U8_STRCMP_NFKC) {
1883 flag = U8_STRCMP_CS;
1887 if (flag == U8_STRCMP_CS) {
1888 return (n == 0 ? strcmp(s1, s2) : strncmp(s1, s2, n));
1901 * Simple case conversion can be done much faster and so we do
1902 * them separately here.
1904 if (flag == U8_STRCMP_CI_UPPER) {
1905 return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2,
1906 n1, n2, B_TRUE, errno));
1907 } else if (flag == U8_STRCMP_CI_LOWER) {
1908 return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2,
1909 n1, n2, B_FALSE, errno));
1912 return (do_norm_compare(uv, (uchar_t *)s1, (uchar_t *)s2, n1, n2,
1917 u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen,
1918 int flag, size_t unicode_version, int *errno)
1926 boolean_t do_not_ignore_null;
1927 boolean_t do_not_ignore_invalid;
1928 boolean_t is_it_toupper;
1929 boolean_t is_it_tolower;
1930 boolean_t canonical_decomposition;
1931 boolean_t compatibility_decomposition;
1932 boolean_t canonical_composition;
1936 uchar_t u8s[U8_STREAM_SAFE_TEXT_MAX + 1];
1937 u8_normalization_states_t state;
1939 if (unicode_version > U8_UNICODE_LATEST) {
1941 return ((size_t)-1);
1944 f = flag & (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER);
1945 if (f == (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER)) {
1947 return ((size_t)-1);
1950 f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP);
1951 if (f && f != U8_TEXTPREP_NFD && f != U8_TEXTPREP_NFC &&
1952 f != U8_TEXTPREP_NFKD && f != U8_TEXTPREP_NFKC) {
1954 return ((size_t)-1);
1957 if (inarray == NULL || *inlen == 0)
1960 if (outarray == NULL) {
1962 return ((size_t)-1);
1965 ib = (uchar_t *)inarray;
1966 ob = (uchar_t *)outarray;
1967 ibtail = ib + *inlen;
1968 obtail = ob + *outlen;
1970 do_not_ignore_null = !(flag & U8_TEXTPREP_IGNORE_NULL);
1971 do_not_ignore_invalid = !(flag & U8_TEXTPREP_IGNORE_INVALID);
1972 is_it_toupper = flag & U8_TEXTPREP_TOUPPER;
1973 is_it_tolower = flag & U8_TEXTPREP_TOLOWER;
1978 * If we don't have a normalization flag set, we do the simple case
1979 * conversion based text preparation separately below. Text
1980 * preparation involving Normalization will be done in the false task
1981 * block, again, separately since it will take much more time and
1982 * resource than doing simple case conversions.
1985 while (ib < ibtail) {
1986 if (*ib == '\0' && do_not_ignore_null)
1989 sz = u8_number_of_bytes[*ib];
1992 if (do_not_ignore_invalid) {
1994 ret_val = (size_t)-1;
2005 ret_val = (size_t)-1;
2010 *ob = U8_ASCII_TOUPPER(*ib);
2011 else if (is_it_tolower)
2012 *ob = U8_ASCII_TOLOWER(*ib);
2017 } else if ((ib + sz) > ibtail) {
2018 if (do_not_ignore_invalid) {
2020 ret_val = (size_t)-1;
2024 if ((obtail - ob) < (ibtail - ib)) {
2026 ret_val = (size_t)-1;
2031 * We treat the remaining incomplete character
2032 * bytes as a character.
2039 if (is_it_toupper || is_it_tolower) {
2040 i = do_case_conv(unicode_version, u8s,
2041 ib, sz, is_it_toupper);
2043 if ((obtail - ob) < i) {
2045 ret_val = (size_t)-1;
2051 for (sz = 0; sz < i; sz++)
2054 if ((obtail - ob) < sz) {
2056 ret_val = (size_t)-1;
2060 for (i = 0; i < sz; i++)
2066 canonical_decomposition = flag & U8_CANON_DECOMP;
2067 compatibility_decomposition = flag & U8_COMPAT_DECOMP;
2068 canonical_composition = flag & U8_CANON_COMP;
2070 while (ib < ibtail) {
2071 if (*ib == '\0' && do_not_ignore_null)
2075 * If the current character is a 7-bit ASCII
2076 * character and it is the last character, or,
2077 * if the current character is a 7-bit ASCII
2078 * character and the next character is also a 7-bit
2079 * ASCII character, then, we copy over this
2080 * character without going through collect_a_seq().
2082 * In any other cases, we need to look further with
2083 * the collect_a_seq() function.
2085 if (U8_ISASCII(*ib) && ((ib + 1) >= ibtail ||
2086 ((ib + 1) < ibtail && U8_ISASCII(*(ib + 1))))) {
2089 ret_val = (size_t)-1;
2094 *ob = U8_ASCII_TOUPPER(*ib);
2095 else if (is_it_tolower)
2096 *ob = U8_ASCII_TOLOWER(*ib);
2103 state = U8_STATE_START;
2105 j = collect_a_seq(unicode_version, u8s,
2109 canonical_decomposition,
2110 compatibility_decomposition,
2111 canonical_composition,
2114 if (*errno && do_not_ignore_invalid) {
2115 ret_val = (size_t)-1;
2119 if ((obtail - ob) < j) {
2121 ret_val = (size_t)-1;
2125 for (i = 0; i < j; i++)
2131 *inlen = ibtail - ib;
2132 *outlen = obtail - ob;
2137 #endif /* HAVE_UNICODE */