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