1
2
3
4
5
6
7
8
9
10#include <linux/module.h>
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/nls.h>
14#include <linux/errno.h>
15
16static const wchar_t charset2uni[256] = {
17
18 0x0000, 0x0001, 0x0002, 0x0003,
19 0x0004, 0x0005, 0x0006, 0x0007,
20 0x0008, 0x0009, 0x000a, 0x000b,
21 0x000c, 0x000d, 0x000e, 0x000f,
22
23 0x0010, 0x0011, 0x0012, 0x0013,
24 0x0014, 0x0015, 0x0016, 0x0017,
25 0x0018, 0x0019, 0x001a, 0x001b,
26 0x001c, 0x001d, 0x001e, 0x001f,
27
28 0x0020, 0x0021, 0x0022, 0x0023,
29 0x0024, 0x0025, 0x0026, 0x0027,
30 0x0028, 0x0029, 0x002a, 0x002b,
31 0x002c, 0x002d, 0x002e, 0x002f,
32
33 0x0030, 0x0031, 0x0032, 0x0033,
34 0x0034, 0x0035, 0x0036, 0x0037,
35 0x0038, 0x0039, 0x003a, 0x003b,
36 0x003c, 0x003d, 0x003e, 0x003f,
37
38 0x0040, 0x0041, 0x0042, 0x0043,
39 0x0044, 0x0045, 0x0046, 0x0047,
40 0x0048, 0x0049, 0x004a, 0x004b,
41 0x004c, 0x004d, 0x004e, 0x004f,
42
43 0x0050, 0x0051, 0x0052, 0x0053,
44 0x0054, 0x0055, 0x0056, 0x0057,
45 0x0058, 0x0059, 0x005a, 0x005b,
46 0x005c, 0x005d, 0x005e, 0x005f,
47
48 0x0060, 0x0061, 0x0062, 0x0063,
49 0x0064, 0x0065, 0x0066, 0x0067,
50 0x0068, 0x0069, 0x006a, 0x006b,
51 0x006c, 0x006d, 0x006e, 0x006f,
52
53 0x0070, 0x0071, 0x0072, 0x0073,
54 0x0074, 0x0075, 0x0076, 0x0077,
55 0x0078, 0x0079, 0x007a, 0x007b,
56 0x007c, 0x007d, 0x007e, 0x007f,
57
58 0x0080, 0x0081, 0x0082, 0x0083,
59 0x0084, 0x0085, 0x0086, 0x0087,
60 0x0088, 0x0089, 0x008a, 0x008b,
61 0x008c, 0x008d, 0x008e, 0x008f,
62
63 0x0090, 0x0091, 0x0092, 0x0093,
64 0x0094, 0x0095, 0x0096, 0x0097,
65 0x0098, 0x0099, 0x009a, 0x009b,
66 0x009c, 0x009d, 0x009e, 0x009f,
67
68 0x00a0, 0x00a1, 0x00a2, 0x00a3,
69 0x00a4, 0x00a5, 0x00a6, 0x00a7,
70 0x00a8, 0x00a9, 0x00aa, 0x00ab,
71 0x00ac, 0x00ad, 0x00ae, 0x00af,
72
73 0x00b0, 0x00b1, 0x00b2, 0x00b3,
74 0x00b4, 0x00b5, 0x00b6, 0x00b7,
75 0x00b8, 0x00b9, 0x00ba, 0x00bb,
76 0x00bc, 0x00bd, 0x00be, 0x00bf,
77
78 0x00c0, 0x00c1, 0x00c2, 0x00c3,
79 0x00c4, 0x00c5, 0x00c6, 0x00c7,
80 0x00c8, 0x00c9, 0x00ca, 0x00cb,
81 0x00cc, 0x00cd, 0x00ce, 0x00cf,
82
83 0x00d0, 0x00d1, 0x00d2, 0x00d3,
84 0x00d4, 0x00d5, 0x00d6, 0x00d7,
85 0x00d8, 0x00d9, 0x00da, 0x00db,
86 0x00dc, 0x00dd, 0x00de, 0x00df,
87
88 0x00e0, 0x00e1, 0x00e2, 0x00e3,
89 0x00e4, 0x00e5, 0x00e6, 0x00e7,
90 0x00e8, 0x00e9, 0x00ea, 0x00eb,
91 0x00ec, 0x00ed, 0x00ee, 0x00ef,
92
93 0x00f0, 0x00f1, 0x00f2, 0x00f3,
94 0x00f4, 0x00f5, 0x00f6, 0x00f7,
95 0x00f8, 0x00f9, 0x00fa, 0x00fb,
96 0x00fc, 0x00fd, 0x00fe, 0x00ff,
97};
98
99static const unsigned char page00[256] = {
100 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
101 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
102 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
103 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
104 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
105 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
106 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
107 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
108 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
109 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
110 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
111 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
112 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
113 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
114 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
115 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
116
117 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
118 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
119 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
120 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
121 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
122 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
123 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
124 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
125 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
126 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
127 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
128 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
129 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
130 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
131 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
132 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
133};
134
135static const unsigned char *const page_uni2charset[256] = {
136 page00, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
137};
138
139static const unsigned char charset2lower[256] = {
140 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
141 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
142 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
143 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
144 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
145 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
146 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
147 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
148 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
149 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
150 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
151 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
152 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
153 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
154 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
155 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
156
157 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
158 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
159 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
160 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
161 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
162 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
163 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
164 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
165 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
166 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
167 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7,
168 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf,
169 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
170 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
171 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
172 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
173};
174
175static const unsigned char charset2upper[256] = {
176 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
177 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
178 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
179 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
180 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
181 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
182 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
183 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
184 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
185 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
186 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
187 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
188 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
189 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
190 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
191 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
192
193 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
194 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
195 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
196 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
197 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
198 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
199 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0x00, 0xb6, 0xb7,
200 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
201 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
202 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
203 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
204 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
205 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
206 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
207 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7,
208 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00,
209};
210
211static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
212{
213 const unsigned char *uni2charset;
214 unsigned char cl = uni & 0x00ff;
215 unsigned char ch = (uni & 0xff00) >> 8;
216
217 if (boundlen <= 0)
218 return -ENAMETOOLONG;
219
220 uni2charset = page_uni2charset[ch];
221 if (uni2charset && uni2charset[cl])
222 out[0] = uni2charset[cl];
223 else
224 return -EINVAL;
225 return 1;
226}
227
228static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
229{
230 *uni = charset2uni[*rawstring];
231 if (*uni == 0x0000)
232 return -EINVAL;
233 return 1;
234}
235
236static struct nls_table table = {
237 .charset = "iso8859-1",
238 .uni2char = uni2char,
239 .char2uni = char2uni,
240 .charset2lower = charset2lower,
241 .charset2upper = charset2upper,
242};
243
244static int __init init_nls_iso8859_1(void)
245{
246 return register_nls(&table);
247}
248
249static void __exit exit_nls_iso8859_1(void)
250{
251 unregister_nls(&table);
252}
253
254module_init(init_nls_iso8859_1)
255module_exit(exit_nls_iso8859_1)
256
257MODULE_LICENSE("Dual BSD/GPL");
258