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