add support http ts stream.(client)
[vuplus_dvbapp] / lib / service / service.cpp
1 #include <lib/base/eerror.h>
2 #include <lib/base/estring.h>
3 #include <lib/python/python.h>
4 #include <lib/service/service.h>
5 #include <lib/base/init_num.h>
6 #include <lib/base/init.h>
7 #include <lib/python/python.h>
8
9 static std::string encode(const std::string s)
10 {
11         int len = s.size();
12         std::string res;
13         int i;
14         for (i=0; i<len; ++i)
15         {
16                 unsigned char c = s[i];
17                 if ((c == ':') || (c < 32) || (c == '%'))
18                 {
19                         res += "%";
20                         char hex[8];
21                         snprintf(hex, 8, "%02x", c);
22                         res += hex;
23                 } else
24                         res += c;
25         }
26         return res;
27 }
28
29 static std::string decode(const std::string s)
30 {
31         int len = s.size();
32         std::string res;
33         int i;
34         for (i=0; i<len; ++i)
35         {
36                 unsigned char c = s[i];
37                 if (c != '%')
38                         res += c;
39                 else
40                 {
41                         i += 2;
42                         if (i >= len)
43                                 break;
44                         char t[3] = {s[i - 1], s[i], 0};
45                         unsigned char r = strtoul(t, 0, 0x10);
46                         if (r)
47                                 res += r;
48                 }
49         }
50         return res;
51 }
52
53
54 eServiceReference::eServiceReference(const std::string &string)
55 {
56         const char *c=string.c_str();
57         int pathl=0;
58
59         if (!string.length())
60                 type = idInvalid;
61         else if ( sscanf(c, "%d:%d:%x:%x:%x:%x:%x:%x:%x:%x:%n", &type, &flags, &data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], &data[7], &pathl) < 8 )
62         {
63                 memset( data, 0, sizeof(data) );
64                 eDebug("find old format eServiceReference string");
65                 if ( sscanf(c, "%d:%d:%x:%x:%x:%x:%n", &type, &flags, &data[0], &data[1], &data[2], &data[3], &pathl) < 2 )
66                         type = idInvalid;
67         }
68
69         if (pathl)
70         {
71                 const char *pathstr = c+pathl;
72                 const char *namestr = strchr(pathstr, ':');
73                 if (namestr)
74                 {
75                         if (!strncmp(namestr, "://", 3)) // The path is a url (e.g. "http://...")
76                         {
77                                 namestr = strchr(namestr, ' ');
78                                 if (namestr)
79                                 {
80                                         path.assign(pathstr, namestr - pathstr);
81                                         if (*(namestr + 1))
82                                                 name = namestr + 1;
83                                 }
84                         }
85                         else
86                         {
87                                 if (pathstr != namestr)
88                                         path.assign(pathstr, namestr-pathstr);
89                                 if (*(namestr+1))
90                                         name=namestr+1;
91                         }
92                 }
93                 else
94                         path=pathstr;
95         }
96         
97         path = decode(path);
98         name = decode(name);
99 }
100
101 std::string eServiceReference::toString() const
102 {
103         std::string ret;
104         ret += getNum(type);
105         ret += ":";
106         ret += getNum(flags);
107         for (unsigned int i=0; i<sizeof(data)/sizeof(*data); ++i)
108                 ret+=":"+ getNum(data[i], 0x10);
109         ret+=":"+encode(path); /* we absolutely have a problem when the path contains a ':' (for example: http://). we need an encoding here. */
110         if (name.length())
111                 ret+=":"+encode(name);
112         return ret;
113 }
114
115 std::string eServiceReference::toCompareString() const
116 {
117         std::string ret;
118         ret += getNum(type);
119         ret += ":0";
120         for (unsigned int i=0; i<sizeof(data)/sizeof(*data); ++i)
121                 ret+=":"+getNum(data[i], 0x10);
122         ret+=":"+encode(path);
123         return ret;
124 }
125
126 eServiceCenter *eServiceCenter::instance;
127
128 eServiceCenter::eServiceCenter()
129 {
130         if (!instance)
131         {
132                 eDebug("settings instance.");
133                 instance = this;
134         }
135 }
136
137 eServiceCenter::~eServiceCenter()
138 {
139         if (instance == this)
140         {
141                 eDebug("clear instance");
142                 instance = 0;
143         }
144 }
145
146 DEFINE_REF(eServiceCenter);
147
148 RESULT eServiceCenter::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
149 {
150         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
151         if (i == handler.end())
152         {
153                 ptr = 0;
154                 return -1;
155         }
156         return i->second->play(ref, ptr);
157 }
158
159 RESULT eServiceCenter::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
160 {
161         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
162         if (i == handler.end())
163         {
164                 ptr = 0;
165                 return -1;
166         }
167         return i->second->record(ref, ptr);
168 }
169
170 RESULT eServiceCenter::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
171 {
172         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
173         if (i == handler.end())
174         {
175                 ptr = 0;
176                 return -1;
177         }
178         return i->second->list(ref, ptr);
179 }
180
181 RESULT eServiceCenter::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
182 {
183         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
184         if (i == handler.end())
185         {
186                 ptr = 0;
187                 return -1;
188         }
189         return i->second->info(ref, ptr);
190 }
191
192 RESULT eServiceCenter::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
193 {
194         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
195         if (i == handler.end())
196         {
197                 ptr = 0;
198                 return -1;
199         }
200         return i->second->offlineOperations(ref, ptr);
201 }
202
203 RESULT eServiceCenter::addServiceFactory(int id, iServiceHandler *hnd, std::list<std::string> &extensions)
204 {
205         handler.insert(std::pair<int,ePtr<iServiceHandler> >(id, hnd));
206         this->extensions[id]=extensions;
207         return 0;
208 }
209
210 RESULT eServiceCenter::removeServiceFactory(int id)
211 {
212         handler.erase(id);
213         extensions.erase(id);
214         return 0;
215 }
216
217 RESULT eServiceCenter::addFactoryExtension(int id, const char *extension)
218 {
219         std::map<int, std::list<std::string> >::iterator it = extensions.find(id);
220         if (it == extensions.end())
221                 return -1;
222         it->second.push_back(extension);
223         return 0;
224 }
225
226 RESULT eServiceCenter::removeFactoryExtension(int id, const char *extension)
227 {
228         std::map<int, std::list<std::string> >::iterator it = extensions.find(id);
229         if (it == extensions.end())
230                 return -1;
231         it->second.remove(extension);
232         return 0;
233 }
234
235
236 int eServiceCenter::getServiceTypeForExtension(const char *str)
237 {
238         for (std::map<int, std::list<std::string> >::iterator sit(extensions.begin()); sit != extensions.end(); ++sit)
239         {
240                 for (std::list<std::string>::iterator eit(sit->second.begin()); eit != sit->second.end(); ++eit)
241                 {
242                         if (*eit == str)
243                                 return sit->first;
244                 }
245         }
246         return -1;
247 }
248
249 int eServiceCenter::getServiceTypeForExtension(const std::string &str)
250 {
251         return getServiceTypeForExtension(str.c_str());
252 }
253
254         /* default handlers */
255 RESULT iServiceHandler::info(const eServiceReference &, ePtr<iStaticServiceInformation> &ptr)
256 {
257         ptr = 0;
258         return -1;
259 }
260
261 #include <lib/service/event.h>
262
263 RESULT iStaticServiceInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &evt, time_t start_time)
264 {
265         evt = 0;
266         return -1;
267 }
268
269 int iStaticServiceInformation::getLength(const eServiceReference &ref)
270 {
271         return -1;
272 }
273
274 int iStaticServiceInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
275 {
276         return 0;
277 }
278
279 RESULT iServiceInformation::getEvent(ePtr<eServiceEvent> &evt, int m_nownext)
280 {
281         evt = 0;
282         return -1;
283 }
284
285 int iStaticServiceInformation::getInfo(const eServiceReference &ref, int w)
286 {
287         return -1;
288 }
289
290 std::string iStaticServiceInformation::getInfoString(const eServiceReference &ref, int w)
291 {
292         return "";
293 }
294
295 PyObject *iStaticServiceInformation::getInfoObject(const eServiceReference &ref, int w)
296 {
297         Py_RETURN_NONE;
298 }
299
300 int iServiceInformation::getInfo(int w)
301 {
302         return -1;
303 }
304
305 std::string iServiceInformation::getInfoString(int w)
306 {
307         return "";
308 }
309
310 PyObject* iServiceInformation::getInfoObject(int w)
311 {
312         Py_RETURN_NONE;
313 }
314
315 int iStaticServiceInformation::setInfo(const eServiceReference &ref, int w, int v)
316 {
317         return -1;
318 }
319
320 int iStaticServiceInformation::setInfoString(const eServiceReference &ref, int w, const char *v)
321 {
322         return -1;
323 }
324
325 int iServiceInformation::setInfo(int w, int v)
326 {
327         return -1;
328 }
329
330 int iServiceInformation::setInfoString(int w, const char *v)
331 {
332         return -1;
333 }
334
335 eAutoInitPtr<eServiceCenter> init_eServiceCenter(eAutoInitNumbers::service, "eServiceCenter");