0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/kernel.h>
0010 #include <linux/string.h>
0011 #include <linux/nls.h>
0012 #include <linux/errno.h>
0013
0014 static const wchar_t charset2uni[256] = {
0015
0016 0x0000, 0x0001, 0x0002, 0x0003,
0017 0x0004, 0x0005, 0x0006, 0x0007,
0018 0x0008, 0x0009, 0x000a, 0x000b,
0019 0x000c, 0x000d, 0x000e, 0x000f,
0020
0021 0x0010, 0x0011, 0x0012, 0x0013,
0022 0x0014, 0x0015, 0x0016, 0x0017,
0023 0x0018, 0x0019, 0x001a, 0x001b,
0024 0x001c, 0x001d, 0x001e, 0x001f,
0025
0026 0x0020, 0x0021, 0x0022, 0x0023,
0027 0x0024, 0x0025, 0x0026, 0x0027,
0028 0x0028, 0x0029, 0x002a, 0x002b,
0029 0x002c, 0x002d, 0x002e, 0x002f,
0030
0031 0x0030, 0x0031, 0x0032, 0x0033,
0032 0x0034, 0x0035, 0x0036, 0x0037,
0033 0x0038, 0x0039, 0x003a, 0x003b,
0034 0x003c, 0x003d, 0x003e, 0x003f,
0035
0036 0x0040, 0x0041, 0x0042, 0x0043,
0037 0x0044, 0x0045, 0x0046, 0x0047,
0038 0x0048, 0x0049, 0x004a, 0x004b,
0039 0x004c, 0x004d, 0x004e, 0x004f,
0040
0041 0x0050, 0x0051, 0x0052, 0x0053,
0042 0x0054, 0x0055, 0x0056, 0x0057,
0043 0x0058, 0x0059, 0x005a, 0x005b,
0044 0x005c, 0x005d, 0x005e, 0x005f,
0045
0046 0x0060, 0x0061, 0x0062, 0x0063,
0047 0x0064, 0x0065, 0x0066, 0x0067,
0048 0x0068, 0x0069, 0x006a, 0x006b,
0049 0x006c, 0x006d, 0x006e, 0x006f,
0050
0051 0x0070, 0x0071, 0x0072, 0x0073,
0052 0x0074, 0x0075, 0x0076, 0x0077,
0053 0x0078, 0x0079, 0x007a, 0x007b,
0054 0x007c, 0x007d, 0x007e, 0x007f,
0055
0056 0x0080, 0x0081, 0x0082, 0x0083,
0057 0x0084, 0x0085, 0x0086, 0x0087,
0058 0x0088, 0x0089, 0x008a, 0x008b,
0059 0x008c, 0x008d, 0x008e, 0x008f,
0060
0061 0x0090, 0x0091, 0x0092, 0x0093,
0062 0x0094, 0x0095, 0x0096, 0x0097,
0063 0x0098, 0x0099, 0x009a, 0x009b,
0064 0x009c, 0x009d, 0x009e, 0x009f,
0065
0066 0x00a0, 0x201d, 0x00a2, 0x00a3,
0067 0x00a4, 0x201e, 0x00a6, 0x00a7,
0068 0x00d8, 0x00a9, 0x0156, 0x00ab,
0069 0x00ac, 0x00ad, 0x00ae, 0x00c6,
0070
0071 0x00b0, 0x00b1, 0x00b2, 0x00b3,
0072 0x201c, 0x00b5, 0x00b6, 0x00b7,
0073 0x00f8, 0x00b9, 0x0157, 0x00bb,
0074 0x00bc, 0x00bd, 0x00be, 0x00e6,
0075
0076 0x0104, 0x012e, 0x0100, 0x0106,
0077 0x00c4, 0x00c5, 0x0118, 0x0112,
0078 0x010c, 0x00c9, 0x0179, 0x0116,
0079 0x0122, 0x0136, 0x012a, 0x013b,
0080
0081 0x0160, 0x0143, 0x0145, 0x00d3,
0082 0x014c, 0x00d5, 0x00d6, 0x00d7,
0083 0x0172, 0x0141, 0x015a, 0x016a,
0084 0x00dc, 0x017b, 0x017d, 0x00df,
0085
0086 0x0105, 0x012f, 0x0101, 0x0107,
0087 0x00e4, 0x00e5, 0x0119, 0x0113,
0088 0x010d, 0x00e9, 0x017a, 0x0117,
0089 0x0123, 0x0137, 0x012b, 0x013c,
0090
0091 0x0161, 0x0144, 0x0146, 0x00f3,
0092 0x014d, 0x00f5, 0x00f6, 0x00f7,
0093 0x0173, 0x0142, 0x015b, 0x016b,
0094 0x00fc, 0x017c, 0x017e, 0x2019,
0095 };
0096
0097 static const unsigned char page00[256] = {
0098 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0099 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0100 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0101 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0102 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0103 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0104 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0105 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0106 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0107 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0108 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0109 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0110 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0111 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0112 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0113 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0114
0115 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0116 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0117 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0118 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0119 0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0x00, 0xa6, 0xa7,
0120 0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00,
0121 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7,
0122 0x00, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00,
0123 0x00, 0x00, 0x00, 0x00, 0xc4, 0xc5, 0xaf, 0x00,
0124 0x00, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0125 0x00, 0x00, 0x00, 0xd3, 0x00, 0xd5, 0xd6, 0xd7,
0126 0xa8, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0xdf,
0127 0x00, 0x00, 0x00, 0x00, 0xe4, 0xe5, 0xbf, 0x00,
0128 0x00, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0129 0x00, 0x00, 0x00, 0xf3, 0x00, 0xf5, 0xf6, 0xf7,
0130 0xb8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
0131 };
0132
0133 static const unsigned char page01[256] = {
0134 0xc2, 0xe2, 0x00, 0x00, 0xc0, 0xe0, 0xc3, 0xe3,
0135 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00,
0136 0x00, 0x00, 0xc7, 0xe7, 0x00, 0x00, 0xcb, 0xeb,
0137 0xc6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0138 0x00, 0x00, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00,
0139 0x00, 0x00, 0xce, 0xee, 0x00, 0x00, 0xc1, 0xe1,
0140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xed,
0141 0x00, 0x00, 0x00, 0xcf, 0xef, 0x00, 0x00, 0x00,
0142 0x00, 0xd9, 0xf9, 0xd1, 0xf1, 0xd2, 0xf2, 0x00,
0143 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf4, 0x00, 0x00,
0144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xba,
0145 0x00, 0x00, 0xda, 0xfa, 0x00, 0x00, 0x00, 0x00,
0146 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0147 0x00, 0x00, 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00,
0148 0x00, 0x00, 0xd8, 0xf8, 0x00, 0x00, 0x00, 0x00,
0149 0x00, 0xca, 0xea, 0xdd, 0xfd, 0xde, 0xfe, 0x00,
0150 };
0151
0152 static const unsigned char page20[256] = {
0153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0156 0x00, 0xff, 0x00, 0x00, 0xb4, 0xa1, 0xa5, 0x00,
0157 };
0158
0159 static const unsigned char *const page_uni2charset[256] = {
0160 page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
0161 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0162 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0163 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0164 page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0165 };
0166
0167 static const unsigned char charset2lower[256] = {
0168 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0169 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0170 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0171 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0172 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0173 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0174 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0175 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0176 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0177 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0178 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0179 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0180 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0181 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0182 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0183 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0184
0185 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0186 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0187 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0188 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0189 0xa0, 0xb1, 0xa2, 0xb3, 0xa4, 0xb5, 0xb6, 0xa7,
0190 0xa8, 0xb9, 0xba, 0xbb, 0xbc, 0xad, 0xbe, 0xaf,
0191 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0192 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbf, 0xbe, 0xbf,
0193 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0194 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0195 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7,
0196 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf,
0197 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0198 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0199 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0200 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0201 };
0202
0203 static const unsigned char charset2upper[256] = {
0204 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0205 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0206 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0207 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0208 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0209 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0210 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0211 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0212 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0213 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0214 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0215 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0216 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0217 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0218 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0219 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0220
0221 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0222 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0223 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0224 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0225 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0226 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0227 0xb0, 0xa1, 0xb2, 0xa3, 0xb4, 0xa5, 0xa6, 0xb7,
0228 0xb8, 0xa9, 0xaa, 0xab, 0xac, 0xbd, 0xae, 0xbd,
0229 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0230 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0231 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0232 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0233 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0234 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0235 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7,
0236 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xff,
0237 };
0238
0239 static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
0240 {
0241 const unsigned char *uni2charset;
0242 unsigned char cl = uni & 0x00ff;
0243 unsigned char ch = (uni & 0xff00) >> 8;
0244
0245 if (boundlen <= 0)
0246 return -ENAMETOOLONG;
0247
0248 uni2charset = page_uni2charset[ch];
0249 if (uni2charset && uni2charset[cl])
0250 out[0] = uni2charset[cl];
0251 else
0252 return -EINVAL;
0253 return 1;
0254 }
0255
0256 static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
0257 {
0258 *uni = charset2uni[*rawstring];
0259 if (*uni == 0x0000)
0260 return -EINVAL;
0261 return 1;
0262 }
0263
0264 static struct nls_table table = {
0265 .charset = "iso8859-13",
0266 .uni2char = uni2char,
0267 .char2uni = char2uni,
0268 .charset2lower = charset2lower,
0269 .charset2upper = charset2upper,
0270 };
0271
0272 static int __init init_nls_iso8859_13(void)
0273 {
0274 return register_nls(&table);
0275 }
0276
0277 static void __exit exit_nls_iso8859_13(void)
0278 {
0279 unregister_nls(&table);
0280 }
0281
0282 module_init(init_nls_iso8859_13)
0283 module_exit(exit_nls_iso8859_13)
0284
0285 MODULE_LICENSE("Dual BSD/GPL");