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 0x0106, 0x00fc, 0x00e9, 0x0101,
0059 0x00e4, 0x0123, 0x00e5, 0x0107,
0060 0x0142, 0x0113, 0x0156, 0x0157,
0061 0x012b, 0x0179, 0x00c4, 0x00c5,
0062
0063 0x00c9, 0x00e6, 0x00c6, 0x014d,
0064 0x00f6, 0x0122, 0x00a2, 0x015a,
0065 0x015b, 0x00d6, 0x00dc, 0x00f8,
0066 0x00a3, 0x00d8, 0x00d7, 0x00a4,
0067
0068 0x0100, 0x012a, 0x00f3, 0x017b,
0069 0x017c, 0x017a, 0x201d, 0x00a6,
0070 0x00a9, 0x00ae, 0x00ac, 0x00bd,
0071 0x00bc, 0x0141, 0x00ab, 0x00bb,
0072
0073 0x2591, 0x2592, 0x2593, 0x2502,
0074 0x2524, 0x0104, 0x010c, 0x0118,
0075 0x0116, 0x2563, 0x2551, 0x2557,
0076 0x255d, 0x012e, 0x0160, 0x2510,
0077
0078 0x2514, 0x2534, 0x252c, 0x251c,
0079 0x2500, 0x253c, 0x0172, 0x016a,
0080 0x255a, 0x2554, 0x2569, 0x2566,
0081 0x2560, 0x2550, 0x256c, 0x017d,
0082
0083 0x0105, 0x010d, 0x0119, 0x0117,
0084 0x012f, 0x0161, 0x0173, 0x016b,
0085 0x017e, 0x2518, 0x250c, 0x2588,
0086 0x2584, 0x258c, 0x2590, 0x2580,
0087
0088 0x00d3, 0x00df, 0x014c, 0x0143,
0089 0x00f5, 0x00d5, 0x00b5, 0x0144,
0090 0x0136, 0x0137, 0x013b, 0x013c,
0091 0x0146, 0x0112, 0x0145, 0x2019,
0092
0093 0x00ad, 0x00b1, 0x201c, 0x00be,
0094 0x00b6, 0x00a7, 0x00f7, 0x201e,
0095 0x00b0, 0x2219, 0x00b7, 0x00b9,
0096 0x00b3, 0x00b2, 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, 0x96, 0x9c, 0x9f, 0x00, 0xa7, 0xf5,
0122 0x00, 0xa8, 0x00, 0xae, 0xaa, 0xf0, 0xa9, 0x00,
0123 0xf8, 0xf1, 0xfd, 0xfc, 0x00, 0xe6, 0xf4, 0xfa,
0124 0x00, 0xfb, 0x00, 0xaf, 0xac, 0xab, 0xf3, 0x00,
0125 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x00,
0126 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0127 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe5, 0x99, 0x9e,
0128 0x9d, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0xe1,
0129 0x00, 0x00, 0x00, 0x00, 0x84, 0x86, 0x91, 0x00,
0130 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0131 0x00, 0x00, 0x00, 0xa2, 0x00, 0xe4, 0x94, 0xf6,
0132 0x9b, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00,
0133 };
0134
0135 static const unsigned char page01[256] = {
0136 0xa0, 0x83, 0x00, 0x00, 0xb5, 0xd0, 0x80, 0x87,
0137 0x00, 0x00, 0x00, 0x00, 0xb6, 0xd1, 0x00, 0x00,
0138 0x00, 0x00, 0xed, 0x89, 0x00, 0x00, 0xb8, 0xd3,
0139 0xb7, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0140 0x00, 0x00, 0x95, 0x85, 0x00, 0x00, 0x00, 0x00,
0141 0x00, 0x00, 0xa1, 0x8c, 0x00, 0x00, 0xbd, 0xd4,
0142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xe9,
0143 0x00, 0x00, 0x00, 0xea, 0xeb, 0x00, 0x00, 0x00,
0144 0x00, 0xad, 0x88, 0xe3, 0xe7, 0xee, 0xec, 0x00,
0145 0x00, 0x00, 0x00, 0x00, 0xe2, 0x93, 0x00, 0x00,
0146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8b,
0147 0x00, 0x00, 0x97, 0x98, 0x00, 0x00, 0x00, 0x00,
0148 0xbe, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0149 0x00, 0x00, 0xc7, 0xd7, 0x00, 0x00, 0x00, 0x00,
0150 0x00, 0x00, 0xc6, 0xd6, 0x00, 0x00, 0x00, 0x00,
0151 0x00, 0x8d, 0xa5, 0xa3, 0xa4, 0xcf, 0xd8, 0x00,
0152 };
0153
0154 static const unsigned char page20[256] = {
0155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0158 0x00, 0xef, 0x00, 0x00, 0xf2, 0xa6, 0xf7, 0x00,
0159 };
0160
0161 static const unsigned char page22[256] = {
0162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0165 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0166 };
0167
0168 static const unsigned char page25[256] = {
0169 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00,
0170 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00,
0171 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
0172 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00,
0173 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
0174 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00,
0175 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00,
0176 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00,
0177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0179 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb,
0180 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00,
0181 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00,
0182 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00,
0183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0185
0186 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00,
0187 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00,
0188 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00,
0189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0190 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0191 };
0192
0193 static const unsigned char *const page_uni2charset[256] = {
0194 page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
0195 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0196 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0197 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0198 page20, NULL, page22, NULL, NULL, page25, NULL, NULL,
0199 };
0200
0201 static const unsigned char charset2lower[256] = {
0202 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0203 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0204 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0205 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0206 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0207 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0208 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0209 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0210 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0211 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0212 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0213 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0214 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0215 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0216 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0217 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0218
0219 0x87, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0220 0x88, 0x89, 0x8b, 0x8b, 0x8c, 0xa5, 0x84, 0x86,
0221 0x82, 0x91, 0x91, 0x93, 0x94, 0x85, 0x96, 0x98,
0222 0x98, 0x94, 0x81, 0x9b, 0x9c, 0x9b, 0x9e, 0x9f,
0223 0x83, 0x8c, 0xa2, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7,
0224 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x88, 0xae, 0xaf,
0225 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xd0, 0xd1, 0xd2,
0226 0xd3, 0xb9, 0xba, 0xbb, 0xbc, 0xd4, 0xd5, 0xbf,
0227 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xd6, 0xd7,
0228 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xd8,
0229 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0230 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0231 0xa2, 0xe1, 0x93, 0xe7, 0xe4, 0xe4, 0xe6, 0xe7,
0232 0xe9, 0xe9, 0xeb, 0xeb, 0xec, 0x89, 0xec, 0xef,
0233 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0234 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0235 };
0236
0237 static const unsigned char charset2upper[256] = {
0238 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0239 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0240 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0241 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0242 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0243 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0244 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0245 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0246 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0247 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0248 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0249 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0250 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0251 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0252 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0253 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0254
0255 0x80, 0x9a, 0x90, 0xa0, 0x8e, 0x95, 0x8f, 0x80,
0256 0xad, 0xed, 0x8a, 0x8a, 0xa1, 0x8d, 0x8e, 0x8f,
0257 0x90, 0x92, 0x92, 0xe2, 0x99, 0x95, 0x96, 0x97,
0258 0x97, 0x99, 0x9a, 0x9d, 0x9c, 0x9d, 0x9e, 0x9f,
0259 0xa0, 0xa1, 0xe0, 0xa3, 0xa3, 0x8d, 0xa6, 0xa7,
0260 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0261 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0262 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0263 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0264 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0265 0xb5, 0xb6, 0xb7, 0xb8, 0xbd, 0xbe, 0xc6, 0xc7,
0266 0xcf, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0267 0xe0, 0xe1, 0xe2, 0xe3, 0xe5, 0xe5, 0x00, 0xe3,
0268 0xe8, 0xe8, 0xea, 0xea, 0xee, 0xed, 0xee, 0xef,
0269 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0270 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0271 };
0272
0273 static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
0274 {
0275 const unsigned char *uni2charset;
0276 unsigned char cl = uni & 0x00ff;
0277 unsigned char ch = (uni & 0xff00) >> 8;
0278
0279 if (boundlen <= 0)
0280 return -ENAMETOOLONG;
0281
0282 uni2charset = page_uni2charset[ch];
0283 if (uni2charset && uni2charset[cl])
0284 out[0] = uni2charset[cl];
0285 else
0286 return -EINVAL;
0287 return 1;
0288 }
0289
0290 static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
0291 {
0292 *uni = charset2uni[*rawstring];
0293 if (*uni == 0x0000)
0294 return -EINVAL;
0295 return 1;
0296 }
0297
0298 static struct nls_table table = {
0299 .charset = "cp775",
0300 .uni2char = uni2char,
0301 .char2uni = char2uni,
0302 .charset2lower = charset2lower,
0303 .charset2upper = charset2upper,
0304 };
0305
0306 static int __init init_nls_cp775(void)
0307 {
0308 return register_nls(&table);
0309 }
0310
0311 static void __exit exit_nls_cp775(void)
0312 {
0313 unregister_nls(&table);
0314 }
0315
0316 module_init(init_nls_cp775)
0317 module_exit(exit_nls_cp775)
0318
0319 MODULE_LICENSE("Dual BSD/GPL");