why not allow directly utf8 encoded dvb texts? ;)
[enigma2.git] / lib / base / estring.cpp
1 #include <string>
2 #include <ctype.h>
3 #include <limits.h>
4 #include <lib/base/eerror.h>
5 #include <lib/base/encoding.h>
6 #include <lib/base/estring.h>
7
8 std::string getNum(int val, int sys)
9 {
10 //      Returns a string that contain the value val as string
11 //      if sys == 16 than hexadezimal if sys == 10 than decimal
12         char buf[12];
13
14         if (sys == 10)
15                 std::snprintf(buf, 12, "%i", val);
16         else if (sys == 16)
17                 std::snprintf(buf, 12, "%X", val);              
18         
19         std::string res;
20         res.assign(buf);
21         return res;
22 }
23
24                 // 8859-x to ucs-16 coding tables. taken from www.unicode.org/Public/MAPPINGS/ISO8859/
25
26 static unsigned long c88592[96]={
27 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
28 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
29 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
30 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
31 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
32 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9};
33
34 static unsigned long c88593[96]={
35 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7, 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B,
36 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C,
37 0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
38 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
39 0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
40 0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9};
41
42 static unsigned long c88594[96]={
43 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF,
44 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B,
45 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A,
46 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF,
47 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B,
48 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9};
49
50 static unsigned long c88595[96]={
51 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
52 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
53 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
54 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
55 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
56 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F};
57
58 static unsigned long c88596[96]={
59 0x00A0, 0x0000, 0x0000, 0x0000, 0x00A4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x060C, 0x00AD, 0x0000, 0x0000,
60 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x061B, 0x0000, 0x0000, 0x0000, 0x061F,
61 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
62 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
63 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F,
64 0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
65
66 static unsigned long c88597[96]={
67 0x00A0, 0x2018, 0x2019, 0x00A3, 0x20AC, 0x20AF, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x037A, 0x00AB, 0x00AC, 0x00AD, 0x0000, 0x2015,
68 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
69 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
70 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
71 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
72 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000};
73
74 static unsigned long c88598[96]={
75 0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
76 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x0000,
77 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
78 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017,
79 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
80 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000};
81
82 static unsigned long c88599[96]={
83 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
84 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
85 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
86 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
87 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
88 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF};
89
90 static unsigned long c885910[96]={
91 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7, 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A,
92 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7, 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2015, 0x016B, 0x014B,
93 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF,
94 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168, 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
95 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF,
96 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169, 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138};
97
98 static unsigned long c885911[96]={
99 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
100 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
101 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
102 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
103 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
104 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000};
105
106 static unsigned long c885913[96]={
107 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
108 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
109 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
110 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
111 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
112 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019};
113
114 static unsigned long c885914[96]={
115 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7, 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178,
116 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56, 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61,
117 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
118 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF,
119 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
120 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF};
121
122 static unsigned long c885915[96]={
123 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7, 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
124 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7, 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF,
125 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
126 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
127 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
128 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF};
129
130 static unsigned long c885916[96]={
131 0x00A0, 0x0104, 0x0105, 0x0141, 0x20AC, 0x201E, 0x0160, 0x00A7, 0x0161, 0x00A9, 0x0218, 0x00AB, 0x0179, 0x00AD, 0x017A, 0x017B,
132 0x00B0, 0x00B1, 0x010C, 0x0142, 0x017D, 0x201D, 0x00B6, 0x00B7, 0x017E, 0x010D, 0x0219, 0x00BB, 0x0152, 0x0153, 0x0178, 0x017C,
133 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0106, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
134 0x0110, 0x0143, 0x00D2, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x015A, 0x0170, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0118, 0x021A, 0x00DF,
135 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x0107, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
136 0x0111, 0x0144, 0x00F2, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x015B, 0x0171, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0119, 0x021B, 0x00FF};
137
138 // Two Char Mapping ( many polish services and UPC Direct/HBO services)
139 // get from http://mitglied.lycos.de/buran/charsets/videotex-suppl.html
140 static inline unsigned int doVideoTexSuppl(int c1, int c2)
141 {
142         switch (c1)
143         {
144                 case 0xC1: // grave
145                         switch (c2)
146                         {
147                                 case 0x61: return 224;                          case 0x41: return 192;
148                                 case 0x65: return 232;                          case 0x45: return 200;
149                                 case 0x69: return 236;                          case 0x49: return 204;
150                                 case 0x6f: return 242;                          case 0x4f: return 210;
151                                 case 0x75: return 249;                          case 0x55: return 217;
152                                 default: return 0;
153                         }
154                 case 0xC2: // acute
155                         switch (c2)
156                         {
157                                 case 0x61: return 225;                          case 0x41: return 193;
158                                 case 0x65: return 233;                          case 0x45: return 201;
159                                 case 0x69: return 237;                          case 0x49: return 205;
160                                 case 0x6f: return 243;                          case 0x4f: return 211;
161                                 case 0x75: return 250;                          case 0x55: return 218;
162                                 case 0x79: return 253;                          case 0x59: return 221;
163                                 case 0x63: return 263;                          case 0x43: return 262;
164                                 case 0x6c: return 314;                          case 0x4c: return 313;
165                                 case 0x6e: return 324;                          case 0x4e: return 323;
166                                 case 0x72: return 341;                          case 0x52: return 340;
167                                 case 0x73: return 347;                          case 0x53: return 346;
168                                 case 0x7a: return 378;                          case 0x5a: return 377;
169                                 default: return 0;
170                         }
171                 case 0xC3: // cedilla
172                         switch (c2)
173                         {
174                                 case 0x61: return 226;                          case 0x41: return 194;
175                                 case 0x65: return 234;                          case 0x45: return 202;
176                                 case 0x69: return 238;                          case 0x49: return 206;
177                                 case 0x6f: return 244;                          case 0x4f: return 212;
178                                 case 0x75: return 251;                          case 0x55: return 219;
179                                 case 0x79: return 375;                          case 0x59: return 374;
180                                 case 0x63: return 265;                          case 0x43: return 264;
181                                 case 0x67: return 285;                          case 0x47: return 284;
182                                 case 0x68: return 293;                          case 0x48: return 292;
183                                 case 0x6a: return 309;                          case 0x4a: return 308;
184                                 case 0x73: return 349;                          case 0x53: return 348;
185                                 case 0x77: return 373;                          case 0x57: return 372;
186                                 default: return 0;
187                         }
188                 case 0xC4: // tilde
189                         switch (c2)
190                         {
191                                 case 0x61: return 227;                          case 0x41: return 195;
192                                 case 0x6e: return 241;                          case 0x4e: return 209;
193                                 case 0x69: return 297;                          case 0x49: return 296;
194                                 case 0x6f: return 245;                          case 0x4f: return 213;
195                                 case 0x75: return 361;                          case 0x55: return 360;
196                                 default: return 0;
197                         }
198                 case 0xC6: // breve
199                         switch (c2)
200                         {
201                                 case 0x61: return 259;                          case 0x41: return 258;
202                                 case 0x67: return 287;                          case 0x47: return 286;
203                                 case 0x75: return 365;                          case 0x55: return 364;
204                                 default: return 0;
205                         }
206                 case 0xC7: // dot above
207                         switch (c2)
208                         {
209                                 case 0x63: return 267;                          case 0x43: return 266;
210                                 case 0x65: return 279;                          case 0x45: return 278;
211                                 case 0x67: return 289;                          case 0x47: return 288;
212                                 case 0x49: return 304;                          case 0x7a: return 380;
213                                 case 0x5a: return 379;
214                                 default: return 0;
215                         }
216                 case 0xC8: // diaeresis
217                         switch (c2)
218                         {
219                                 case 0x61: return 228;                          case 0x41: return 196;
220                                 case 0x65: return 235;                          case 0x45: return 203;
221                                 case 0x69: return 239;                          case 0x49: return 207;
222                                 case 0x6f: return 246;                          case 0x4f: return 214;
223                                 case 0x75: return 252;                          case 0x55: return 220;
224                                 case 0x79: return 255;                          case 0x59: return 376;
225                                 default: return 0;
226                                 }
227                 case 0xCA: // ring above
228                         switch (c2)
229                         {
230                                 case 0x61: return 229;                          case 0x41: return 197;
231                                 case 0x75: return 367;                          case 0x55: return 366;
232                                 default: return 0;
233                         }
234                 case 0xCB: // cedilla
235                         switch (c2)
236                         {
237                                 case 0x63: return 231;                          case 0x43: return 199;
238                                 case 0x67: return 291;                          case 0x47: return 290;
239                                 case 0x6b: return 311;                          case 0x4b: return 310;
240                                 case 0x6c: return 316;                          case 0x4c: return 315;
241                                 case 0x6e: return 326;                          case 0x4e: return 325;
242                                 case 0x72: return 343;                          case 0x52: return 342;
243                                 case 0x73: return 351;                          case 0x53: return 350;
244                                 case 0x74: return 355;                          case 0x54: return 354;
245                                 default: return 0;
246                         }
247                 case 0xCD: // double acute accent
248                         switch (c2)
249                         {
250                                 case 0x6f: return 337;                          case 0x4f: return 336;
251                                 case 0x75: return 369;                          case 0x55: return 368;
252                                 default: return 0;
253                         }
254                 case 0xCE: // ogonek
255                         switch (c2)
256                         {
257                                 case 0x61: return 261;                          case 0x41: return 260;
258                                 case 0x65: return 281;                          case 0x45: return 280;
259                                 case 0x69: return 303;                          case 0x49: return 302;
260                                 case 0x75: return 371;                          case 0x55: return 370;
261                                 default: return 0;
262                         }
263                 case 0xCF: // caron
264                         switch (c2)
265                         {
266                                 case 0x63: return 269;                          case 0x43: return 268;
267                                 case 0x64: return 271;                          case 0x44: return 270;
268                                 case 0x65: return 283;                          case 0x45: return 282;
269                                 case 0x6c: return 318;                          case 0x4c: return 317;
270                                 case 0x6e: return 328;                          case 0x4e: return 327;
271                                 case 0x72: return 345;                          case 0x52: return 344;
272                                 case 0x73: return 353;                          case 0x53: return 352;
273                                 case 0x74: return 357;                          case 0x54: return 356;
274                                 case 0x7a: return 382;                          case 0x5a: return 381;
275                                 default: return 0;
276                         }
277         }
278         return 0;
279 }
280
281 static inline unsigned int recode(unsigned char d, int cp)
282 {
283         if (d < 0xA0)
284                 return d;
285         switch (cp)
286         {
287         case 0:         // Latin1 <-> unicode mapping
288         case 1:         // 8859-1 <-> unicode mapping
289                 return d;
290         case 2:         // 8859-2 -> unicode mapping
291                 return c88592[d-0xA0];
292         case 3:         // 8859-3 -> unicode mapping
293                 return c88593[d-0xA0];
294         case 4:         // 8859-2 -> unicode mapping
295                 return c88594[d-0xA0];
296         case 5:         // 8859-5 -> unicode mapping
297                 return c88595[d-0xA0];
298         case 6:         // 8859-6 -> unicode mapping
299                 return c88596[d-0xA0];
300         case 7:         // 8859-7 -> unicode mapping
301                 return c88597[d-0xA0];
302         case 8:         // 8859-8 -> unicode mapping
303                 return c88598[d-0xA0];
304         case 9:         // 8859-9 -> unicode mapping
305                 return c88599[d-0xA0];
306         case 10:// 8859-10 -> unicode mapping
307                 return c885910[d-0xA0];
308         case 11:// 8859-11 -> unicode mapping
309                 return c885911[d-0xA0];
310 /*      case 12:// 8859-12 -> unicode mapping  // reserved for indian use..
311                 return c885912[d-0xA0];*/
312         case 13:// 8859-13 -> unicode mapping
313                 return c885913[d-0xA0];
314         case 14:// 8859-14 -> unicode mapping
315                 return c885914[d-0xA0];
316         case 15:// 8859-15 -> unicode mapping
317                 return c885915[d-0xA0];
318         case 16:// 8859-16 -> unicode mapping
319                 return c885916[d-0xA0];
320         default:
321                 return d;
322         }
323 }
324
325 std::string convertDVBUTF8(const unsigned char *data, int len, int table, int tsidonid)
326 {
327         if (!len)
328                 return "";
329
330         int i=0, t=0;
331
332         if ( tsidonid )
333                 encodingHandler.getTransponderDefaultMapping(tsidonid, table);
334
335         switch(data[0])
336         {
337                 case 1 ... 11:
338                         table=data[i++]+4;
339 //                      eDebug("(1..11)text encoded in ISO-8859-%d",table);
340                         break;
341                 case 0x10:
342                 {
343 //                      eDebug("(0x10)text encoded in ISO-8859-%d",n);
344                         int n=(data[++i]<<8);
345                         n |= (data[++i]);
346                         ++i;
347                         switch(n)
348                         {
349                                 case 12:
350                                         eDebug("unsup. ISO8859-12 enc.", n);
351                                         break;
352                                 default:
353                                         table=n;
354                                         break;
355                         }
356                         break;
357                 }
358                 case 0x11:
359                         eDebug("unsup. Basic Multilingual Plane of ISO/IEC 10646-1 enc.");
360                         ++i;
361                         break;
362                 case 0x12:
363                         ++i;
364                         eDebug("unsup. KSC 5601 enc.");
365                         break;
366                 case 0x13:
367                         ++i;
368                         eDebug("unsup. GB-2312-1980 enc.");
369                         break;
370                 case 0x14:
371                         ++i;
372                         eDebug("unsup. Big5 subset of ISO/IEC 10646-1 enc.");
373                         break;
374                 case 0x15: // UTF-8 encoding of ISO/IEC 10646-1
375                         return std::string((char*)data+1, len-1);
376                 case 0x0:
377                 case 0xC ... 0xF:
378                 case 0x16 ... 0x1F:
379                 default:
380                         eDebug("reserved %d", data[0]);
381                         ++i;
382                         break;
383         }
384
385         bool useTwoCharMapping =
386                 tsidonid && encodingHandler.getTransponderUseTwoCharMapping(tsidonid);
387
388         unsigned char res[2048];
389         while (i < len)
390         {
391                 unsigned long code=0;
392
393                 if ( useTwoCharMapping && i+1 < len &&
394                         (code=doVideoTexSuppl(data[i], data[i+1])) )
395                         i+=2;
396
397                 if (!code)
398                         code=recode(data[i++], table);
399                 if (!code)
400                         continue;
401                                 // Unicode->UTF8 encoding
402                 if (code < 0x80) // identity ascii <-> utf8 mapping
403                         res[t++]=char(code);
404                 else if (code < 0x800) // two byte mapping
405                 {
406                         res[t++]=(code>>6)|0xC0;
407                         res[t++]=(code&0x3F)|0x80;
408                 } else if (code < 0x10000) // three bytes mapping
409                 {
410                         res[t++]=(code>>12)|0xE0;
411                         res[t++]=((code>>6)&0x3F)|0x80;
412                         res[t++]=(code&0x3F)|0x80;
413                 } else
414                 {
415                         res[t++]=(code>>18)|0xF0;
416                         res[t++]=((code>>12)&0x3F)|0x80;
417                         res[t++]=((code>>6)&0x3F)|0x80;
418                         res[t++]=(code&0x3F)|0x80;
419                 }
420                 if (t+4 > 2047)
421                 {
422                         eDebug("convertDVBUTF8 buffer to small.. break now");
423                         break;
424                 }
425         }
426         return std::string((char*)res, t);
427 }
428
429 std::string convertUTF8DVB(const std::string &string, int table)
430 {
431         unsigned long *coding_table=0;
432
433         int len=string.length(), t=0;
434
435         unsigned char buf[len];
436
437         for(int i=0;i<len;i++)
438         {
439                 unsigned char c1=string[i];
440                 unsigned int c;
441                 if(c1<0x80)
442                         c=c1;
443                 else
444                 {
445                         i++;
446                         unsigned char c2=string[i];
447                         c=((c1&0x3F)<<6) + (c2&0x3F);
448                         if (table==0||table==1||c1<0xA0)
449                                 ;
450                         else
451                         {
452                                 if (!coding_table)
453                                 {
454                                         switch(table)
455                                         {
456                                                 case 2:
457                                                         coding_table = c88592;
458                                                         break;
459                                                 case 3:
460                                                         coding_table = c88593;
461                                                         break;
462                                                 case 4:
463                                                         coding_table = c88594;
464                                                         break;
465                                                 case 5:
466                                                         coding_table = c88595;
467                                                         break;
468                                                 case 6:
469                                                         coding_table = c88596;
470                                                         break;
471                                                 case 7:
472                                                         coding_table = c88597;
473                                                         break;
474                                                 case 8:
475                                                         coding_table = c88598;
476                                                         break;
477                                                 case 9:
478                                                         coding_table = c88599;
479                                                         break;
480                                                 case 10:
481                                                         coding_table = c885910;
482                                                         break;
483                                                 case 11:
484                                                         coding_table = c885911;
485                                                         break;
486 /*                              case 12:   // reserved.. for indian use
487                                                 coding_table = c885912;
488                                                 break;*/
489                                                 case 13:
490                                                         coding_table = c885913;
491                                                         break;
492                                                 case 14:
493                                                         coding_table = c885914;
494                                                         break;
495                                                 case 15:
496                                                         coding_table = c885915;
497                                                         break;
498                                                 case 16:
499                                                         coding_table = c885916;
500                                                         break;
501                                                 default:
502                                                         eFatal("unknown coding table %d", table);
503                                                         break;
504                                         }
505                                 }
506                                 for(unsigned int j=0;j<96;j++)
507                                 {
508                                         if(coding_table[j]==c)
509                                         {
510                                                 c=0xA0+j;
511                                                 break;
512                                         }
513                                 }
514                         }
515                 }
516                 buf[t++]=(unsigned char)c;
517         }
518         return std::string((char*)buf,t);
519 }
520
521 std::string convertLatin1UTF8(const std::string &string)
522 {
523         unsigned int t=0, i=0, len=string.size();
524
525         unsigned char res[2048];
526
527         while (i < len)
528         {
529                 unsigned long code=(unsigned char)string[i++];
530                                 // Unicode->UTF8 encoding
531                 if (code < 0x80) // identity latin <-> utf8 mapping
532                         res[t++]=char(code);
533                 else if (code < 0x800) // two byte mapping
534                 {
535                         res[t++]=(code>>6)|0xC0;
536                         res[t++]=(code&0x3F)|0x80;
537                 } else if (code < 0x10000) // three bytes mapping
538                 {
539                         res[t++]=(code>>12)|0xE0;
540                         res[t++]=((code>>6)&0x3F)|0x80;
541                         res[t++]=(code&0x3F)|0x80;
542                 } else
543                 {
544                         res[t++]=(code>>18)|0xF0;
545                         res[t++]=((code>>12)&0x3F)|0x80;
546                         res[t++]=((code>>6)&0x3F)|0x80;
547                         res[t++]=(code&0x3F)|0x80;
548                 }
549                 if (t+4 > 2047)
550                 {
551                         eDebug("convertLatin1UTF8 buffer to small.. break now");
552                         break;
553                 }
554         }
555         return std::string((char*)res, t);
556 }
557
558 int isUTF8(const std::string &string)
559 {
560         unsigned int len=string.size();
561
562         for (unsigned int i=0; i < len; ++i)
563         {
564                 if (!(string[i]&0x80)) // normal ASCII
565                         continue;
566                 if ((string[i] & 0xE0) == 0xC0) // one char following.
567                 {
568                                 // first, length check:
569                         if (i+1 >= len)
570                                 return 0; // certainly NOT utf-8
571                         i++;
572                         if ((string[i]&0xC0) != 0x80)
573                                 return 0; // no, not UTF-8.
574                 } else if ((string[i] & 0xF0) == 0xE0)
575                 {
576                         if ((i+1) >= len)
577                                 return 0;
578                         i++;
579                         if ((string[i]&0xC0) != 0x80)
580                                 return 0;
581                         i++;
582                         if ((string[i]&0xC0) != 0x80)
583                                 return 0;
584                 }
585         }
586         return 1; // can be UTF8 (or pure ASCII, at least no non-UTF-8 8bit characters)
587 }
588
589 std::string removeDVBChars(const std::string &s)
590 {
591         std::string res;
592         
593         int len = s.length();
594         
595         for(int i = 0; i < len; i++)
596         {
597                 unsigned char c1 = s[i];
598                 unsigned int c;
599                 
600                         /* UTF8? decode (but only simple) */
601                 if((c1 > 0x80) && (i < len-1))
602                 {
603                         unsigned char c2 = s[i + 1];
604                         c = ((c1&0x3F)<<6) + (c2&0x3F);
605                         if ((c >= 0x80) && (c <= 0x9F))
606                         {
607                                 ++i; /* skip 2nd utf8 char */
608                                 continue;
609                         }
610                 }
611                 
612                 res += s[i];
613         }
614         
615         return res;
616 }
617
618 void makeUpper(std::string &s)
619 {
620         std::transform(s.begin(), s.end(), s.begin(), (int(*)(int)) toupper);
621 }