diff options
Diffstat (limited to 'fs/nls/nls_koi8-ru.c')
-rw-r--r-- | fs/nls/nls_koi8-ru.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/fs/nls/nls_koi8-ru.c b/fs/nls/nls_koi8-ru.c new file mode 100644 index 000000000000..5db83efe27c6 --- /dev/null +++ b/fs/nls/nls_koi8-ru.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * linux/fs/nls_koi8-ru.c | ||
3 | * | ||
4 | * Charset koi8-ru translation based on charset koi8-u. | ||
5 | * The Unicode to charset table has only exact mappings. | ||
6 | */ | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/string.h> | ||
11 | #include <linux/nls.h> | ||
12 | #include <linux/errno.h> | ||
13 | |||
14 | static struct nls_table *p_nls; | ||
15 | |||
16 | static int uni2char(const wchar_t uni, | ||
17 | unsigned char *out, int boundlen) | ||
18 | { | ||
19 | if (boundlen <= 0) | ||
20 | return -ENAMETOOLONG; | ||
21 | |||
22 | if ((uni & 0xffaf) == 0x040e || (uni & 0xffce) == 0x254c) { | ||
23 | /* koi8-ru and koi8-u differ only on two characters */ | ||
24 | if (uni == 0x040e) | ||
25 | out[0] = 0xbe; | ||
26 | else if (uni == 0x045e) | ||
27 | out[0] = 0xae; | ||
28 | else if (uni == 0x255d || uni == 0x256c) | ||
29 | return 0; | ||
30 | else | ||
31 | return p_nls->uni2char(uni, out, boundlen); | ||
32 | return 1; | ||
33 | } | ||
34 | else | ||
35 | /* fast path */ | ||
36 | return p_nls->uni2char(uni, out, boundlen); | ||
37 | } | ||
38 | |||
39 | static int char2uni(const unsigned char *rawstring, int boundlen, | ||
40 | wchar_t *uni) | ||
41 | { | ||
42 | int n; | ||
43 | |||
44 | if ((*rawstring & 0xef) != 0xae) { | ||
45 | /* koi8-ru and koi8-u differ only on two characters */ | ||
46 | *uni = (*rawstring & 0x10) ? 0x040e : 0x045e; | ||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | n = p_nls->char2uni(rawstring, boundlen, uni); | ||
51 | return n; | ||
52 | } | ||
53 | |||
54 | static struct nls_table table = { | ||
55 | .charset = "koi8-ru", | ||
56 | .uni2char = uni2char, | ||
57 | .char2uni = char2uni, | ||
58 | .owner = THIS_MODULE, | ||
59 | }; | ||
60 | |||
61 | static int __init init_nls_koi8_ru(void) | ||
62 | { | ||
63 | p_nls = load_nls("koi8-u"); | ||
64 | |||
65 | if (p_nls) { | ||
66 | table.charset2upper = p_nls->charset2upper; | ||
67 | table.charset2lower = p_nls->charset2lower; | ||
68 | return register_nls(&table); | ||
69 | } | ||
70 | |||
71 | return -EINVAL; | ||
72 | } | ||
73 | |||
74 | static void __exit exit_nls_koi8_ru(void) | ||
75 | { | ||
76 | unregister_nls(&table); | ||
77 | unload_nls(p_nls); | ||
78 | } | ||
79 | |||
80 | module_init(init_nls_koi8_ru) | ||
81 | module_exit(exit_nls_koi8_ru) | ||
82 | |||
83 | MODULE_LICENSE("Dual BSD/GPL"); | ||