add ignore files.
[vuplus_transtreamproxy] / src / eURIDecoder.cpp
1 /*
2  * URIDecoder.cpp
3  *
4  *  Created on: 2013. 10. 21.
5  *      Author: kos
6  */
7
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "eURIDecoder.h"
12 //-------------------------------------------------------------------------------
13
14 eURIDecoder::eURIDecoder()
15 {
16 }
17 //-------------------------------------------------------------------------------
18
19 eURIDecoder::~eURIDecoder()
20 {
21 }
22 //-------------------------------------------------------------------------------
23
24 unsigned char eURIDecoder::H2I(wchar_t aHexDigit)
25 {
26         switch (aHexDigit) {
27         case _UL_('0'):
28         case _UL_('1'):
29         case _UL_('2'):
30         case _UL_('3'):
31         case _UL_('4'):
32         case _UL_('5'):
33         case _UL_('6'):
34         case _UL_('7'):
35         case _UL_('8'):
36         case _UL_('9'):
37                 return (unsigned char)(9 + aHexDigit - _UL_('9'));
38         case _UL_('a'):
39         case _UL_('b'):
40         case _UL_('c'):
41         case _UL_('d'):
42         case _UL_('e'):
43         case _UL_('f'):
44                 return (unsigned char)(15 + aHexDigit - _UL_('f'));
45         case _UL_('A'):
46         case _UL_('B'):
47         case _UL_('C'):
48         case _UL_('D'):
49         case _UL_('E'):
50         case _UL_('F'):
51                 return (unsigned char)(15 + aHexDigit - _UL_('F'));
52         default:
53                 return 0;
54         }
55 }
56 //-------------------------------------------------------------------------------
57
58 const wchar_t* eURIDecoder::DecodeURI(wchar_t* aData, int aBreakCond)
59 {
60         wchar_t* read  = aData;
61         wchar_t* write = aData;
62         bool prevWasCr = false;
63
64         if (aData == NULL) {
65                 return NULL;
66         }
67
68         for (;;) {
69                 switch (read[0]) {
70                 case _UL_('\0'):
71                         if (read > write) {
72                                 write[0] = _UL_('\0');
73                         }
74                         return write;
75
76                 case _UL_('%'):
77                         switch (read[1]) {
78                         case _UL_('0'):
79                         case _UL_('1'):
80                         case _UL_('2'):
81                         case _UL_('3'):
82                         case _UL_('4'):
83                         case _UL_('5'):
84                         case _UL_('6'):
85                         case _UL_('7'):
86                         case _UL_('8'):
87                         case _UL_('9'):
88                         case _UL_('a'):
89                         case _UL_('b'):
90                         case _UL_('c'):
91                         case _UL_('d'):
92                         case _UL_('e'):
93                         case _UL_('f'):
94                         case _UL_('A'):
95                         case _UL_('B'):
96                         case _UL_('C'):
97                         case _UL_('D'):
98                         case _UL_('E'):
99                         case _UL_('F'):
100                                 switch (read[2]) {
101                                 case _UL_('0'):
102                                 case _UL_('1'):
103                                 case _UL_('2'):
104                                 case _UL_('3'):
105                                 case _UL_('4'):
106                                 case _UL_('5'):
107                                 case _UL_('6'):
108                                 case _UL_('7'):
109                                 case _UL_('8'):
110                                 case _UL_('9'):
111                                 case _UL_('a'):
112                                 case _UL_('b'):
113                                 case _UL_('c'):
114                                 case _UL_('d'):
115                                 case _UL_('e'):
116                                 case _UL_('f'):
117                                 case _UL_('A'):
118                                 case _UL_('B'):
119                                 case _UL_('C'):
120                                 case _UL_('D'):
121                                 case _UL_('E'):
122                                 case _UL_('F'): {
123                                                 const unsigned char left = H2I(read[1]);
124                                                 const unsigned char right = H2I(read[2]);
125                                                 const int code = 16 * left + right;
126                                                 switch (code) {
127                                                 case 10:
128                                                         switch (aBreakCond) {
129                                                         case BR_TO_LF:
130                                                                 if (!prevWasCr) {
131                                                                         write[0] = (wchar_t)10;
132                                                                         write++;
133                                                                 }
134                                                                 break;
135
136                                                         case BR_TO_CRLF:
137                                                                 if (!prevWasCr) {
138                                                                         write[0] = (wchar_t)13;
139                                                                         write[1] = (wchar_t)10;
140                                                                         write += 2;
141                                                                 }
142                                                                 break;
143
144                                                         case BR_TO_CR:
145                                                                 if (!prevWasCr) {
146                                                                         write[0] = (wchar_t)13;
147                                                                         write++;
148                                                                 }
149                                                                 break;
150
151                                                         case BR_DONT_TOUCH:
152                                                         default:
153                                                                 write[0] = (wchar_t)10;
154                                                                 write++;
155
156                                                         }
157                                                         prevWasCr = false;
158                                                         break;
159
160                                                 case 13:
161                                                         switch (aBreakCond) {
162                                                         case BR_TO_LF:
163                                                                 write[0] = (wchar_t)10;
164                                                                 write++;
165                                                                 break;
166
167                                                         case BR_TO_CRLF:
168                                                                 write[0] = (wchar_t)13;
169                                                                 write[1] = (wchar_t)10;
170                                                                 write += 2;
171                                                                 break;
172
173                                                         case BR_TO_CR:
174                                                                 write[0] = (wchar_t)13;
175                                                                 write++;
176                                                                 break;
177
178                                                         case BR_DONT_TOUCH:
179                                                         default:
180                                                                 write[0] = (wchar_t)13;
181                                                                 write++;
182
183                                                         }
184                                                         prevWasCr = true;
185                                                         break;
186
187                                                 default:
188                                                         write[0] = (wchar_t)(code);
189                                                         write++;
190
191                                                         prevWasCr = false;
192
193                                                 }
194                                                 read += 3;
195                                         }
196                                         break;
197
198                                 default:
199                                         if (read > write) {
200                                                 write[0] = read[0];
201                                                 write[1] = read[1];
202                                         }
203                                         read += 2;
204                                         write += 2;
205
206                                         prevWasCr = false;
207                                 }
208                                 break;
209
210                         default:
211                                 if (read > write) {
212                                         write[0] = read[0];
213                                 }
214                                 read++;
215                                 write++;
216
217                                 prevWasCr = false;
218                         }
219                         break;
220
221                 case _UL_('+'):
222                         if (read > write) {
223                                 write[0] = _UL_(' ');
224                         }
225                         read++;
226                         write++;
227
228                         prevWasCr = false;
229                         break;
230
231                 default:
232                         if (read > write) {
233                                 write[0] = read[0];
234                         }
235                         read++;
236                         write++;
237
238                         prevWasCr = false;
239                 }
240         }
241 }
242 //-------------------------------------------------------------------------------
243
244 std::wstring eURIDecoder::Decode(const wchar_t* aInput)
245 {
246         wchar_t working[1024] = {0};
247
248         wcscpy(working, aInput);
249         DecodeURI(working, BR_DONT_TOUCH);
250
251         return std::wstring(working);
252 }
253 //-------------------------------------------------------------------------------
254
255 std::string eURIDecoder::Decode(const char* aInput)
256 {
257         std::string tmp = aInput;
258         std::wstring in = L"";
259         in.assign(tmp.begin(), tmp.end());
260
261         std::wstring decode = Decode(in.c_str());
262
263         tmp.assign(decode.begin(), decode.end());
264
265         return tmp;
266 }
267 //-------------------------------------------------------------------------------
268
269 #ifdef UNIT_TEST
270 #include <iostream>
271 int main()
272 {
273         std::string in = "/home/kos/work/workspace/tsstreamproxy/test/20130528%201415%20-%20ZDF%20-%20Die%20K%C3%BCchenschlacht.ts";
274         std::string out = URIDecoder().Decode(in.c_str());
275
276         cout << out << endl;
277
278         FILE* fp = fopen(out.c_str(), "rb");
279
280         cout << (fp == NULL) ? "OPEN FAIL!!" : "OPEN OK" << endl;
281 }
282
283 #endif