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