TranscodingSetup : fix misspelling name.
[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         if (pathl)
69         {
70                 const char *pathstr = c+pathl;
71                 const char *namestr = NULL;
72                 int found = strlen(pathstr)-1;
73                 for(;found >= 0;found--)
74                 {
75                         if(pathstr[found] == ':')
76                                 break;
77                 }
78                 if (found != -1)
79                         namestr = pathstr + found;
80                 if (namestr)
81                 {
82                         if (!strncmp(namestr, "://", 3)) // The path is a url (e.g. "http://...")
83                         {
84                                 namestr = strchr(namestr, ' ');
85                                 if (namestr)
86                                 {
87                                         path.assign(pathstr, namestr - pathstr);
88                                         if (*(namestr + 1))
89                                                 name = namestr + 1;
90                                 }
91                         }
92                         else
93                         {
94                                 if (pathstr != namestr)
95                                         path.assign(pathstr, namestr-pathstr);
96                                 if (*(namestr+1))
97                                         name=namestr+1;
98                         }
99                 }
100                 else
101                         path=pathstr;
102         }
103         
104         path = decode(path);
105         name = decode(name);
106 }
107
108 std::string eServiceReference::toString() const
109 {
110         std::string ret;
111         ret += getNum(type);
112         ret += ":";
113         ret += getNum(flags);
114         for (unsigned int i=0; i<sizeof(data)/sizeof(*data); ++i)
115                 ret+=":"+ getNum(data[i], 0x10);
116         ret+=":"+encode(path); /* we absolutely have a problem when the path contains a ':' (for example: http://). we need an encoding here. */
117         if (name.length())
118                 ret+=":"+encode(name);
119         return ret;
120 }
121
122 std::string eServiceReference::toCompareString() const
123 {
124         std::string ret;
125         ret += getNum(type);
126         ret += ":0";
127         for (unsigned int i=0; i<sizeof(data)/sizeof(*data); ++i)
128                 ret+=":"+getNum(data[i], 0x10);
129         ret+=":"+encode(path);
130         return ret;
131 }
132
133 eServiceCenter *eServiceCenter::instance;
134
135 eServiceCenter::eServiceCenter()
136 {
137         if (!instance)
138         {
139                 eDebug("settings instance.");
140                 instance = this;
141         }
142 }
143
144 eServiceCenter::~eServiceCenter()
145 {
146         if (instance == this)
147         {
148                 eDebug("clear instance");
149                 instance = 0;
150         }
151 }
152
153 DEFINE_REF(eServiceCenter);
154
155 RESULT eServiceCenter::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
156 {
157         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
158         if (i == handler.end())
159         {
160                 ptr = 0;
161                 return -1;
162         }
163         return i->second->play(ref, ptr);
164 }
165
166 RESULT eServiceCenter::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
167 {
168         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
169         if (i == handler.end())
170         {
171                 ptr = 0;
172                 return -1;
173         }
174         return i->second->record(ref, ptr);
175 }
176
177 RESULT eServiceCenter::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
178 {
179         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
180         if (i == handler.end())
181         {
182                 ptr = 0;
183                 return -1;
184         }
185         return i->second->list(ref, ptr);
186 }
187
188 RESULT eServiceCenter::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
189 {
190         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
191         if (i == handler.end())
192         {
193                 ptr = 0;
194                 return -1;
195         }
196         return i->second->info(ref, ptr);
197 }
198
199 RESULT eServiceCenter::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
200 {
201         std::map<int,ePtr<iServiceHandler> >::iterator i = handler.find(ref.type);
202         if (i == handler.end())
203         {
204                 ptr = 0;
205                 return -1;
206         }
207         return i->second->offlineOperations(ref, ptr);
208 }
209
210 RESULT eServiceCenter::addServiceFactory(int id, iServiceHandler *hnd, std::list<std::string> &extensions)
211 {
212         handler.insert(std::pair<int,ePtr<iServiceHandler> >(id, hnd));
213         this->extensions[id]=extensions;
214         return 0;
215 }
216
217 RESULT eServiceCenter::removeServiceFactory(int id)
218 {
219         handler.erase(id);
220         extensions.erase(id);
221         return 0;
222 }
223
224 RESULT eServiceCenter::addFactoryExtension(int id, const char *extension)
225 {
226         std::map<int, std::list<std::string> >::iterator it = extensions.find(id);
227         if (it == extensions.end())
228                 return -1;
229         it->second.push_back(extension);
230         return 0;
231 }
232
233 RESULT eServiceCenter::removeFactoryExtension(int id, const char *extension)
234 {
235         std::map<int, std::list<std::string> >::iterator it = extensions.find(id);
236         if (it == extensions.end())
237                 return -1;
238         it->second.remove(extension);
239         return 0;
240 }
241
242
243 int eServiceCenter::getServiceTypeForExtension(const char *str)
244 {
245         for (std::map<int, std::list<std::string> >::iterator sit(extensions.begin()); sit != extensions.end(); ++sit)
246         {
247                 for (std::list<std::string>::iterator eit(sit->second.begin()); eit != sit->second.end(); ++eit)
248                 {
249                         if (*eit == str)
250                                 return sit->first;
251                 }
252         }
253         return -1;
254 }
255
256 int eServiceCenter::getServiceTypeForExtension(const std::string &str)
257 {
258         return getServiceTypeForExtension(str.c_str());
259 }
260
261         /* default handlers */
262 RESULT iServiceHandler::info(const eServiceReference &, ePtr<iStaticServiceInformation> &ptr)
263 {
264         ptr = 0;
265         return -1;
266 }
267
268 #include <lib/service/event.h>
269
270 RESULT iStaticServiceInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &evt, time_t start_time)
271 {
272         evt = 0;
273         return -1;
274 }
275
276 int iStaticServiceInformation::getLength(const eServiceReference &ref)
277 {
278         return -1;
279 }
280
281 int iStaticServiceInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
282 {
283         return 0;
284 }
285
286 RESULT iServiceInformation::getEvent(ePtr<eServiceEvent> &evt, int m_nownext)
287 {
288         evt = 0;
289         return -1;
290 }
291
292 int iStaticServiceInformation::getInfo(const eServiceReference &ref, int w)
293 {
294         return -1;
295 }
296
297 std::string iStaticServiceInformation::getInfoString(const eServiceReference &ref, int w)
298 {
299         return "";
300 }
301
302 PyObject *iStaticServiceInformation::getInfoObject(const eServiceReference &ref, int w)
303 {
304         Py_RETURN_NONE;
305 }
306
307 int iServiceInformation::getInfo(int w)
308 {
309         return -1;
310 }
311
312 std::string iServiceInformation::getInfoString(int w)
313 {
314         return "";
315 }
316
317 PyObject* iServiceInformation::getInfoObject(int w)
318 {
319         Py_RETURN_NONE;
320 }
321
322 int iStaticServiceInformation::setInfo(const eServiceReference &ref, int w, int v)
323 {
324         return -1;
325 }
326
327 int iStaticServiceInformation::setInfoString(const eServiceReference &ref, int w, const char *v)
328 {
329         return -1;
330 }
331
332 int iServiceInformation::setInfo(int w, int v)
333 {
334         return -1;
335 }
336
337 int iServiceInformation::setInfoString(int w, const char *v)
338 {
339         return -1;
340 }
341
342 eAutoInitPtr<eServiceCenter> init_eServiceCenter(eAutoInitNumbers::service, "eServiceCenter");