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