11 #include <linux/module.h>
12 #include <linux/string.h>
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
18 #include <asm/byteorder.h>
38 {0x80, 0x00, 0*6, 0x7F, 0, },
39 {0xE0, 0xC0, 1*6, 0x7FF, 0x80, },
40 {0xF0, 0xE0, 2*6, 0xFFFF, 0x800, },
41 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, },
42 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, },
43 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, },
47 #define UNICODE_MAX 0x0010ffff
48 #define PLANE_SIZE 0x00010000
50 #define SURROGATE_MASK 0xfffff800
51 #define SURROGATE_PAIR 0x0000d800
52 #define SURROGATE_LOW 0x00000400
53 #define SURROGATE_BITS 0x000003ff
59 const struct utf8_table *
t;
64 for (t = utf8_table; t->
cmask; t++) {
77 c = (*s ^ 0x80) & 0xFF;
90 const struct utf8_table *
t;
100 for (t = utf8_table; t->
cmask && maxout; t++, maxout--) {
104 *s = (
u8) (t->
cval | (l >> c));
108 *s = (
u8) (0x80 | ((l >> c) & 0x3F));
117 static inline void put_utf16(
wchar_t *
s,
unsigned c,
enum utf16_endian endian)
133 wchar_t *pwcs,
int maxout)
140 while (inlen > 0 && maxout > 0 && *s) {
161 put_utf16(op++, u, endian);
165 put_utf16(op++, *s++, endian);
174 static inline unsigned long get_utf16(
unsigned c,
enum utf16_endian endian)
194 while (inlen > 0 && maxout > 0) {
195 u = get_utf16(*pwcs, endian);
208 v = get_utf16(*pwcs, endian);
210 !(v & SURROGATE_LOW)) {
242 spin_lock(&nls_lock);
245 spin_unlock(&nls_lock);
252 spin_unlock(&nls_lock);
260 spin_lock(&nls_lock);
264 spin_unlock(&nls_lock);
269 spin_unlock(&nls_lock);
276 spin_lock(&nls_lock);
277 for (nls = tables; nls; nls = nls->
next) {
283 if (nls && !try_module_get(nls->
owner))
285 spin_unlock(&nls_lock);
297 module_put(nls->
owner);
300 static const wchar_t charset2uni[256] = {
302 0x0000, 0x0001, 0x0002, 0x0003,
303 0x0004, 0x0005, 0x0006, 0x0007,
304 0x0008, 0x0009, 0x000a, 0x000b,
305 0x000c, 0x000d, 0x000e, 0x000f,
307 0x0010, 0x0011, 0x0012, 0x0013,
308 0x0014, 0x0015, 0x0016, 0x0017,
309 0x0018, 0x0019, 0x001a, 0x001b,
310 0x001c, 0x001d, 0x001e, 0x001f,
312 0x0020, 0x0021, 0x0022, 0x0023,
313 0x0024, 0x0025, 0x0026, 0x0027,
314 0x0028, 0x0029, 0x002a, 0x002b,
315 0x002c, 0x002d, 0x002e, 0x002f,
317 0x0030, 0x0031, 0x0032, 0x0033,
318 0x0034, 0x0035, 0x0036, 0x0037,
319 0x0038, 0x0039, 0x003a, 0x003b,
320 0x003c, 0x003d, 0x003e, 0x003f,
322 0x0040, 0x0041, 0x0042, 0x0043,
323 0x0044, 0x0045, 0x0046, 0x0047,
324 0x0048, 0x0049, 0x004a, 0x004b,
325 0x004c, 0x004d, 0x004e, 0x004f,
327 0x0050, 0x0051, 0x0052, 0x0053,
328 0x0054, 0x0055, 0x0056, 0x0057,
329 0x0058, 0x0059, 0x005a, 0x005b,
330 0x005c, 0x005d, 0x005e, 0x005f,
332 0x0060, 0x0061, 0x0062, 0x0063,
333 0x0064, 0x0065, 0x0066, 0x0067,
334 0x0068, 0x0069, 0x006a, 0x006b,
335 0x006c, 0x006d, 0x006e, 0x006f,
337 0x0070, 0x0071, 0x0072, 0x0073,
338 0x0074, 0x0075, 0x0076, 0x0077,
339 0x0078, 0x0079, 0x007a, 0x007b,
340 0x007c, 0x007d, 0x007e, 0x007f,
342 0x0080, 0x0081, 0x0082, 0x0083,
343 0x0084, 0x0085, 0x0086, 0x0087,
344 0x0088, 0x0089, 0x008a, 0x008b,
345 0x008c, 0x008d, 0x008e, 0x008f,
347 0x0090, 0x0091, 0x0092, 0x0093,
348 0x0094, 0x0095, 0x0096, 0x0097,
349 0x0098, 0x0099, 0x009a, 0x009b,
350 0x009c, 0x009d, 0x009e, 0x009f,
352 0x00a0, 0x00a1, 0x00a2, 0x00a3,
353 0x00a4, 0x00a5, 0x00a6, 0x00a7,
354 0x00a8, 0x00a9, 0x00aa, 0x00ab,
355 0x00ac, 0x00ad, 0x00ae, 0x00af,
357 0x00b0, 0x00b1, 0x00b2, 0x00b3,
358 0x00b4, 0x00b5, 0x00b6, 0x00b7,
359 0x00b8, 0x00b9, 0x00ba, 0x00bb,
360 0x00bc, 0x00bd, 0x00be, 0x00bf,
362 0x00c0, 0x00c1, 0x00c2, 0x00c3,
363 0x00c4, 0x00c5, 0x00c6, 0x00c7,
364 0x00c8, 0x00c9, 0x00ca, 0x00cb,
365 0x00cc, 0x00cd, 0x00ce, 0x00cf,
367 0x00d0, 0x00d1, 0x00d2, 0x00d3,
368 0x00d4, 0x00d5, 0x00d6, 0x00d7,
369 0x00d8, 0x00d9, 0x00da, 0x00db,
370 0x00dc, 0x00dd, 0x00de, 0x00df,
372 0x00e0, 0x00e1, 0x00e2, 0x00e3,
373 0x00e4, 0x00e5, 0x00e6, 0x00e7,
374 0x00e8, 0x00e9, 0x00ea, 0x00eb,
375 0x00ec, 0x00ed, 0x00ee, 0x00ef,
377 0x00f0, 0x00f1, 0x00f2, 0x00f3,
378 0x00f4, 0x00f5, 0x00f6, 0x00f7,
379 0x00f8, 0x00f9, 0x00fa, 0x00fb,
380 0x00fc, 0x00fd, 0x00fe, 0x00ff,
383 static const unsigned char page00[256] = {
384 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
385 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
386 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
387 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
388 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
389 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
390 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
391 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
392 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
393 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
394 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
395 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
396 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
397 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
398 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
399 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
401 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
402 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
403 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
404 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
405 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
406 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
407 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
408 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
409 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
410 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
411 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
412 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
413 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
414 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
415 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
416 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
419 static const unsigned char *
const page_uni2charset[256] = {
424 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
425 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
426 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
427 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
428 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
429 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
430 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
431 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
432 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
433 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
434 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
435 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
436 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
437 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
438 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
439 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
441 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
442 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
443 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
444 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
445 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
446 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
447 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
448 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
449 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
450 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
451 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
452 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
453 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
454 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
455 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
456 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
460 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
461 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
462 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
463 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
464 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
465 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
466 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
467 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
468 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
469 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
470 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
471 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
472 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
473 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
474 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
475 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
477 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
478 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
479 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
480 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
481 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
482 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
483 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
484 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
485 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
486 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
487 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
488 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
489 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
490 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
491 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
492 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
496 static int uni2char(
wchar_t uni,
unsigned char *
out,
int boundlen)
498 const unsigned char *uni2charset;
499 unsigned char cl = uni & 0x00ff;
500 unsigned char ch = (uni & 0xff00) >> 8;
505 uni2charset = page_uni2charset[ch];
506 if (uni2charset && uni2charset[cl])
507 out[0] = uni2charset[
cl];
513 static int char2uni(
const unsigned char *rawstring,
int boundlen,
wchar_t *uni)
515 *uni = charset2uni[*rawstring];
521 static struct nls_table default_table = {
522 .charset =
"default",
534 default_nls =
load_nls(CONFIG_NLS_DEFAULT);
535 if (default_nls !=
NULL)
538 return &default_table;