ab95ef79abe49e58c719f453e4cf68ee82ce3d89
[enigma2.git] / lib / service / iservice.h
1 #ifndef __lib_dvb_iservice_h
2 #define __lib_dvb_iservice_h
3
4 #include <lib/python/swig.h>
5 #include <lib/base/object.h>
6 #include <lib/service/event.h>
7 #include <string>
8 #include <connection.h>
9 #include <list>
10
11 class eServiceReference
12 {
13 public:
14         enum
15         {
16                 idInvalid=-1,
17                 idStructure,    // service_id == 0 is root
18                 idDVB,
19                 idFile,
20                 idUser=0x1000
21         };
22         int type;
23
24         int flags; // flags will NOT be compared.
25         enum
26         {
27                 isDirectory=1,          // SHOULD enter  (implies mustDescent)
28                 mustDescent=2,          // cannot be played directly - often used with "isDirectory" (implies canDescent)
29                 /*
30                         for example:
31                                 normal services have none of them - they can be fed directly into the "play"-handler.
32                                 normal directories have both of them set - you cannot play a directory directly and the UI should descent into it.
33                                 playlists have "mustDescent", but not "isDirectory" - you don't want the user to browse inside the playlist (unless he really wants)
34                                 services with sub-services have none of them, instead the have the "canDecsent" flag (as all of the above)
35                 */
36                 canDescent=4,                   // supports enterDirectory/leaveDirectory
37                 flagDirectory=isDirectory|mustDescent|canDescent,
38                 shouldSort=8,                   // should be ASCII-sorted according to service_name. great for directories.
39                 hasSortKey=16,          // has a sort key in data[3]. not having a sort key implies 0.
40                 sort1=32                                        // sort key is 1 instead of 0
41         };
42
43         inline int getSortKey() const { return (flags & hasSortKey) ? data[3] : ((flags & sort1) ? 1 : 0); }
44
45         int data[8];
46         std::string path;
47         std::string getPath() { return path; }
48
49 // only for override service names in bouquets or to give servicerefs a name which not have a
50 // real existing service ( for dvb eServiceDVB )
51         std::string name;
52         std::string getName() { return name; }
53
54         eServiceReference()
55                 : type(idInvalid), flags(0)
56         {
57         }
58
59         eServiceReference(int type, int flags)
60                 : type(type), flags(flags)
61         {
62                 memset(data, 0, sizeof(data));
63         }
64         eServiceReference(int type, int flags, int data0)
65                 : type(type), flags(flags)
66         {
67                 memset(data, 0, sizeof(data));
68                 data[0]=data0;
69         }
70         eServiceReference(int type, int flags, int data0, int data1)
71                 : type(type), flags(flags)
72         {
73                 memset(data, 0, sizeof(data));
74                 data[0]=data0;
75                 data[1]=data1;
76         }
77         eServiceReference(int type, int flags, int data0, int data1, int data2)
78                 : type(type), flags(flags)
79         {
80                 memset(data, 0, sizeof(data));
81                 data[0]=data0;
82                 data[1]=data1;
83                 data[2]=data2;
84         }
85         eServiceReference(int type, int flags, int data0, int data1, int data2, int data3)
86                 : type(type), flags(flags)
87         {
88                 memset(data, 0, sizeof(data));
89                 data[0]=data0;
90                 data[1]=data1;
91                 data[2]=data2;
92                 data[3]=data3;
93         }
94         eServiceReference(int type, int flags, int data0, int data1, int data2, int data3, int data4)
95                 : type(type), flags(flags)
96         {
97                 memset(data, 0, sizeof(data));
98                 data[0]=data0;
99                 data[1]=data1;
100                 data[2]=data2;
101                 data[3]=data3;
102                 data[4]=data4;
103         }
104         eServiceReference(int type, int flags, const std::string &path)
105                 : type(type), flags(flags), path(path)
106         {
107                 memset(data, 0, sizeof(data));
108         }
109         eServiceReference(const std::string &string);
110         std::string toString() const;
111         bool operator==(const eServiceReference &c) const
112         {
113                 if (type != c.type)
114                         return 0;
115                 return (memcmp(data, c.data, sizeof(int)*8)==0) && (path == c.path);
116         }
117         bool operator!=(const eServiceReference &c) const
118         {
119                 return !(*this == c);
120         }
121         bool operator<(const eServiceReference &c) const
122         {
123                 if (type < c.type)
124                         return 1;
125
126                 if (type > c.type)
127                         return 0;
128
129                 int r=memcmp(data, c.data, sizeof(int)*8);
130                 if (r)
131                         return r < 0;
132                 return path < c.path;
133         }
134         operator bool() const
135         {
136                 return valid();
137         }
138         
139         int valid() const
140         {
141                 return type != idInvalid;
142         }
143 };
144
145 SWIG_ALLOW_OUTPUT_SIMPLE(eServiceReference);
146
147 typedef long long pts_t;
148
149         /* the reason we have the servicereference as additional argument is
150            that we don't have to create one object for every entry in a possibly
151            large list, provided that no state information is nessesary to deliver
152            the required information. Anyway - ref *must* be the same as the argument
153            to the info() or getIServiceInformation call! */
154
155         /* About the usage of SWIG_VOID:
156            SWIG_VOID(real_returntype_t) hides a return value from swig. This is used for
157            the "superflouus" RESULT return values.
158            
159            Python code has to check the returned pointer against 0. This works,
160            as all functions returning instances in smartpointers AND having a 
161            RESULT have to BOTH return non-zero AND set the pointer to zero.
162            
163            Python code thus can't check for the reason, but the reason isn't
164            user-servicable anyway. If you want to return a real reason which
165            goes beyong "it just doesn't work", use extra variables for this,
166            not the RESULT.
167            
168            Hide the result only if there is another way to check for failure! */
169            
170 class iStaticServiceInformation: public iObject
171 {
172 public:
173         virtual SWIG_VOID(RESULT) getName(const eServiceReference &ref, std::string &SWIG_OUTPUT)=0;
174         
175                 // doesn't need to be implemented, should return -1 then.
176         virtual int getLength(const eServiceReference &ref);
177         virtual SWIG_VOID(RESULT) getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT);
178 };
179
180 TEMPLATE_TYPEDEF(ePtr<iStaticServiceInformation>, iStaticServiceInformationPtr);
181
182 class eServiceEvent;
183
184 TEMPLATE_TYPEDEF(ePtr<eServiceEvent>, eServiceEventPtr);
185
186 class iServiceInformation: public iObject
187 {
188 public:
189         virtual SWIG_VOID(RESULT) getName(std::string &SWIG_OUTPUT)=0;
190         virtual SWIG_VOID(RESULT) getEvent(ePtr<eServiceEvent> &SWIG_OUTPUT, int nownext);
191
192         enum { 
193                 sIsCrypted,  /* is encrypted (no indication if decrypt was possible) */
194                 sAspect,     /* aspect ratio: 0=4:3, 1=16:9, 2=whatever we need */
195                 sIsMultichannel, /* multichannel *available* (probably not selected) */
196                 
197                         /* "user serviceable info" - they are not reliable. Don't use them for anything except the service menu!
198                            that's also the reason why they are so globally defined. 
199                            
200                            
201                            again - if somebody EVER tries to use this information for anything else than simply displaying it,
202                            i will change this to return a user-readable text like "zero x zero three three" (and change the
203                            exact spelling in every version) to stop that!
204                         */
205                 sVideoPID,
206                 sAudioPID,
207                 sPCRPID,
208                 sPMTPID,
209                 sTXTPID,
210                 
211                 sSID,
212                 sONID,
213                 sTSID,
214                 sNamespace,
215                 sProvider,
216         };
217         enum { resNA = -1, resIsString = -2 };
218
219         virtual int getInfo(int w);
220         virtual std::string getInfoString(int w);
221 };
222
223 TEMPLATE_TYPEDEF(ePtr<iServiceInformation>, iServiceInformationPtr);
224
225 class iPauseableService: public iObject
226 {
227 public:
228         virtual RESULT pause()=0;
229         virtual RESULT unpause()=0;
230 };
231
232 TEMPLATE_TYPEDEF(ePtr<iPauseableService>, iPauseableServicePtr);
233
234 class iSeekableService: public iObject
235 {
236 public:
237         virtual RESULT getLength(pts_t &SWIG_OUTPUT)=0;
238         virtual RESULT seekTo(pts_t to)=0;
239         enum { dirForward = +1, dirBackward = -1 };
240         virtual RESULT seekRelative(int direction, pts_t to)=0;
241         virtual RESULT getPlayPosition(pts_t &SWIG_OUTPUT)=0;
242 };
243
244 TEMPLATE_TYPEDEF(ePtr<iSeekableService>, iSeekableServicePtr);
245
246 struct iAudioTrackInfo
247 {
248         std::string m_description;
249         std::string m_language; /* iso639 */
250         
251         std::string getDescription() { return m_description; }
252         std::string getLanguage() { return m_language; }
253 };
254
255 SWIG_ALLOW_OUTPUT_SIMPLE(iAudioTrackInfo);
256
257 class iAudioTrackSelection: public iObject
258 {
259 public:
260         virtual int getNumberOfTracks()=0;
261         virtual RESULT selectTrack(unsigned int i)=0;
262         virtual SWIG_VOID(RESULT) getTrackInfo(struct iAudioTrackInfo &SWIG_OUTPUT, unsigned int n)=0;
263 };
264
265 TEMPLATE_TYPEDEF(ePtr<iAudioTrackSelection>, iAudioTrackSelectionPtr);
266
267
268 class iPlayableService: public iObject
269 {
270         friend class iServiceHandler;
271 public:
272         enum
273         {
274                 evStart,
275                 evEnd,
276                 
277                 evTuneFailed,
278                         // when iServiceInformation is implemented:
279                 evUpdatedEventInfo,
280                 evUpdatedInfo,
281         };
282         virtual RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)=0;
283         virtual RESULT start()=0;
284         virtual RESULT stop()=0;
285         virtual SWIG_VOID(RESULT) seek(ePtr<iSeekableService> &SWIG_OUTPUT)=0;
286         virtual SWIG_VOID(RESULT) pause(ePtr<iPauseableService> &SWIG_OUTPUT)=0;
287         virtual SWIG_VOID(RESULT) info(ePtr<iServiceInformation> &SWIG_OUTPUT)=0;
288         virtual SWIG_VOID(RESULT) audioTracks(ePtr<iAudioTrackSelection> &SWIG_OUTPUT)=0;
289 };
290
291 TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
292
293 class iRecordableService: public iObject
294 {
295 public:
296         virtual RESULT prepare(const char *filename)=0;
297         virtual RESULT start()=0;
298         virtual RESULT stop()=0;
299 };
300
301 TEMPLATE_TYPEDEF(ePtr<iRecordableService>, iRecordableServicePtr);
302
303 // TEMPLATE_TYPEDEF(std::list<eServiceReference>, eServiceReferenceList);
304
305 class iMutableServiceList: public iObject
306 {
307 public:
308                 /* flush changes */
309         virtual RESULT flushChanges()=0;
310                 /* adds a service to a list */
311         virtual RESULT addService(eServiceReference &ref)=0;
312                 /* removes a service from a list */
313         virtual RESULT removeService(eServiceReference &ref)=0;
314                 /* moves a service in a list, only if list suppports a specific sort method. */
315                 /* pos is the new, absolute position from 0..size-1 */
316         virtual RESULT moveService(eServiceReference &ref, int pos)=0;
317 };
318
319 TEMPLATE_TYPEDEF(ePtr<iMutableServiceList>, iMutableServiceListPtr);
320
321 class iListableService: public iObject
322 {
323 public:
324                 /* legacy interface: get a list */
325         virtual RESULT getContent(std::list<eServiceReference> &list)=0;
326         
327                 /* new, shiny interface: streaming. */
328         virtual SWIG_VOID(RESULT) getNext(eServiceReference &SWIG_OUTPUT)=0;
329         
330                 /* use this for sorting. output is not sorted because of either
331                  - performance reasons: the whole list must be buffered or
332                  - the interface would be restricted to a list. streaming
333                    (as well as a future "active" extension) won't be possible.
334                 */
335         virtual int compareLessEqual(const eServiceReference &, const eServiceReference &)=0;
336         
337         virtual SWIG_VOID(RESULT) startEdit(ePtr<iMutableServiceList> &SWIG_OUTPUT)=0;
338 };
339
340 TEMPLATE_TYPEDEF(ePtr<iListableService>, iListableServicePtr);
341
342         /* a helper class which can be used as argument to stl's sort(). */
343 class iListableServiceCompare
344 {
345         ePtr<iListableService> m_list;
346 public:
347         iListableServiceCompare(iListableService *list): m_list(list) { }
348         bool operator()(const eServiceReference &a, const eServiceReference &b)
349         {
350                 return m_list->compareLessEqual(a, b);
351         }
352 };
353
354 class iServiceOfflineOperations: public iObject
355 {
356 public:
357                 /* to delete a service, forever. */
358         virtual RESULT deleteFromDisk(int simulate=1)=0;
359         
360                 /* for transferring a service... */
361         virtual SWIG_VOID(RESULT) getListOfFilenames(std::list<std::string> &SWIG_OUTPUT)=0;
362         
363                 // TODO: additional stuff, like a conversion interface?
364 };
365
366 TEMPLATE_TYPEDEF(ePtr<iServiceOfflineOperations>, iServiceOfflineOperationsPtr);
367
368 class iServiceHandler: public iObject
369 {
370 public:
371         virtual SWIG_VOID(RESULT) play(const eServiceReference &, ePtr<iPlayableService> &SWIG_OUTPUT)=0;
372         virtual SWIG_VOID(RESULT) record(const eServiceReference &, ePtr<iRecordableService> &SWIG_OUTPUT)=0;
373         virtual SWIG_VOID(RESULT) list(const eServiceReference &, ePtr<iListableService> &SWIG_OUTPUT)=0;
374         virtual SWIG_VOID(RESULT) info(const eServiceReference &, ePtr<iStaticServiceInformation> &SWIG_OUTPUT)=0;
375         virtual SWIG_VOID(RESULT) offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &SWIG_OUTPUT)=0;
376 };
377
378 TEMPLATE_TYPEDEF(ePtr<iServiceHandler>, iServiceHandlerPtr);
379
380 #endif