Reduce dbuf_find() lock contention
[zfs.git] / module / unicode / u8_textprep.c
blob37d648b2172dea3ac5eecee288de22ccb56d143b
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
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>
39 #include <sys/string.h>
40 #include <sys/param.h>
41 #include <sys/sysmacros.h>
42 #include <sys/debug.h>
43 #include <sys/kmem.h>
44 #include <sys/sunddi.h>
45 #include <sys/u8_textprep.h>
46 #include <sys/byteorder.h>
47 #include <sys/errno.h>
48 #include <sys/u8_textprep_data.h>
49 #include <sys/mod.h>
51 /* The maximum possible number of bytes in a UTF-8 character. */
52 #define U8_MB_CUR_MAX (4)
55 * The maximum number of bytes needed for a UTF-8 character to cover
56 * U+0000 - U+FFFF, i.e., the coding space of now deprecated UCS-2.
58 #define U8_MAX_BYTES_UCS2 (3)
60 /* The maximum possible number of bytes in a Stream-Safe Text. */
61 #define U8_STREAM_SAFE_TEXT_MAX (128)
64 * The maximum number of characters in a combining/conjoining sequence and
65 * the actual upperbound limit of a combining/conjoining sequence.
67 #define U8_MAX_CHARS_A_SEQ (32)
68 #define U8_UPPER_LIMIT_IN_A_SEQ (31)
70 /* The combining class value for Starter. */
71 #define U8_COMBINING_CLASS_STARTER (0)
74 * Some Hangul related macros at below.
76 * The first and the last of Hangul syllables, Hangul Jamo Leading consonants,
77 * Vowels, and optional Trailing consonants in Unicode scalar values.
79 * Please be noted that the U8_HANGUL_JAMO_T_FIRST is 0x11A7 at below not
80 * the actual U+11A8. This is due to that the trailing consonant is optional
81 * and thus we are doing a pre-calculation of subtracting one.
83 * Each of 19 modern leading consonants has total 588 possible syllables since
84 * Hangul has 21 modern vowels and 27 modern trailing consonants plus 1 for
85 * no trailing consonant case, i.e., 21 x 28 = 588.
87 * We also have bunch of Hangul related macros at below. Please bear in mind
88 * that the U8_HANGUL_JAMO_1ST_BYTE can be used to check whether it is
89 * a Hangul Jamo or not but the value does not guarantee that it is a Hangul
90 * Jamo; it just guarantee that it will be most likely.
92 #define U8_HANGUL_SYL_FIRST (0xAC00U)
93 #define U8_HANGUL_SYL_LAST (0xD7A3U)
95 #define U8_HANGUL_JAMO_L_FIRST (0x1100U)
96 #define U8_HANGUL_JAMO_L_LAST (0x1112U)
97 #define U8_HANGUL_JAMO_V_FIRST (0x1161U)
98 #define U8_HANGUL_JAMO_V_LAST (0x1175U)
99 #define U8_HANGUL_JAMO_T_FIRST (0x11A7U)
100 #define U8_HANGUL_JAMO_T_LAST (0x11C2U)
102 #define U8_HANGUL_V_COUNT (21)
103 #define U8_HANGUL_VT_COUNT (588)
104 #define U8_HANGUL_T_COUNT (28)
106 #define U8_HANGUL_JAMO_1ST_BYTE (0xE1U)
108 #define U8_SAVE_HANGUL_AS_UTF8(s, i, j, k, b) \
109 (s)[(i)] = (uchar_t)(0xE0U | ((uint32_t)(b) & 0xF000U) >> 12); \
110 (s)[(j)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x0FC0U) >> 6); \
111 (s)[(k)] = (uchar_t)(0x80U | ((uint32_t)(b) & 0x003FU));
113 #define U8_HANGUL_JAMO_L(u) \
114 ((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_L_LAST)
116 #define U8_HANGUL_JAMO_V(u) \
117 ((u) >= U8_HANGUL_JAMO_V_FIRST && (u) <= U8_HANGUL_JAMO_V_LAST)
119 #define U8_HANGUL_JAMO_T(u) \
120 ((u) > U8_HANGUL_JAMO_T_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
122 #define U8_HANGUL_JAMO(u) \
123 ((u) >= U8_HANGUL_JAMO_L_FIRST && (u) <= U8_HANGUL_JAMO_T_LAST)
125 #define U8_HANGUL_SYLLABLE(u) \
126 ((u) >= U8_HANGUL_SYL_FIRST && (u) <= U8_HANGUL_SYL_LAST)
128 #define U8_HANGUL_COMPOSABLE_L_V(s, u) \
129 ((s) == U8_STATE_HANGUL_L && U8_HANGUL_JAMO_V((u)))
131 #define U8_HANGUL_COMPOSABLE_LV_T(s, u) \
132 ((s) == U8_STATE_HANGUL_LV && U8_HANGUL_JAMO_T((u)))
134 /* The types of decomposition mappings. */
135 #define U8_DECOMP_BOTH (0xF5U)
136 #define U8_DECOMP_CANONICAL (0xF6U)
138 /* The indicator for 16-bit table. */
139 #define U8_16BIT_TABLE_INDICATOR (0x8000U)
141 /* The following are some convenience macros. */
142 #define U8_PUT_3BYTES_INTO_UTF32(u, b1, b2, b3) \
143 (u) = ((((uint32_t)(b1) & 0x0F) << 12) | \
144 (((uint32_t)(b2) & 0x3F) << 6) | \
145 ((uint32_t)(b3) & 0x3F));
147 #define U8_SIMPLE_SWAP(a, b, t) \
148 (t) = (a); \
149 (a) = (b); \
150 (b) = (t);
152 #define U8_ASCII_TOUPPER(c) \
153 (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c))
155 #define U8_ASCII_TOLOWER(c) \
156 (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
158 #define U8_ISASCII(c) (((uchar_t)(c)) < 0x80U)
160 * The following macro assumes that the two characters that are to be
161 * swapped are adjacent to each other and 'a' comes before 'b'.
163 * If the assumptions are not met, then, the macro will fail.
165 #define U8_SWAP_COMB_MARKS(a, b) \
166 for (k = 0; k < disp[(a)]; k++) \
167 u8t[k] = u8s[start[(a)] + k]; \
168 for (k = 0; k < disp[(b)]; k++) \
169 u8s[start[(a)] + k] = u8s[start[(b)] + k]; \
170 start[(b)] = start[(a)] + disp[(b)]; \
171 for (k = 0; k < disp[(a)]; k++) \
172 u8s[start[(b)] + k] = u8t[k]; \
173 U8_SIMPLE_SWAP(comb_class[(a)], comb_class[(b)], tc); \
174 U8_SIMPLE_SWAP(disp[(a)], disp[(b)], tc);
176 /* The possible states during normalization. */
177 typedef enum {
178 U8_STATE_START = 0,
179 U8_STATE_HANGUL_L = 1,
180 U8_STATE_HANGUL_LV = 2,
181 U8_STATE_HANGUL_LVT = 3,
182 U8_STATE_HANGUL_V = 4,
183 U8_STATE_HANGUL_T = 5,
184 U8_STATE_COMBINING_MARK = 6
185 } u8_normalization_states_t;
188 * The three vectors at below are used to check bytes of a given UTF-8
189 * character are valid and not containing any malformed byte values.
191 * We used to have a quite relaxed UTF-8 binary representation but then there
192 * was some security related issues and so the Unicode Consortium defined
193 * and announced the UTF-8 Corrigendum at Unicode 3.1 and then refined it
194 * one more time at the Unicode 3.2. The following three tables are based on
195 * that.
198 #define U8_ILLEGAL_NEXT_BYTE_COMMON(c) ((c) < 0x80 || (c) > 0xBF)
200 #define I_ U8_ILLEGAL_CHAR
201 #define O_ U8_OUT_OF_RANGE_CHAR
203 static const int8_t u8_number_of_bytes[0x100] = {
204 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
205 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
206 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
207 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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,
213 /* 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F */
214 I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
216 /* 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F */
217 I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
219 /* A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF */
220 I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
222 /* B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF */
223 I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_, I_,
225 /* C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF */
226 I_, I_, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
228 /* D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF */
229 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
231 /* E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF */
232 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
234 /* F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF */
235 4, 4, 4, 4, 4, O_, O_, O_, O_, O_, O_, O_, O_, O_, O_, O_,
238 #undef I_
239 #undef O_
241 static const uint8_t u8_valid_min_2nd_byte[0x100] = {
242 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0,
244 0, 0, 0, 0, 0, 0, 0, 0,
245 0, 0, 0, 0, 0, 0, 0, 0,
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 /* C0 C1 C2 C3 C4 C5 C6 C7 */
267 0, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
268 /* C8 C9 CA CB CC CD CE CF */
269 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
270 /* D0 D1 D2 D3 D4 D5 D6 D7 */
271 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
272 /* D8 D9 DA DB DC DD DE DF */
273 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
274 /* E0 E1 E2 E3 E4 E5 E6 E7 */
275 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
276 /* E8 E9 EA EB EC ED EE EF */
277 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
278 /* F0 F1 F2 F3 F4 F5 F6 F7 */
279 0x90, 0x80, 0x80, 0x80, 0x80, 0, 0, 0,
280 0, 0, 0, 0, 0, 0, 0, 0,
283 static const uint8_t u8_valid_max_2nd_byte[0x100] = {
284 0, 0, 0, 0, 0, 0, 0, 0,
285 0, 0, 0, 0, 0, 0, 0, 0,
286 0, 0, 0, 0, 0, 0, 0, 0,
287 0, 0, 0, 0, 0, 0, 0, 0,
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 /* C0 C1 C2 C3 C4 C5 C6 C7 */
309 0, 0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
310 /* C8 C9 CA CB CC CD CE CF */
311 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
312 /* D0 D1 D2 D3 D4 D5 D6 D7 */
313 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
314 /* D8 D9 DA DB DC DD DE DF */
315 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
316 /* E0 E1 E2 E3 E4 E5 E6 E7 */
317 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
318 /* E8 E9 EA EB EC ED EE EF */
319 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x9f, 0xbf, 0xbf,
320 /* F0 F1 F2 F3 F4 F5 F6 F7 */
321 0xbf, 0xbf, 0xbf, 0xbf, 0x8f, 0, 0, 0,
322 0, 0, 0, 0, 0, 0, 0, 0,
327 * The u8_validate() validates on the given UTF-8 character string and
328 * calculate the byte length. It is quite similar to mblen(3C) except that
329 * this will validate against the list of characters if required and
330 * specific to UTF-8 and Unicode.
333 u8_validate(const char *u8str, size_t n, char **list, int flag, int *errnum)
335 uchar_t *ib;
336 uchar_t *ibtail;
337 uchar_t **p;
338 uchar_t *s1;
339 uchar_t *s2;
340 uchar_t f;
341 int sz;
342 size_t i;
343 int ret_val;
344 boolean_t second;
345 boolean_t no_need_to_validate_entire;
346 boolean_t check_additional;
347 boolean_t validate_ucs2_range_only;
349 if (! u8str)
350 return (0);
352 ib = (uchar_t *)u8str;
353 ibtail = ib + n;
355 ret_val = 0;
357 no_need_to_validate_entire = ! (flag & U8_VALIDATE_ENTIRE);
358 check_additional = flag & U8_VALIDATE_CHECK_ADDITIONAL;
359 validate_ucs2_range_only = flag & U8_VALIDATE_UCS2_RANGE;
361 while (ib < ibtail) {
363 * The first byte of a UTF-8 character tells how many
364 * bytes will follow for the character. If the first byte
365 * is an illegal byte value or out of range value, we just
366 * return -1 with an appropriate error number.
368 sz = u8_number_of_bytes[*ib];
369 if (sz == U8_ILLEGAL_CHAR) {
370 *errnum = EILSEQ;
371 return (-1);
374 if (sz == U8_OUT_OF_RANGE_CHAR ||
375 (validate_ucs2_range_only && sz > U8_MAX_BYTES_UCS2)) {
376 *errnum = ERANGE;
377 return (-1);
381 * If we don't have enough bytes to check on, that's also
382 * an error. As you can see, we give illegal byte sequence
383 * checking higher priority then EINVAL cases.
385 if ((ibtail - ib) < sz) {
386 *errnum = EINVAL;
387 return (-1);
390 if (sz == 1) {
391 ib++;
392 ret_val++;
393 } else {
395 * Check on the multi-byte UTF-8 character. For more
396 * details on this, see comment added for the used
397 * data structures at the beginning of the file.
399 f = *ib++;
400 ret_val++;
401 second = B_TRUE;
402 for (i = 1; i < sz; i++) {
403 if (second) {
404 if (*ib < u8_valid_min_2nd_byte[f] ||
405 *ib > u8_valid_max_2nd_byte[f]) {
406 *errnum = EILSEQ;
407 return (-1);
409 second = B_FALSE;
410 } else if (U8_ILLEGAL_NEXT_BYTE_COMMON(*ib)) {
411 *errnum = EILSEQ;
412 return (-1);
414 ib++;
415 ret_val++;
419 if (check_additional) {
420 for (p = (uchar_t **)list, i = 0; p[i]; i++) {
421 s1 = ib - sz;
422 s2 = p[i];
423 while (s1 < ib) {
424 if (*s1 != *s2 || *s2 == '\0')
425 break;
426 s1++;
427 s2++;
430 if (s1 >= ib && *s2 == '\0') {
431 *errnum = EBADF;
432 return (-1);
437 if (no_need_to_validate_entire)
438 break;
441 return (ret_val);
445 * The do_case_conv() looks at the mapping tables and returns found
446 * bytes if any. If not found, the input bytes are returned. The function
447 * always terminate the return bytes with a null character assuming that
448 * there are plenty of room to do so.
450 * The case conversions are simple case conversions mapping a character to
451 * another character as specified in the Unicode data. The byte size of
452 * the mapped character could be different from that of the input character.
454 * The return value is the byte length of the returned character excluding
455 * the terminating null byte.
457 static size_t
458 do_case_conv(int uv, uchar_t *u8s, uchar_t *s, int sz, boolean_t is_it_toupper)
460 size_t i;
461 uint16_t b1 = 0;
462 uint16_t b2 = 0;
463 uint16_t b3 = 0;
464 uint16_t b3_tbl;
465 uint16_t b3_base;
466 uint16_t b4 = 0;
467 size_t start_id;
468 size_t end_id;
471 * At this point, the only possible values for sz are 2, 3, and 4.
472 * The u8s should point to a vector that is well beyond the size of
473 * 5 bytes.
475 if (sz == 2) {
476 b3 = u8s[0] = s[0];
477 b4 = u8s[1] = s[1];
478 } else if (sz == 3) {
479 b2 = u8s[0] = s[0];
480 b3 = u8s[1] = s[1];
481 b4 = u8s[2] = s[2];
482 } else if (sz == 4) {
483 b1 = u8s[0] = s[0];
484 b2 = u8s[1] = s[1];
485 b3 = u8s[2] = s[2];
486 b4 = u8s[3] = s[3];
487 } else {
488 /* This is not possible but just in case as a fallback. */
489 if (is_it_toupper)
490 *u8s = U8_ASCII_TOUPPER(*s);
491 else
492 *u8s = U8_ASCII_TOLOWER(*s);
493 u8s[1] = '\0';
495 return (1);
497 u8s[sz] = '\0';
500 * Let's find out if we have a corresponding character.
502 b1 = u8_common_b1_tbl[uv][b1];
503 if (b1 == U8_TBL_ELEMENT_NOT_DEF)
504 return ((size_t)sz);
506 b2 = u8_case_common_b2_tbl[uv][b1][b2];
507 if (b2 == U8_TBL_ELEMENT_NOT_DEF)
508 return ((size_t)sz);
510 if (is_it_toupper) {
511 b3_tbl = u8_toupper_b3_tbl[uv][b2][b3].tbl_id;
512 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
513 return ((size_t)sz);
515 start_id = u8_toupper_b4_tbl[uv][b3_tbl][b4];
516 end_id = u8_toupper_b4_tbl[uv][b3_tbl][b4 + 1];
518 /* Either there is no match or an error at the table. */
519 if (start_id >= end_id || (end_id - start_id) > U8_MB_CUR_MAX)
520 return ((size_t)sz);
522 b3_base = u8_toupper_b3_tbl[uv][b2][b3].base;
524 for (i = 0; start_id < end_id; start_id++)
525 u8s[i++] = u8_toupper_final_tbl[uv][b3_base + start_id];
526 } else {
527 b3_tbl = u8_tolower_b3_tbl[uv][b2][b3].tbl_id;
528 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
529 return ((size_t)sz);
531 start_id = u8_tolower_b4_tbl[uv][b3_tbl][b4];
532 end_id = u8_tolower_b4_tbl[uv][b3_tbl][b4 + 1];
534 if (start_id >= end_id || (end_id - start_id) > U8_MB_CUR_MAX)
535 return ((size_t)sz);
537 b3_base = u8_tolower_b3_tbl[uv][b2][b3].base;
539 for (i = 0; start_id < end_id; start_id++)
540 u8s[i++] = u8_tolower_final_tbl[uv][b3_base + start_id];
544 * If i is still zero, that means there is no corresponding character.
546 if (i == 0)
547 return ((size_t)sz);
549 u8s[i] = '\0';
551 return (i);
555 * The do_case_compare() function compares the two input strings, s1 and s2,
556 * one character at a time doing case conversions if applicable and return
557 * the comparison result as like strcmp().
559 * Since, in empirical sense, most of text data are 7-bit ASCII characters,
560 * we treat the 7-bit ASCII characters as a special case trying to yield
561 * faster processing time.
563 static int
564 do_case_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1,
565 size_t n2, boolean_t is_it_toupper, int *errnum)
567 int f;
568 int sz1;
569 int sz2;
570 size_t j;
571 size_t i1;
572 size_t i2;
573 uchar_t u8s1[U8_MB_CUR_MAX + 1];
574 uchar_t u8s2[U8_MB_CUR_MAX + 1];
576 i1 = i2 = 0;
577 while (i1 < n1 && i2 < n2) {
579 * Find out what would be the byte length for this UTF-8
580 * character at string s1 and also find out if this is
581 * an illegal start byte or not and if so, issue a proper
582 * error number and yet treat this byte as a character.
584 sz1 = u8_number_of_bytes[*s1];
585 if (sz1 < 0) {
586 *errnum = EILSEQ;
587 sz1 = 1;
591 * For 7-bit ASCII characters mainly, we do a quick case
592 * conversion right at here.
594 * If we don't have enough bytes for this character, issue
595 * an EINVAL error and use what are available.
597 * If we have enough bytes, find out if there is
598 * a corresponding uppercase character and if so, copy over
599 * the bytes for a comparison later. If there is no
600 * corresponding uppercase character, then, use what we have
601 * for the comparison.
603 if (sz1 == 1) {
604 if (is_it_toupper)
605 u8s1[0] = U8_ASCII_TOUPPER(*s1);
606 else
607 u8s1[0] = U8_ASCII_TOLOWER(*s1);
608 s1++;
609 u8s1[1] = '\0';
610 } else if ((i1 + sz1) > n1) {
611 *errnum = EINVAL;
612 for (j = 0; (i1 + j) < n1; )
613 u8s1[j++] = *s1++;
614 u8s1[j] = '\0';
615 } else {
616 (void) do_case_conv(uv, u8s1, s1, sz1, is_it_toupper);
617 s1 += sz1;
620 /* Do the same for the string s2. */
621 sz2 = u8_number_of_bytes[*s2];
622 if (sz2 < 0) {
623 *errnum = EILSEQ;
624 sz2 = 1;
627 if (sz2 == 1) {
628 if (is_it_toupper)
629 u8s2[0] = U8_ASCII_TOUPPER(*s2);
630 else
631 u8s2[0] = U8_ASCII_TOLOWER(*s2);
632 s2++;
633 u8s2[1] = '\0';
634 } else if ((i2 + sz2) > n2) {
635 *errnum = EINVAL;
636 for (j = 0; (i2 + j) < n2; )
637 u8s2[j++] = *s2++;
638 u8s2[j] = '\0';
639 } else {
640 (void) do_case_conv(uv, u8s2, s2, sz2, is_it_toupper);
641 s2 += sz2;
644 /* Now compare the two characters. */
645 if (sz1 == 1 && sz2 == 1) {
646 if (*u8s1 > *u8s2)
647 return (1);
648 if (*u8s1 < *u8s2)
649 return (-1);
650 } else {
651 f = strcmp((const char *)u8s1, (const char *)u8s2);
652 if (f != 0)
653 return (f);
657 * They were the same. Let's move on to the next
658 * characters then.
660 i1 += sz1;
661 i2 += sz2;
665 * We compared until the end of either or both strings.
667 * If we reached to or went over the ends for the both, that means
668 * they are the same.
670 * If we reached only one of the two ends, that means the other string
671 * has something which then the fact can be used to determine
672 * the return value.
674 if (i1 >= n1) {
675 if (i2 >= n2)
676 return (0);
677 return (-1);
679 return (1);
683 * The combining_class() function checks on the given bytes and find out
684 * the corresponding Unicode combining class value. The return value 0 means
685 * it is a Starter. Any illegal UTF-8 character will also be treated as
686 * a Starter.
688 static uchar_t
689 combining_class(size_t uv, uchar_t *s, size_t sz)
691 uint16_t b1 = 0;
692 uint16_t b2 = 0;
693 uint16_t b3 = 0;
694 uint16_t b4 = 0;
696 if (sz == 1 || sz > 4)
697 return (0);
699 if (sz == 2) {
700 b3 = s[0];
701 b4 = s[1];
702 } else if (sz == 3) {
703 b2 = s[0];
704 b3 = s[1];
705 b4 = s[2];
706 } else if (sz == 4) {
707 b1 = s[0];
708 b2 = s[1];
709 b3 = s[2];
710 b4 = s[3];
713 b1 = u8_common_b1_tbl[uv][b1];
714 if (b1 == U8_TBL_ELEMENT_NOT_DEF)
715 return (0);
717 b2 = u8_combining_class_b2_tbl[uv][b1][b2];
718 if (b2 == U8_TBL_ELEMENT_NOT_DEF)
719 return (0);
721 b3 = u8_combining_class_b3_tbl[uv][b2][b3];
722 if (b3 == U8_TBL_ELEMENT_NOT_DEF)
723 return (0);
725 return (u8_combining_class_b4_tbl[uv][b3][b4]);
729 * The do_decomp() function finds out a matching decomposition if any
730 * and return. If there is no match, the input bytes are copied and returned.
731 * The function also checks if there is a Hangul, decomposes it if necessary
732 * and returns.
734 * To save time, a single byte 7-bit ASCII character should be handled by
735 * the caller.
737 * The function returns the number of bytes returned sans always terminating
738 * the null byte. It will also return a state that will tell if there was
739 * a Hangul character decomposed which then will be used by the caller.
741 static size_t
742 do_decomp(size_t uv, uchar_t *u8s, uchar_t *s, int sz,
743 boolean_t canonical_decomposition, u8_normalization_states_t *state)
745 uint16_t b1 = 0;
746 uint16_t b2 = 0;
747 uint16_t b3 = 0;
748 uint16_t b3_tbl;
749 uint16_t b3_base;
750 uint16_t b4 = 0;
751 size_t start_id;
752 size_t end_id;
753 size_t i;
754 uint32_t u1;
756 if (sz == 2) {
757 b3 = u8s[0] = s[0];
758 b4 = u8s[1] = s[1];
759 u8s[2] = '\0';
760 } else if (sz == 3) {
761 /* Convert it to a Unicode scalar value. */
762 U8_PUT_3BYTES_INTO_UTF32(u1, s[0], s[1], s[2]);
765 * If this is a Hangul syllable, we decompose it into
766 * a leading consonant, a vowel, and an optional trailing
767 * consonant and then return.
769 if (U8_HANGUL_SYLLABLE(u1)) {
770 u1 -= U8_HANGUL_SYL_FIRST;
772 b1 = U8_HANGUL_JAMO_L_FIRST + u1 / U8_HANGUL_VT_COUNT;
773 b2 = U8_HANGUL_JAMO_V_FIRST + (u1 % U8_HANGUL_VT_COUNT)
774 / U8_HANGUL_T_COUNT;
775 b3 = u1 % U8_HANGUL_T_COUNT;
777 U8_SAVE_HANGUL_AS_UTF8(u8s, 0, 1, 2, b1);
778 U8_SAVE_HANGUL_AS_UTF8(u8s, 3, 4, 5, b2);
779 if (b3) {
780 b3 += U8_HANGUL_JAMO_T_FIRST;
781 U8_SAVE_HANGUL_AS_UTF8(u8s, 6, 7, 8, b3);
783 u8s[9] = '\0';
784 *state = U8_STATE_HANGUL_LVT;
785 return (9);
788 u8s[6] = '\0';
789 *state = U8_STATE_HANGUL_LV;
790 return (6);
793 b2 = u8s[0] = s[0];
794 b3 = u8s[1] = s[1];
795 b4 = u8s[2] = s[2];
796 u8s[3] = '\0';
799 * If this is a Hangul Jamo, we know there is nothing
800 * further that we can decompose.
802 if (U8_HANGUL_JAMO_L(u1)) {
803 *state = U8_STATE_HANGUL_L;
804 return (3);
807 if (U8_HANGUL_JAMO_V(u1)) {
808 if (*state == U8_STATE_HANGUL_L)
809 *state = U8_STATE_HANGUL_LV;
810 else
811 *state = U8_STATE_HANGUL_V;
812 return (3);
815 if (U8_HANGUL_JAMO_T(u1)) {
816 if (*state == U8_STATE_HANGUL_LV)
817 *state = U8_STATE_HANGUL_LVT;
818 else
819 *state = U8_STATE_HANGUL_T;
820 return (3);
822 } else if (sz == 4) {
823 b1 = u8s[0] = s[0];
824 b2 = u8s[1] = s[1];
825 b3 = u8s[2] = s[2];
826 b4 = u8s[3] = s[3];
827 u8s[4] = '\0';
828 } else {
830 * This is a fallback and should not happen if the function
831 * was called properly.
833 u8s[0] = s[0];
834 u8s[1] = '\0';
835 *state = U8_STATE_START;
836 return (1);
840 * At this point, this routine does not know what it would get.
841 * The caller should sort it out if the state isn't a Hangul one.
843 *state = U8_STATE_START;
845 /* Try to find matching decomposition mapping byte sequence. */
846 b1 = u8_common_b1_tbl[uv][b1];
847 if (b1 == U8_TBL_ELEMENT_NOT_DEF)
848 return ((size_t)sz);
850 b2 = u8_decomp_b2_tbl[uv][b1][b2];
851 if (b2 == U8_TBL_ELEMENT_NOT_DEF)
852 return ((size_t)sz);
854 b3_tbl = u8_decomp_b3_tbl[uv][b2][b3].tbl_id;
855 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
856 return ((size_t)sz);
859 * If b3_tbl is bigger than or equal to U8_16BIT_TABLE_INDICATOR
860 * which is 0x8000, this means we couldn't fit the mappings into
861 * the cardinality of a unsigned byte.
863 if (b3_tbl >= U8_16BIT_TABLE_INDICATOR) {
864 b3_tbl -= U8_16BIT_TABLE_INDICATOR;
865 start_id = u8_decomp_b4_16bit_tbl[uv][b3_tbl][b4];
866 end_id = u8_decomp_b4_16bit_tbl[uv][b3_tbl][b4 + 1];
867 } else {
868 // cppcheck-suppress arrayIndexOutOfBoundsCond
869 start_id = u8_decomp_b4_tbl[uv][b3_tbl][b4];
870 // cppcheck-suppress arrayIndexOutOfBoundsCond
871 end_id = u8_decomp_b4_tbl[uv][b3_tbl][b4 + 1];
874 /* This also means there wasn't any matching decomposition. */
875 if (start_id >= end_id)
876 return ((size_t)sz);
879 * The final table for decomposition mappings has three types of
880 * byte sequences depending on whether a mapping is for compatibility
881 * decomposition, canonical decomposition, or both like the following:
883 * (1) Compatibility decomposition mappings:
885 * +---+---+-...-+---+
886 * | B0| B1| ... | Bm|
887 * +---+---+-...-+---+
889 * The first byte, B0, is always less than 0xF5 (U8_DECOMP_BOTH).
891 * (2) Canonical decomposition mappings:
893 * +---+---+---+-...-+---+
894 * | T | b0| b1| ... | bn|
895 * +---+---+---+-...-+---+
897 * where the first byte, T, is 0xF6 (U8_DECOMP_CANONICAL).
899 * (3) Both mappings:
901 * +---+---+---+---+-...-+---+---+---+-...-+---+
902 * | T | D | b0| b1| ... | bn| B0| B1| ... | Bm|
903 * +---+---+---+---+-...-+---+---+---+-...-+---+
905 * where T is 0xF5 (U8_DECOMP_BOTH) and D is a displacement
906 * byte, b0 to bn are canonical mapping bytes and B0 to Bm are
907 * compatibility mapping bytes.
909 * Note that compatibility decomposition means doing recursive
910 * decompositions using both compatibility decomposition mappings and
911 * canonical decomposition mappings. On the other hand, canonical
912 * decomposition means doing recursive decompositions using only
913 * canonical decomposition mappings. Since the table we have has gone
914 * through the recursions already, we do not need to do so during
915 * runtime, i.e., the table has been completely flattened out
916 * already.
919 b3_base = u8_decomp_b3_tbl[uv][b2][b3].base;
921 /* Get the type, T, of the byte sequence. */
922 b1 = u8_decomp_final_tbl[uv][b3_base + start_id];
925 * If necessary, adjust start_id, end_id, or both. Note that if
926 * this is compatibility decomposition mapping, there is no
927 * adjustment.
929 if (canonical_decomposition) {
930 /* Is the mapping only for compatibility decomposition? */
931 if (b1 < U8_DECOMP_BOTH)
932 return ((size_t)sz);
934 start_id++;
936 if (b1 == U8_DECOMP_BOTH) {
937 end_id = start_id +
938 u8_decomp_final_tbl[uv][b3_base + start_id];
939 start_id++;
941 } else {
943 * Unless this is a compatibility decomposition mapping,
944 * we adjust the start_id.
946 if (b1 == U8_DECOMP_BOTH) {
947 start_id++;
948 start_id += u8_decomp_final_tbl[uv][b3_base + start_id];
949 } else if (b1 == U8_DECOMP_CANONICAL) {
950 start_id++;
954 for (i = 0; start_id < end_id; start_id++)
955 u8s[i++] = u8_decomp_final_tbl[uv][b3_base + start_id];
956 u8s[i] = '\0';
958 return (i);
962 * The find_composition_start() function uses the character bytes given and
963 * find out the matching composition mappings if any and return the address
964 * to the composition mappings as explained in the do_composition().
966 static uchar_t *
967 find_composition_start(size_t uv, uchar_t *s, size_t sz)
969 uint16_t b1 = 0;
970 uint16_t b2 = 0;
971 uint16_t b3 = 0;
972 uint16_t b3_tbl;
973 uint16_t b3_base;
974 uint16_t b4 = 0;
975 size_t start_id;
976 size_t end_id;
978 if (sz == 1) {
979 b4 = s[0];
980 } else if (sz == 2) {
981 b3 = s[0];
982 b4 = s[1];
983 } else if (sz == 3) {
984 b2 = s[0];
985 b3 = s[1];
986 b4 = s[2];
987 } else if (sz == 4) {
988 b1 = s[0];
989 b2 = s[1];
990 b3 = s[2];
991 b4 = s[3];
992 } else {
994 * This is a fallback and should not happen if the function
995 * was called properly.
997 return (NULL);
1000 b1 = u8_composition_b1_tbl[uv][b1];
1001 if (b1 == U8_TBL_ELEMENT_NOT_DEF)
1002 return (NULL);
1004 b2 = u8_composition_b2_tbl[uv][b1][b2];
1005 if (b2 == U8_TBL_ELEMENT_NOT_DEF)
1006 return (NULL);
1008 b3_tbl = u8_composition_b3_tbl[uv][b2][b3].tbl_id;
1009 if (b3_tbl == U8_TBL_ELEMENT_NOT_DEF)
1010 return (NULL);
1012 if (b3_tbl >= U8_16BIT_TABLE_INDICATOR) {
1013 b3_tbl -= U8_16BIT_TABLE_INDICATOR;
1014 start_id = u8_composition_b4_16bit_tbl[uv][b3_tbl][b4];
1015 end_id = u8_composition_b4_16bit_tbl[uv][b3_tbl][b4 + 1];
1016 } else {
1017 // cppcheck-suppress arrayIndexOutOfBoundsCond
1018 start_id = u8_composition_b4_tbl[uv][b3_tbl][b4];
1019 // cppcheck-suppress arrayIndexOutOfBoundsCond
1020 end_id = u8_composition_b4_tbl[uv][b3_tbl][b4 + 1];
1023 if (start_id >= end_id)
1024 return (NULL);
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.
1035 static boolean_t
1036 blocked(uchar_t *comb_class, size_t last)
1038 uchar_t my_comb_class;
1039 size_t i;
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)
1045 return (B_TRUE);
1047 return (B_FALSE);
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
1053 * the 's'.
1055 * The input argument 's' cannot contain more than 32 characters.
1057 static size_t
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] = { '\0' };
1063 uint8_t saved_marks[U8_MAX_CHARS_A_SEQ];
1064 size_t saved_marks_count;
1065 uchar_t *p;
1066 uchar_t *saved_p;
1067 uchar_t *q;
1068 size_t i;
1069 size_t saved_i;
1070 size_t j;
1071 size_t k;
1072 size_t l;
1073 size_t C;
1074 size_t saved_l;
1075 size_t size;
1076 uint32_t u1;
1077 uint32_t u2;
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) {
1096 SAVE_THE_CHAR:
1097 p = s + start[i];
1098 size = disp[i];
1099 for (k = 0; k < size; k++)
1100 t[l++] = *p++;
1101 continue;
1105 * If this could be a start of Hangul Jamos, then, we try to
1106 * conjoin them.
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) *
1119 U8_HANGUL_T_COUNT;
1121 i += 2;
1122 if (i <= last) {
1123 U8_PUT_3BYTES_INTO_UTF32(u2,
1124 s[start[i]], s[start[i] + 1],
1125 s[start[i] + 2]);
1127 if (U8_HANGUL_JAMO_T(u2)) {
1128 u1 += u2 -
1129 U8_HANGUL_JAMO_T_FIRST;
1130 i++;
1134 U8_SAVE_HANGUL_AS_UTF8(t + l, 0, 1, 2, u1);
1135 i--;
1136 l += 3;
1137 continue;
1142 * Let's then find out if this Starter has composition
1143 * mapping.
1145 p = find_composition_start(uv, s + start[i], disp[i]);
1146 if (p == NULL)
1147 goto SAVE_THE_CHAR;
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.
1155 saved_p = p;
1156 saved_i = i;
1157 saved_l = l;
1158 saved_marks_count = 0;
1160 TRY_THE_NEXT_MARK:
1161 q = s + start[++i];
1162 size = disp[i];
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++)
1187 if (*p != q[k])
1188 break;
1190 /* Have we found it? */
1191 if (k >= size && *p == U8_TBL_ELEMENT_FILLER) {
1192 match_not_found = B_FALSE;
1194 l = saved_l;
1196 while (*++p != U8_TBL_ELEMENT_FILLER)
1197 t[l++] = *p;
1199 break;
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)
1208 p++;
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) {
1228 i--;
1229 goto SAVE_THE_CHAR;
1232 saved_marks[saved_marks_count++] = i;
1235 if (saved_l == l) {
1236 while (i < last) {
1237 if (blocked(comb_class, i + 1))
1238 saved_marks[saved_marks_count++] = ++i;
1239 else
1240 break;
1242 if (i < last) {
1243 p = saved_p;
1244 goto TRY_THE_NEXT_MARK;
1246 } else if (i < last) {
1247 p = find_composition_start(uv, t + saved_l,
1248 l - saved_l);
1249 if (p != NULL) {
1250 saved_p = p;
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.
1263 if (saved_l == l) {
1264 p = s + start[saved_i];
1265 size = disp[saved_i];
1266 for (j = 0; j < size; j++)
1267 t[l++] = *p++;
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++)
1274 t[l++] = *p++;
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
1282 * possible.
1284 if (comb_class[last] == U8_COMBINING_CLASS_STARTER) {
1285 p = *os;
1286 saved_l = l - disp[last];
1288 while (p < oslast) {
1289 size = u8_number_of_bytes[*p];
1290 if (size <= 1 || (p + size) > oslast)
1291 break;
1293 saved_p = p;
1295 for (i = 0; i < size; i++)
1296 tc[i] = *p++;
1298 q = find_composition_start(uv, t + saved_l,
1299 l - saved_l);
1300 if (q == NULL) {
1301 p = saved_p;
1302 break;
1305 match_not_found = B_TRUE;
1307 for (C = *q++; C > 0; C--) {
1308 for (k = 0; k < size; q++, k++)
1309 if (*q != tc[k])
1310 break;
1312 if (k >= size && *q == U8_TBL_ELEMENT_FILLER) {
1313 match_not_found = B_FALSE;
1315 l = saved_l;
1317 while (*++q != U8_TBL_ELEMENT_FILLER) {
1319 * This is practically
1320 * impossible but we don't
1321 * want to take any chances.
1323 if (l >=
1324 U8_STREAM_SAFE_TEXT_MAX) {
1325 p = saved_p;
1326 goto SAFE_RETURN;
1328 t[l++] = *q;
1331 break;
1334 if (*q != U8_TBL_ELEMENT_FILLER)
1335 while (*++q != U8_TBL_ELEMENT_FILLER)
1337 while (*++q != U8_TBL_ELEMENT_FILLER)
1339 q++;
1342 if (match_not_found) {
1343 p = saved_p;
1344 break;
1347 SAFE_RETURN:
1348 *os = p;
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++)
1358 s[i] = t[i];
1359 s[l] = '\0';
1361 return (l);
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
1369 * in that order.
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
1377 * null byte.
1379 static size_t
1380 collect_a_seq(size_t uv, uchar_t *u8s, uchar_t **source, uchar_t *slast,
1381 boolean_t is_it_toupper, boolean_t is_it_tolower,
1382 boolean_t canonical_decomposition, boolean_t compatibility_decomposition,
1383 boolean_t canonical_composition,
1384 int *errnum, u8_normalization_states_t *state)
1386 uchar_t *s;
1387 int sz;
1388 int saved_sz;
1389 size_t i;
1390 size_t j;
1391 size_t k;
1392 size_t l;
1393 uchar_t comb_class[U8_MAX_CHARS_A_SEQ];
1394 uchar_t disp[U8_MAX_CHARS_A_SEQ];
1395 uchar_t start[U8_MAX_CHARS_A_SEQ];
1396 uchar_t u8t[U8_MB_CUR_MAX] = { '\0' };
1397 uchar_t uts[U8_STREAM_SAFE_TEXT_MAX + 1];
1398 uchar_t tc;
1399 size_t last;
1400 size_t saved_last;
1401 uint32_t u1;
1404 * Save the source string pointer which we will return a changed
1405 * pointer if we do processing.
1407 s = *source;
1410 * The following is a fallback for just in case callers are not
1411 * checking the string boundaries before the calling.
1413 if (s >= slast) {
1414 u8s[0] = '\0';
1416 return (0);
1420 * As the first thing, let's collect a character and do case
1421 * conversion if necessary.
1424 sz = u8_number_of_bytes[*s];
1426 if (sz < 0) {
1427 *errnum = EILSEQ;
1429 u8s[0] = *s++;
1430 u8s[1] = '\0';
1432 *source = s;
1434 return (1);
1437 if (sz == 1) {
1438 if (is_it_toupper)
1439 u8s[0] = U8_ASCII_TOUPPER(*s);
1440 else if (is_it_tolower)
1441 u8s[0] = U8_ASCII_TOLOWER(*s);
1442 else
1443 u8s[0] = *s;
1444 s++;
1445 u8s[1] = '\0';
1446 } else if ((s + sz) > slast) {
1447 *errnum = EINVAL;
1449 for (i = 0; s < slast; )
1450 u8s[i++] = *s++;
1451 u8s[i] = '\0';
1453 *source = s;
1455 return (i);
1456 } else {
1457 if (is_it_toupper || is_it_tolower) {
1458 i = do_case_conv(uv, u8s, s, sz, is_it_toupper);
1459 s += sz;
1460 sz = i;
1461 } else {
1462 for (i = 0; i < sz; )
1463 u8s[i++] = *s++;
1464 u8s[i] = '\0';
1469 * And then canonical/compatibility decomposition followed by
1470 * an optional canonical composition. Please be noted that
1471 * canonical composition is done only when a decomposition is
1472 * done.
1474 if (canonical_decomposition || compatibility_decomposition) {
1475 if (sz == 1) {
1476 *state = U8_STATE_START;
1478 saved_sz = 1;
1480 comb_class[0] = 0;
1481 start[0] = 0;
1482 disp[0] = 1;
1484 last = 1;
1485 } else {
1486 saved_sz = do_decomp(uv, u8s, u8s, sz,
1487 canonical_decomposition, state);
1489 last = 0;
1491 for (i = 0; i < saved_sz; ) {
1492 sz = u8_number_of_bytes[u8s[i]];
1494 comb_class[last] = combining_class(uv,
1495 u8s + i, sz);
1496 start[last] = i;
1497 disp[last] = sz;
1499 last++;
1500 i += sz;
1504 * Decomposition yields various Hangul related
1505 * states but not on combining marks. We need to
1506 * find out at here by checking on the last
1507 * character.
1509 if (*state == U8_STATE_START) {
1510 if (comb_class[last - 1])
1511 *state = U8_STATE_COMBINING_MARK;
1515 saved_last = last;
1517 while (s < slast) {
1518 sz = u8_number_of_bytes[*s];
1521 * If this is an illegal character, an incomplete
1522 * character, or an 7-bit ASCII Starter character,
1523 * then we have collected a sequence; break and let
1524 * the next call deal with the two cases.
1526 * Note that this is okay only if you are using this
1527 * function with a fixed length string, not on
1528 * a buffer with multiple calls of one chunk at a time.
1530 if (sz <= 1) {
1531 break;
1532 } else if ((s + sz) > slast) {
1533 break;
1534 } else {
1536 * If the previous character was a Hangul Jamo
1537 * and this character is a Hangul Jamo that
1538 * can be conjoined, we collect the Jamo.
1540 if (*s == U8_HANGUL_JAMO_1ST_BYTE) {
1541 U8_PUT_3BYTES_INTO_UTF32(u1,
1542 *s, *(s + 1), *(s + 2));
1544 if (U8_HANGUL_COMPOSABLE_L_V(*state,
1545 u1)) {
1546 i = 0;
1547 *state = U8_STATE_HANGUL_LV;
1548 goto COLLECT_A_HANGUL;
1551 if (U8_HANGUL_COMPOSABLE_LV_T(*state,
1552 u1)) {
1553 i = 0;
1554 *state = U8_STATE_HANGUL_LVT;
1555 goto COLLECT_A_HANGUL;
1560 * Regardless of whatever it was, if this is
1561 * a Starter, we don't collect the character
1562 * since that's a new start and we will deal
1563 * with it at the next time.
1565 i = combining_class(uv, s, sz);
1566 if (i == U8_COMBINING_CLASS_STARTER)
1567 break;
1570 * We know the current character is a combining
1571 * mark. If the previous character wasn't
1572 * a Starter (not Hangul) or a combining mark,
1573 * then, we don't collect this combining mark.
1575 if (*state != U8_STATE_START &&
1576 *state != U8_STATE_COMBINING_MARK)
1577 break;
1579 *state = U8_STATE_COMBINING_MARK;
1580 COLLECT_A_HANGUL:
1582 * If we collected a Starter and combining
1583 * marks up to 30, i.e., total 31 characters,
1584 * then, we terminate this degenerately long
1585 * combining sequence with a U+034F COMBINING
1586 * GRAPHEME JOINER (CGJ) which is 0xCD 0x8F in
1587 * UTF-8 and turn this into a Stream-Safe
1588 * Text. This will be extremely rare but
1589 * possible.
1591 * The following will also guarantee that
1592 * we are not writing more than 32 characters
1593 * plus a NULL at u8s[].
1595 if (last >= U8_UPPER_LIMIT_IN_A_SEQ) {
1596 TURN_STREAM_SAFE:
1597 *state = U8_STATE_START;
1598 comb_class[last] = 0;
1599 start[last] = saved_sz;
1600 disp[last] = 2;
1601 last++;
1603 u8s[saved_sz++] = 0xCD;
1604 u8s[saved_sz++] = 0x8F;
1606 break;
1610 * Some combining marks also do decompose into
1611 * another combining mark or marks.
1613 if (*state == U8_STATE_COMBINING_MARK) {
1614 k = last;
1615 l = sz;
1616 i = do_decomp(uv, uts, s, sz,
1617 canonical_decomposition, state);
1618 for (j = 0; j < i; ) {
1619 sz = u8_number_of_bytes[uts[j]];
1621 comb_class[last] =
1622 combining_class(uv,
1623 uts + j, sz);
1624 start[last] = saved_sz + j;
1625 disp[last] = sz;
1627 last++;
1628 if (last >=
1629 U8_UPPER_LIMIT_IN_A_SEQ) {
1630 last = k;
1631 goto TURN_STREAM_SAFE;
1633 j += sz;
1636 *state = U8_STATE_COMBINING_MARK;
1637 sz = i;
1638 s += l;
1640 for (i = 0; i < sz; i++)
1641 u8s[saved_sz++] = uts[i];
1642 } else {
1643 comb_class[last] = i;
1644 start[last] = saved_sz;
1645 disp[last] = sz;
1646 last++;
1648 for (i = 0; i < sz; i++)
1649 u8s[saved_sz++] = *s++;
1653 * If this is U+0345 COMBINING GREEK
1654 * YPOGEGRAMMENI (0xCD 0x85 in UTF-8), a.k.a.,
1655 * iota subscript, and need to be converted to
1656 * uppercase letter, convert it to U+0399 GREEK
1657 * CAPITAL LETTER IOTA (0xCE 0x99 in UTF-8),
1658 * i.e., convert to capital adscript form as
1659 * specified in the Unicode standard.
1661 * This is the only special case of (ambiguous)
1662 * case conversion at combining marks and
1663 * probably the standard will never have
1664 * anything similar like this in future.
1666 if (is_it_toupper && sz >= 2 &&
1667 u8s[saved_sz - 2] == 0xCD &&
1668 u8s[saved_sz - 1] == 0x85) {
1669 u8s[saved_sz - 2] = 0xCE;
1670 u8s[saved_sz - 1] = 0x99;
1676 * Let's try to ensure a canonical ordering for the collected
1677 * combining marks. We do this only if we have collected
1678 * at least one more non-Starter. (The decomposition mapping
1679 * data tables have fully (and recursively) expanded and
1680 * canonically ordered decompositions.)
1682 * The U8_SWAP_COMB_MARKS() convenience macro has some
1683 * assumptions and we are meeting the assumptions.
1685 last--;
1686 if (last >= saved_last) {
1687 for (i = 0; i < last; i++)
1688 for (j = last; j > i; j--)
1689 if (comb_class[j] &&
1690 comb_class[j - 1] > comb_class[j]) {
1691 U8_SWAP_COMB_MARKS(j - 1, j);
1695 *source = s;
1697 if (! canonical_composition) {
1698 u8s[saved_sz] = '\0';
1699 return (saved_sz);
1703 * Now do the canonical composition. Note that we do this
1704 * only after a canonical or compatibility decomposition to
1705 * finish up NFC or NFKC.
1707 sz = do_composition(uv, u8s, comb_class, start, disp, last,
1708 &s, slast);
1711 *source = s;
1713 return ((size_t)sz);
1717 * The do_norm_compare() function does string comparison based on Unicode
1718 * simple case mappings and Unicode Normalization definitions.
1720 * It does so by collecting a sequence of character at a time and comparing
1721 * the collected sequences from the strings.
1723 * The meanings on the return values are the same as the usual strcmp().
1725 static int
1726 do_norm_compare(size_t uv, uchar_t *s1, uchar_t *s2, size_t n1, size_t n2,
1727 int flag, int *errnum)
1729 int result;
1730 size_t sz1;
1731 size_t sz2;
1732 uchar_t u8s1[U8_STREAM_SAFE_TEXT_MAX + 1];
1733 uchar_t u8s2[U8_STREAM_SAFE_TEXT_MAX + 1];
1734 uchar_t *s1last;
1735 uchar_t *s2last;
1736 boolean_t is_it_toupper;
1737 boolean_t is_it_tolower;
1738 boolean_t canonical_decomposition;
1739 boolean_t compatibility_decomposition;
1740 boolean_t canonical_composition;
1741 u8_normalization_states_t state;
1743 s1last = s1 + n1;
1744 s2last = s2 + n2;
1746 is_it_toupper = flag & U8_TEXTPREP_TOUPPER;
1747 is_it_tolower = flag & U8_TEXTPREP_TOLOWER;
1748 canonical_decomposition = flag & U8_CANON_DECOMP;
1749 compatibility_decomposition = flag & U8_COMPAT_DECOMP;
1750 canonical_composition = flag & U8_CANON_COMP;
1752 while (s1 < s1last && s2 < s2last) {
1754 * If the current character is a 7-bit ASCII and the last
1755 * character, or, if the current character and the next
1756 * character are both some 7-bit ASCII characters then
1757 * we treat the current character as a sequence.
1759 * In any other cases, we need to call collect_a_seq().
1762 if (U8_ISASCII(*s1) && ((s1 + 1) >= s1last ||
1763 ((s1 + 1) < s1last && U8_ISASCII(*(s1 + 1))))) {
1764 if (is_it_toupper)
1765 u8s1[0] = U8_ASCII_TOUPPER(*s1);
1766 else if (is_it_tolower)
1767 u8s1[0] = U8_ASCII_TOLOWER(*s1);
1768 else
1769 u8s1[0] = *s1;
1770 u8s1[1] = '\0';
1771 sz1 = 1;
1772 s1++;
1773 } else {
1774 state = U8_STATE_START;
1775 sz1 = collect_a_seq(uv, u8s1, &s1, s1last,
1776 is_it_toupper, is_it_tolower,
1777 canonical_decomposition,
1778 compatibility_decomposition,
1779 canonical_composition, errnum, &state);
1782 if (U8_ISASCII(*s2) && ((s2 + 1) >= s2last ||
1783 ((s2 + 1) < s2last && U8_ISASCII(*(s2 + 1))))) {
1784 if (is_it_toupper)
1785 u8s2[0] = U8_ASCII_TOUPPER(*s2);
1786 else if (is_it_tolower)
1787 u8s2[0] = U8_ASCII_TOLOWER(*s2);
1788 else
1789 u8s2[0] = *s2;
1790 u8s2[1] = '\0';
1791 sz2 = 1;
1792 s2++;
1793 } else {
1794 state = U8_STATE_START;
1795 sz2 = collect_a_seq(uv, u8s2, &s2, s2last,
1796 is_it_toupper, is_it_tolower,
1797 canonical_decomposition,
1798 compatibility_decomposition,
1799 canonical_composition, errnum, &state);
1803 * Now compare the two characters. If they are the same,
1804 * we move on to the next character sequences.
1806 if (sz1 == 1 && sz2 == 1) {
1807 if (*u8s1 > *u8s2)
1808 return (1);
1809 if (*u8s1 < *u8s2)
1810 return (-1);
1811 } else {
1812 result = strcmp((const char *)u8s1, (const char *)u8s2);
1813 if (result != 0)
1814 return (result);
1819 * We compared until the end of either or both strings.
1821 * If we reached to or went over the ends for the both, that means
1822 * they are the same.
1824 * If we reached only one end, that means the other string has
1825 * something which then can be used to determine the return value.
1827 if (s1 >= s1last) {
1828 if (s2 >= s2last)
1829 return (0);
1830 return (-1);
1832 return (1);
1836 * The u8_strcmp() function compares two UTF-8 strings quite similar to
1837 * the strcmp(). For the comparison, however, Unicode Normalization specific
1838 * equivalency and Unicode simple case conversion mappings based equivalency
1839 * can be requested and checked against.
1842 u8_strcmp(const char *s1, const char *s2, size_t n, int flag, size_t uv,
1843 int *errnum)
1845 int f;
1846 size_t n1;
1847 size_t n2;
1849 *errnum = 0;
1852 * Check on the requested Unicode version, case conversion, and
1853 * normalization flag values.
1856 if (uv > U8_UNICODE_LATEST) {
1857 *errnum = ERANGE;
1858 uv = U8_UNICODE_LATEST;
1861 if (flag == 0) {
1862 flag = U8_STRCMP_CS;
1863 } else {
1864 f = flag & (U8_STRCMP_CS | U8_STRCMP_CI_UPPER |
1865 U8_STRCMP_CI_LOWER);
1866 if (f == 0) {
1867 flag |= U8_STRCMP_CS;
1868 } else if (f != U8_STRCMP_CS && f != U8_STRCMP_CI_UPPER &&
1869 f != U8_STRCMP_CI_LOWER) {
1870 *errnum = EBADF;
1871 flag = U8_STRCMP_CS;
1874 f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP);
1875 if (f && f != U8_STRCMP_NFD && f != U8_STRCMP_NFC &&
1876 f != U8_STRCMP_NFKD && f != U8_STRCMP_NFKC) {
1877 *errnum = EBADF;
1878 flag = U8_STRCMP_CS;
1882 if (flag == U8_STRCMP_CS) {
1883 return (n == 0 ? strcmp(s1, s2) : strncmp(s1, s2, n));
1886 n1 = strlen(s1);
1887 n2 = strlen(s2);
1888 if (n != 0) {
1889 if (n < n1)
1890 n1 = n;
1891 if (n < n2)
1892 n2 = n;
1896 * Simple case conversion can be done much faster and so we do
1897 * them separately here.
1899 if (flag == U8_STRCMP_CI_UPPER) {
1900 return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2,
1901 n1, n2, B_TRUE, errnum));
1902 } else if (flag == U8_STRCMP_CI_LOWER) {
1903 return (do_case_compare(uv, (uchar_t *)s1, (uchar_t *)s2,
1904 n1, n2, B_FALSE, errnum));
1907 return (do_norm_compare(uv, (uchar_t *)s1, (uchar_t *)s2, n1, n2,
1908 flag, errnum));
1911 size_t
1912 u8_textprep_str(char *inarray, size_t *inlen, char *outarray, size_t *outlen,
1913 int flag, size_t unicode_version, int *errnum)
1915 int f;
1916 int sz;
1917 uchar_t *ib;
1918 uchar_t *ibtail;
1919 uchar_t *ob;
1920 uchar_t *obtail;
1921 boolean_t do_not_ignore_null;
1922 boolean_t do_not_ignore_invalid;
1923 boolean_t is_it_toupper;
1924 boolean_t is_it_tolower;
1925 boolean_t canonical_decomposition;
1926 boolean_t compatibility_decomposition;
1927 boolean_t canonical_composition;
1928 size_t ret_val;
1929 size_t i;
1930 size_t j;
1931 uchar_t u8s[U8_STREAM_SAFE_TEXT_MAX + 1];
1932 u8_normalization_states_t state;
1934 if (unicode_version > U8_UNICODE_LATEST) {
1935 *errnum = ERANGE;
1936 return ((size_t)-1);
1939 f = flag & (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER);
1940 if (f == (U8_TEXTPREP_TOUPPER | U8_TEXTPREP_TOLOWER)) {
1941 *errnum = EBADF;
1942 return ((size_t)-1);
1945 f = flag & (U8_CANON_DECOMP | U8_COMPAT_DECOMP | U8_CANON_COMP);
1946 if (f && f != U8_TEXTPREP_NFD && f != U8_TEXTPREP_NFC &&
1947 f != U8_TEXTPREP_NFKD && f != U8_TEXTPREP_NFKC) {
1948 *errnum = EBADF;
1949 return ((size_t)-1);
1952 if (inarray == NULL || *inlen == 0)
1953 return (0);
1955 if (outarray == NULL) {
1956 *errnum = E2BIG;
1957 return ((size_t)-1);
1960 ib = (uchar_t *)inarray;
1961 ob = (uchar_t *)outarray;
1962 ibtail = ib + *inlen;
1963 obtail = ob + *outlen;
1965 do_not_ignore_null = !(flag & U8_TEXTPREP_IGNORE_NULL);
1966 do_not_ignore_invalid = !(flag & U8_TEXTPREP_IGNORE_INVALID);
1967 is_it_toupper = flag & U8_TEXTPREP_TOUPPER;
1968 is_it_tolower = flag & U8_TEXTPREP_TOLOWER;
1970 ret_val = 0;
1973 * If we don't have a normalization flag set, we do the simple case
1974 * conversion based text preparation separately below. Text
1975 * preparation involving Normalization will be done in the false task
1976 * block, again, separately since it will take much more time and
1977 * resource than doing simple case conversions.
1979 if (f == 0) {
1980 while (ib < ibtail) {
1981 if (*ib == '\0' && do_not_ignore_null)
1982 break;
1984 sz = u8_number_of_bytes[*ib];
1986 if (sz < 0) {
1987 if (do_not_ignore_invalid) {
1988 *errnum = EILSEQ;
1989 ret_val = (size_t)-1;
1990 break;
1993 sz = 1;
1994 ret_val++;
1997 if (sz == 1) {
1998 if (ob >= obtail) {
1999 *errnum = E2BIG;
2000 ret_val = (size_t)-1;
2001 break;
2004 if (is_it_toupper)
2005 *ob = U8_ASCII_TOUPPER(*ib);
2006 else if (is_it_tolower)
2007 *ob = U8_ASCII_TOLOWER(*ib);
2008 else
2009 *ob = *ib;
2010 ib++;
2011 ob++;
2012 } else if ((ib + sz) > ibtail) {
2013 if (do_not_ignore_invalid) {
2014 *errnum = EINVAL;
2015 ret_val = (size_t)-1;
2016 break;
2019 if ((obtail - ob) < (ibtail - ib)) {
2020 *errnum = E2BIG;
2021 ret_val = (size_t)-1;
2022 break;
2026 * We treat the remaining incomplete character
2027 * bytes as a character.
2029 ret_val++;
2031 while (ib < ibtail)
2032 *ob++ = *ib++;
2033 } else {
2034 if (is_it_toupper || is_it_tolower) {
2035 i = do_case_conv(unicode_version, u8s,
2036 ib, sz, is_it_toupper);
2038 if ((obtail - ob) < i) {
2039 *errnum = E2BIG;
2040 ret_val = (size_t)-1;
2041 break;
2044 ib += sz;
2046 for (sz = 0; sz < i; sz++)
2047 *ob++ = u8s[sz];
2048 } else {
2049 if ((obtail - ob) < sz) {
2050 *errnum = E2BIG;
2051 ret_val = (size_t)-1;
2052 break;
2055 for (i = 0; i < sz; i++)
2056 *ob++ = *ib++;
2060 } else {
2061 canonical_decomposition = flag & U8_CANON_DECOMP;
2062 compatibility_decomposition = flag & U8_COMPAT_DECOMP;
2063 canonical_composition = flag & U8_CANON_COMP;
2065 while (ib < ibtail) {
2066 if (*ib == '\0' && do_not_ignore_null)
2067 break;
2070 * If the current character is a 7-bit ASCII
2071 * character and it is the last character, or,
2072 * if the current character is a 7-bit ASCII
2073 * character and the next character is also a 7-bit
2074 * ASCII character, then, we copy over this
2075 * character without going through collect_a_seq().
2077 * In any other cases, we need to look further with
2078 * the collect_a_seq() function.
2080 if (U8_ISASCII(*ib) && ((ib + 1) >= ibtail ||
2081 ((ib + 1) < ibtail && U8_ISASCII(*(ib + 1))))) {
2082 if (ob >= obtail) {
2083 *errnum = E2BIG;
2084 ret_val = (size_t)-1;
2085 break;
2088 if (is_it_toupper)
2089 *ob = U8_ASCII_TOUPPER(*ib);
2090 else if (is_it_tolower)
2091 *ob = U8_ASCII_TOLOWER(*ib);
2092 else
2093 *ob = *ib;
2094 ib++;
2095 ob++;
2096 } else {
2097 *errnum = 0;
2098 state = U8_STATE_START;
2100 j = collect_a_seq(unicode_version, u8s,
2101 &ib, ibtail,
2102 is_it_toupper,
2103 is_it_tolower,
2104 canonical_decomposition,
2105 compatibility_decomposition,
2106 canonical_composition,
2107 errnum, &state);
2109 if (*errnum && do_not_ignore_invalid) {
2110 ret_val = (size_t)-1;
2111 break;
2114 if ((obtail - ob) < j) {
2115 *errnum = E2BIG;
2116 ret_val = (size_t)-1;
2117 break;
2120 for (i = 0; i < j; i++)
2121 *ob++ = u8s[i];
2126 *inlen = ibtail - ib;
2127 *outlen = obtail - ob;
2129 return (ret_val);
2132 EXPORT_SYMBOL(u8_validate);
2133 EXPORT_SYMBOL(u8_strcmp);
2134 EXPORT_SYMBOL(u8_textprep_str);