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, 0x00a1, 0x00a2, 0x00a3,
0067 0x20ac, 0x00a5, 0x0160, 0x00a7,
0068 0x0161, 0x00a9, 0x00aa, 0x00ab,
0069 0x00ac, 0x00ad, 0x00ae, 0x00af,
0070
0071 0x00b0, 0x00b1, 0x00b2, 0x00b3,
0072 0x017d, 0x00b5, 0x00b6, 0x00b7,
0073 0x017e, 0x00b9, 0x00ba, 0x00bb,
0074 0x0152, 0x0153, 0x0178, 0x00bf,
0075
0076 0x00c0, 0x00c1, 0x00c2, 0x00c3,
0077 0x00c4, 0x00c5, 0x00c6, 0x00c7,
0078 0x00c8, 0x00c9, 0x00ca, 0x00cb,
0079 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0080
0081 0x00d0, 0x00d1, 0x00d2, 0x00d3,
0082 0x00d4, 0x00d5, 0x00d6, 0x00d7,
0083 0x00d8, 0x00d9, 0x00da, 0x00db,
0084 0x00dc, 0x00dd, 0x00de, 0x00df,
0085
0086 0x00e0, 0x00e1, 0x00e2, 0x00e3,
0087 0x00e4, 0x00e5, 0x00e6, 0x00e7,
0088 0x00e8, 0x00e9, 0x00ea, 0x00eb,
0089 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0090
0091 0x00f0, 0x00f1, 0x00f2, 0x00f3,
0092 0x00f4, 0x00f5, 0x00f6, 0x00f7,
0093 0x00f8, 0x00f9, 0x00fa, 0x00fb,
0094 0x00fc, 0x00fd, 0x00fe, 0x00ff,
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, 0xa1, 0xa2, 0xa3, 0x00, 0xa5, 0x00, 0xa7,
0120 0x00, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0121 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7,
0122 0x00, 0xb9, 0xba, 0xbb, 0x00, 0x00, 0x00, 0xbf,
0123 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0124 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0125 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0126 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0127 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0128 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0129 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0130 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0131 };
0132
0133 static const unsigned char page01[256] = {
0134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0144 0x00, 0x00, 0xbc, 0xbd, 0x00, 0x00, 0x00, 0x00,
0145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0146 0xa6, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0149 0xbe, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb8, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0169
0170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0175 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00,
0176 };
0177
0178 static const unsigned char *const page_uni2charset[256] = {
0179 page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
0180 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0181
0182 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0183 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0184
0185 page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0186 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0187 };
0188
0189 static const unsigned char charset2lower[256] = {
0190 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0191 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0192 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0193 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0194 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0195 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0196 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0197 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0198 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0199 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0200 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0201 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0202 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0203 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0204 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0205 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0206
0207 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0208 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0209 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0210 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0211 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xa7,
0212 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0213 0xb0, 0xb1, 0xb2, 0xb3, 0xb8, 0xb5, 0xb6, 0xb7,
0214 0xb8, 0xb9, 0xba, 0xbb, 0xbd, 0xbd, 0xff, 0xbf,
0215 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0216 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0217 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7,
0218 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf,
0219 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0220 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0221 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0222 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0223 };
0224
0225 static const unsigned char charset2upper[256] = {
0226 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0227 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0228 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0229 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0230 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0231 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0232 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0233 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0234 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0235 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0236 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0237 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0238 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0239 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0240 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0241 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0242
0243 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0244 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0245 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0246 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0247 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0248 0xa6, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0249 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0x00, 0xb6, 0xb7,
0250 0xb4, 0xb9, 0xba, 0xbb, 0xbc, 0xbc, 0xbe, 0xbf,
0251 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0252 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0253 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0254 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0255 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0256 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0257 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7,
0258 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xbe,
0259 };
0260
0261 static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
0262 {
0263 const unsigned char *uni2charset;
0264 unsigned char cl = uni & 0x00ff;
0265 unsigned char ch = (uni & 0xff00) >> 8;
0266
0267 if (boundlen <= 0)
0268 return -ENAMETOOLONG;
0269
0270 uni2charset = page_uni2charset[ch];
0271 if (uni2charset && uni2charset[cl])
0272 out[0] = uni2charset[cl];
0273 else
0274 return -EINVAL;
0275 return 1;
0276 }
0277
0278 static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
0279 {
0280 *uni = charset2uni[*rawstring];
0281 if (*uni == 0x0000)
0282 return -EINVAL;
0283 return 1;
0284 }
0285
0286 static struct nls_table table = {
0287 .charset = "iso8859-15",
0288 .uni2char = uni2char,
0289 .char2uni = char2uni,
0290 .charset2lower = charset2lower,
0291 .charset2upper = charset2upper,
0292 };
0293
0294 static int __init init_nls_iso8859_15(void)
0295 {
0296 return register_nls(&table);
0297 }
0298
0299 static void __exit exit_nls_iso8859_15(void)
0300 {
0301 unregister_nls(&table);
0302 }
0303
0304 module_init(init_nls_iso8859_15)
0305 module_exit(exit_nls_iso8859_15)
0306
0307 MODULE_LICENSE("Dual BSD/GPL");