xref: /linux/fs/nls/nls_iso8859-13.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 /*
2  * linux/fs/nls/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 const 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 const 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 const 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 const 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 const unsigned char *const 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 const 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 const 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 	const 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 	.uni2char	= uni2char,
267 	.char2uni	= char2uni,
268 	.charset2lower	= charset2lower,
269 	.charset2upper	= charset2upper,
270 };
271 
272 static int __init init_nls_iso8859_13(void)
273 {
274 	return register_nls(&table);
275 }
276 
277 static void __exit exit_nls_iso8859_13(void)
278 {
279 	unregister_nls(&table);
280 }
281 
282 module_init(init_nls_iso8859_13)
283 module_exit(exit_nls_iso8859_13)
284 
285 MODULE_DESCRIPTION("NLS ISO 8859-13 (Latin 7; Baltic)");
286 MODULE_LICENSE("Dual BSD/GPL");
287