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 0x0000, 0x0000, 0x0000, 0x0000,
0059 0x0000, 0x2026, 0x0000, 0x0000,
0060 0x0000, 0x0000, 0x0000, 0x0000,
0061 0x0000, 0x0000, 0x0000, 0x0000,
0062
0063 0x0000, 0x2018, 0x2019, 0x201c,
0064 0x201d, 0x2022, 0x2013, 0x2014,
0065 0x0000, 0x0000, 0x0000, 0x0000,
0066 0x0000, 0x0000, 0x0000, 0x0000,
0067
0068 0x00a0, 0x0e01, 0x0e02, 0x0e03,
0069 0x0e04, 0x0e05, 0x0e06, 0x0e07,
0070 0x0e08, 0x0e09, 0x0e0a, 0x0e0b,
0071 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
0072
0073 0x0e10, 0x0e11, 0x0e12, 0x0e13,
0074 0x0e14, 0x0e15, 0x0e16, 0x0e17,
0075 0x0e18, 0x0e19, 0x0e1a, 0x0e1b,
0076 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,
0077
0078 0x0e20, 0x0e21, 0x0e22, 0x0e23,
0079 0x0e24, 0x0e25, 0x0e26, 0x0e27,
0080 0x0e28, 0x0e29, 0x0e2a, 0x0e2b,
0081 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,
0082
0083 0x0e30, 0x0e31, 0x0e32, 0x0e33,
0084 0x0e34, 0x0e35, 0x0e36, 0x0e37,
0085 0x0e38, 0x0e39, 0x0e3a, 0x0000,
0086 0x0000, 0x0000, 0x0000, 0x0e3f,
0087
0088 0x0e40, 0x0e41, 0x0e42, 0x0e43,
0089 0x0e44, 0x0e45, 0x0e46, 0x0e47,
0090 0x0e48, 0x0e49, 0x0e4a, 0x0e4b,
0091 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,
0092
0093 0x0e50, 0x0e51, 0x0e52, 0x0e53,
0094 0x0e54, 0x0e55, 0x0e56, 0x0e57,
0095 0x0e58, 0x0e59, 0x0e5a, 0x0e5b,
0096 0x0000, 0x0000, 0x0000, 0x0000,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0121 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0122 };
0123
0124 static const unsigned char page0e[256] = {
0125 0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0126 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0127 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0128 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0129 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0130 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0131 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0132 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0xdf,
0133 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0134 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0135 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0136 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0x00, 0x00, 0x00,
0137 };
0138
0139 static const unsigned char page20[256] = {
0140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0142 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00,
0143 0x91, 0x92, 0x00, 0x00, 0x93, 0x94, 0x00, 0x00,
0144 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00,
0145 };
0146
0147 static const unsigned char *const page_uni2charset[256] = {
0148 page00, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0149 NULL, NULL, NULL, NULL, NULL, NULL, page0e, NULL,
0150 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0151 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0152 page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0153 };
0154
0155 static const unsigned char charset2lower[256] = {
0156 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0157 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0158 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0159 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0160 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0161 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0162 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0163 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0164 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0165 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0166 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0167 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0168 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0169 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0170 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0171 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0172
0173 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00,
0174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0175 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0177 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0178 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0179 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0180 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0181 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0182 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0183 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0184 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0xdf,
0185 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0186 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0187 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0188 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0x00, 0x00, 0x00,
0189 };
0190
0191 static const unsigned char charset2upper[256] = {
0192 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0193 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0194 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0195 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0196 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0197 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0198 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0199 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0200 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0201 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0202 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0203 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0204 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0205 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0206 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0207 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0208
0209 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00,
0210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0211 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0213 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0214 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0215 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0216 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0217 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0218 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0219 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0220 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0xdf,
0221 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0222 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0223 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0224 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0x00, 0x00, 0x00,
0225 };
0226
0227 static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
0228 {
0229 const unsigned char *uni2charset;
0230 unsigned char cl = uni & 0x00ff;
0231 unsigned char ch = (uni & 0xff00) >> 8;
0232
0233 if (boundlen <= 0)
0234 return -ENAMETOOLONG;
0235
0236 uni2charset = page_uni2charset[ch];
0237 if (uni2charset && uni2charset[cl])
0238 out[0] = uni2charset[cl];
0239 else
0240 return -EINVAL;
0241 return 1;
0242 }
0243
0244 static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
0245 {
0246 *uni = charset2uni[*rawstring];
0247 if (*uni == 0x0000)
0248 return -EINVAL;
0249 return 1;
0250 }
0251
0252 static struct nls_table table = {
0253 .charset = "cp874",
0254 .alias = "tis-620",
0255 .uni2char = uni2char,
0256 .char2uni = char2uni,
0257 .charset2lower = charset2lower,
0258 .charset2upper = charset2upper,
0259 };
0260
0261 static int __init init_nls_cp874(void)
0262 {
0263 return register_nls(&table);
0264 }
0265
0266 static void __exit exit_nls_cp874(void)
0267 {
0268 unregister_nls(&table);
0269 }
0270
0271 module_init(init_nls_cp874)
0272 module_exit(exit_nls_cp874)
0273
0274 MODULE_LICENSE("Dual BSD/GPL");
0275 MODULE_ALIAS_NLS(tis-620);