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 0x0452, 0x0402, 0x0453, 0x0403,
0059 0x0451, 0x0401, 0x0454, 0x0404,
0060 0x0455, 0x0405, 0x0456, 0x0406,
0061 0x0457, 0x0407, 0x0458, 0x0408,
0062
0063 0x0459, 0x0409, 0x045a, 0x040a,
0064 0x045b, 0x040b, 0x045c, 0x040c,
0065 0x045e, 0x040e, 0x045f, 0x040f,
0066 0x044e, 0x042e, 0x044a, 0x042a,
0067
0068 0x0430, 0x0410, 0x0431, 0x0411,
0069 0x0446, 0x0426, 0x0434, 0x0414,
0070 0x0435, 0x0415, 0x0444, 0x0424,
0071 0x0433, 0x0413, 0x00ab, 0x00bb,
0072
0073 0x2591, 0x2592, 0x2593, 0x2502,
0074 0x2524, 0x0445, 0x0425, 0x0438,
0075 0x0418, 0x2563, 0x2551, 0x2557,
0076 0x255d, 0x0439, 0x0419, 0x2510,
0077
0078 0x2514, 0x2534, 0x252c, 0x251c,
0079 0x2500, 0x253c, 0x043a, 0x041a,
0080 0x255a, 0x2554, 0x2569, 0x2566,
0081 0x2560, 0x2550, 0x256c, 0x00a4,
0082
0083 0x043b, 0x041b, 0x043c, 0x041c,
0084 0x043d, 0x041d, 0x043e, 0x041e,
0085 0x043f, 0x2518, 0x250c, 0x2588,
0086 0x2584, 0x041f, 0x044f, 0x2580,
0087
0088 0x042f, 0x0440, 0x0420, 0x0441,
0089 0x0421, 0x0442, 0x0422, 0x0443,
0090 0x0423, 0x0436, 0x0416, 0x0432,
0091 0x0412, 0x044c, 0x042c, 0x2116,
0092
0093 0x00ad, 0x044b, 0x042b, 0x0437,
0094 0x0417, 0x0448, 0x0428, 0x044d,
0095 0x042d, 0x0449, 0x0429, 0x0447,
0096 0x0427, 0x00a7, 0x25a0, 0x00a0,
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 0xff, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0xfd,
0122 0x00, 0x00, 0x00, 0xae, 0x00, 0xf0, 0x00, 0x00,
0123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0124 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00,
0125 };
0126
0127 static const unsigned char page04[256] = {
0128 0x00, 0x85, 0x81, 0x83, 0x87, 0x89, 0x8b, 0x8d,
0129 0x8f, 0x91, 0x93, 0x95, 0x97, 0x00, 0x99, 0x9b,
0130 0xa1, 0xa3, 0xec, 0xad, 0xa7, 0xa9, 0xea, 0xf4,
0131 0xb8, 0xbe, 0xc7, 0xd1, 0xd3, 0xd5, 0xd7, 0xdd,
0132 0xe2, 0xe4, 0xe6, 0xe8, 0xab, 0xb6, 0xa5, 0xfc,
0133 0xf6, 0xfa, 0x9f, 0xf2, 0xee, 0xf8, 0x9d, 0xe0,
0134 0xa0, 0xa2, 0xeb, 0xac, 0xa6, 0xa8, 0xe9, 0xf3,
0135 0xb7, 0xbd, 0xc6, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8,
0136 0xe1, 0xe3, 0xe5, 0xe7, 0xaa, 0xb5, 0xa4, 0xfb,
0137 0xf5, 0xf9, 0x9e, 0xf1, 0xed, 0xf7, 0x9c, 0xde,
0138 0x00, 0x84, 0x80, 0x82, 0x86, 0x88, 0x8a, 0x8c,
0139 0x8e, 0x90, 0x92, 0x94, 0x96, 0x00, 0x98, 0x9a,
0140 };
0141
0142 static const unsigned char page21[256] = {
0143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00,
0146 };
0147
0148 static const unsigned char page25[256] = {
0149 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00,
0150 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00,
0151 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
0152 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00,
0153 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
0154 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00,
0155 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00,
0156 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00,
0157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0159 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb,
0160 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00,
0161 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00,
0162 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00,
0163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0165
0166 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00,
0167 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0168 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00,
0169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0170 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0171 };
0172
0173 static const unsigned char *const page_uni2charset[256] = {
0174 page00, NULL, NULL, NULL, page04, NULL, NULL, NULL,
0175 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0176 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0177 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0178 NULL, page21, NULL, NULL, NULL, page25, NULL, NULL,
0179 };
0180
0181 static const unsigned char charset2lower[256] = {
0182 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0183 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0184 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0185 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0186 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0187 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0188 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0189 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0190 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0191 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0192 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0193 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0194 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0195 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0196 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0197 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0198
0199 0x80, 0x80, 0x82, 0x82, 0x84, 0x84, 0x86, 0x86,
0200 0x88, 0x88, 0x8a, 0x8a, 0x8c, 0x8c, 0x8e, 0x8e,
0201 0x90, 0x90, 0x92, 0x92, 0x94, 0x94, 0x96, 0x96,
0202 0x98, 0x98, 0x9a, 0x9a, 0x9c, 0x9c, 0x9e, 0x9e,
0203 0xa0, 0xa0, 0xa2, 0xa2, 0xa4, 0xa4, 0xa6, 0xa6,
0204 0xa8, 0xa8, 0xaa, 0xaa, 0xac, 0xac, 0xae, 0xaf,
0205 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5, 0xb7,
0206 0xb7, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbd, 0xbf,
0207 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6,
0208 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0209 0xd0, 0xd0, 0xd2, 0xd2, 0xd4, 0xd4, 0xd6, 0xd6,
0210 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xd8, 0xde, 0xdf,
0211 0xde, 0xe1, 0xe1, 0xe3, 0xe3, 0xe5, 0xe5, 0xe7,
0212 0xe7, 0xe9, 0xe9, 0xeb, 0xeb, 0xed, 0xed, 0xef,
0213 0xf0, 0xf1, 0xf1, 0xf3, 0xf3, 0xf5, 0xf5, 0xf7,
0214 0xf7, 0xf9, 0xf9, 0xfb, 0xfb, 0xfd, 0xfe, 0xff,
0215 };
0216
0217 static const unsigned char charset2upper[256] = {
0218 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0219 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0220 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0221 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0222 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0223 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0224 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0225 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0226 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0227 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0228 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0229 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0230 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0231 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0232 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0233 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0234
0235 0x81, 0x81, 0x83, 0x83, 0x85, 0x85, 0x87, 0x87,
0236 0x89, 0x89, 0x8b, 0x8b, 0x8d, 0x8d, 0x8f, 0x8f,
0237 0x91, 0x91, 0x93, 0x93, 0x95, 0x95, 0x97, 0x97,
0238 0x99, 0x99, 0x9b, 0x9b, 0x9d, 0x9d, 0x9f, 0x9f,
0239 0xa1, 0xa1, 0xa3, 0xa3, 0xa5, 0xa5, 0xa7, 0xa7,
0240 0xa9, 0xa9, 0xab, 0xab, 0xad, 0xad, 0xae, 0xaf,
0241 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb6, 0xb8,
0242 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbe, 0xbe, 0xbf,
0243 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc7, 0xc7,
0244 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0245 0xd1, 0xd1, 0xd3, 0xd3, 0xd5, 0xd5, 0xd7, 0xd7,
0246 0xdd, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xe0, 0xdf,
0247 0xe0, 0xe2, 0xe2, 0xe4, 0xe4, 0xe6, 0xe6, 0xe8,
0248 0xe8, 0xea, 0xea, 0xec, 0xec, 0xee, 0xee, 0xef,
0249 0xf0, 0xf2, 0xf2, 0xf4, 0xf4, 0xf6, 0xf6, 0xf8,
0250 0xf8, 0xfa, 0xfa, 0xfc, 0xfc, 0xfd, 0xfe, 0xff,
0251 };
0252
0253 static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
0254 {
0255 const unsigned char *uni2charset;
0256 unsigned char cl = uni & 0x00ff;
0257 unsigned char ch = (uni & 0xff00) >> 8;
0258
0259 if (boundlen <= 0)
0260 return -ENAMETOOLONG;
0261
0262 uni2charset = page_uni2charset[ch];
0263 if (uni2charset && uni2charset[cl])
0264 out[0] = uni2charset[cl];
0265 else
0266 return -EINVAL;
0267 return 1;
0268 }
0269
0270 static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
0271 {
0272 *uni = charset2uni[*rawstring];
0273 if (*uni == 0x0000)
0274 return -EINVAL;
0275 return 1;
0276 }
0277
0278 static struct nls_table table = {
0279 .charset = "cp855",
0280 .uni2char = uni2char,
0281 .char2uni = char2uni,
0282 .charset2lower = charset2lower,
0283 .charset2upper = charset2upper,
0284 };
0285
0286 static int __init init_nls_cp855(void)
0287 {
0288 return register_nls(&table);
0289 }
0290
0291 static void __exit exit_nls_cp855(void)
0292 {
0293 unregister_nls(&table);
0294 }
0295
0296 module_init(init_nls_cp855)
0297 module_exit(exit_nls_cp855)
0298
0299 MODULE_LICENSE("Dual BSD/GPL");