fix possible segfault
[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/python/python.h>
6 #include <lib/base/object.h>
7 #include <string>
8 #include <connection.h>
9 #include <list>
10
11 class eServiceEvent;
12
13 class eServiceReference
14 {
15 public:
16         enum
17         {
18                 idInvalid=-1,
19                 idStructure,    // service_id == 0 is root
20                 idDVB,
21                 idFile,
22                 idUser=0x1000
23         };
24         int type;
25
26         enum
27         {
28                 isDirectory=1,          // SHOULD enter  (implies mustDescent)
29                 mustDescent=2,          // cannot be played directly - often used with "isDirectory" (implies canDescent)
30                 /*
31                         for example:
32                                 normal services have none of them - they can be fed directly into the "play"-handler.
33                                 normal directories have both of them set - you cannot play a directory directly and the UI should descent into it.
34                                 playlists have "mustDescent", but not "isDirectory" - you don't want the user to browse inside the playlist (unless he really wants)
35                                 services with sub-services have none of them, instead the have the "canDecsent" flag (as all of the above)
36                 */
37                 canDescent=4,                   // supports enterDirectory/leaveDirectory
38                 flagDirectory=isDirectory|mustDescent|canDescent,
39                 shouldSort=8,                   // should be ASCII-sorted according to service_name. great for directories.
40                 hasSortKey=16,          // has a sort key in data[3]. not having a sort key implies 0.
41                 sort1=32,                                       // sort key is 1 instead of 0
42                 isMarker=64,                    // Marker
43                 isGroup=128                     // is a group of services
44         };
45         int flags; // flags will NOT be compared.
46
47         inline int getSortKey() const { return (flags & hasSortKey) ? data[3] : ((flags & sort1) ? 1 : 0); }
48
49 #ifndef SWIG
50         int data[8];
51         std::string path;
52 #endif
53         std::string getPath() { return path; }
54         void setPath( const std::string &n ) { path=n; }
55
56         unsigned int getUnsignedData(unsigned int num) const
57         {
58                 if ( num < sizeof(data)/sizeof(int) )
59                         return data[num];
60                 return 0;
61         }
62
63         int getData(unsigned int num) const
64         {
65                 if ( num < sizeof(data)/sizeof(int) )
66                         return data[num];
67                 return 0;
68         }
69
70         void setUnsignedData(unsigned int num, unsigned int val)
71         {
72                 if ( num < sizeof(data)/sizeof(int) )
73                         data[num] = val;
74         }
75
76         void setData(unsigned int num, int val)
77         {
78                 if ( num < sizeof(data)/sizeof(int) )
79                         data[num] = val;
80         }
81
82 // only for override service names in bouquets or to give servicerefs a name which not have a
83 // real existing service ( for dvb eServiceDVB )
84 #ifndef SWIG
85         std::string name;
86 #endif
87         std::string getName() { return name; }
88         void setName( const std::string &n ) { name=n; }
89
90         eServiceReference()
91                 : type(idInvalid), flags(0)
92         {
93                 memset(data, 0, sizeof(data));
94         }
95 #ifndef SWIG
96         eServiceReference(int type, int flags)
97                 : type(type), flags(flags)
98         {
99                 memset(data, 0, sizeof(data));
100         }
101         eServiceReference(int type, int flags, int data0)
102                 : type(type), flags(flags)
103         {
104                 memset(data, 0, sizeof(data));
105                 data[0]=data0;
106         }
107         eServiceReference(int type, int flags, int data0, int data1)
108                 : type(type), flags(flags)
109         {
110                 memset(data, 0, sizeof(data));
111                 data[0]=data0;
112                 data[1]=data1;
113         }
114         eServiceReference(int type, int flags, int data0, int data1, int data2)
115                 : type(type), flags(flags)
116         {
117                 memset(data, 0, sizeof(data));
118                 data[0]=data0;
119                 data[1]=data1;
120                 data[2]=data2;
121         }
122         eServiceReference(int type, int flags, int data0, int data1, int data2, int data3)
123                 : type(type), flags(flags)
124         {
125                 memset(data, 0, sizeof(data));
126                 data[0]=data0;
127                 data[1]=data1;
128                 data[2]=data2;
129                 data[3]=data3;
130         }
131         eServiceReference(int type, int flags, int data0, int data1, int data2, int data3, int data4)
132                 : type(type), flags(flags)
133         {
134                 memset(data, 0, sizeof(data));
135                 data[0]=data0;
136                 data[1]=data1;
137                 data[2]=data2;
138                 data[3]=data3;
139                 data[4]=data4;
140         }
141 #endif
142         eServiceReference(int type, int flags, const std::string &path)
143                 : type(type), flags(flags), path(path)
144         {
145                 memset(data, 0, sizeof(data));
146         }
147         eServiceReference(const std::string &string);
148         std::string toString() const;
149         std::string toCompareString() const;
150         bool operator==(const eServiceReference &c) const
151         {
152                 if (type != c.type)
153                         return 0;
154                 return (memcmp(data, c.data, sizeof(int)*8)==0) && (path == c.path);
155         }
156         bool operator!=(const eServiceReference &c) const
157         {
158                 return !(*this == c);
159         }
160         bool operator<(const eServiceReference &c) const
161         {
162                 if (type < c.type)
163                         return 1;
164
165                 if (type > c.type)
166                         return 0;
167
168                 int r=memcmp(data, c.data, sizeof(int)*8);
169                 if (r)
170                         return r < 0;
171                 return path < c.path;
172         }
173         operator bool() const
174         {
175                 return valid();
176         }
177         
178         int valid() const
179         {
180                 return type != idInvalid;
181         }
182 };
183
184 SWIG_ALLOW_OUTPUT_SIMPLE(eServiceReference);
185
186 extern PyObject *New_eServiceReference(const eServiceReference &ref); // defined in enigma_python.i
187
188 #ifndef SWIG
189 #ifdef PYTHON_REFCOUNT_DEBUG
190 inline ePyObject Impl_New_eServiceReference(const char* file, int line, const eServiceReference &ref)
191 {
192         return ePyObject(New_eServiceReference(ref), file, line);
193 }
194 #define NEW_eServiceReference(ref) Impl_New_eServiceReference(__FILE__, __LINE__, ref)
195 #else
196 inline ePyObject Impl_New_eServiceReference(const eServiceReference &ref)
197 {
198         return New_eServiceReference(ref);
199 }
200 #define NEW_eServiceReference(ref) Impl_New_eServiceReference(ref)
201 #endif
202 #endif // SWIG
203
204 typedef long long pts_t;
205
206         /* the reason we have the servicereference as additional argument is
207            that we don't have to create one object for every entry in a possibly
208            large list, provided that no state information is nessesary to deliver
209            the required information. Anyway - ref *must* be the same as the argument
210            to the info() or getIServiceInformation call! */
211
212         /* About the usage of SWIG_VOID:
213            SWIG_VOID(real_returntype_t) hides a return value from swig. This is used for
214            the "superflouus" RESULT return values.
215            
216            Python code has to check the returned pointer against 0. This works,
217            as all functions returning instances in smartpointers AND having a 
218            RESULT have to BOTH return non-zero AND set the pointer to zero.
219            
220            Python code thus can't check for the reason, but the reason isn't
221            user-servicable anyway. If you want to return a real reason which
222            goes beyong "it just doesn't work", use extra variables for this,
223            not the RESULT.
224            
225            Hide the result only if there is another way to check for failure! */
226            
227 TEMPLATE_TYPEDEF(ePtr<eServiceEvent>, eServiceEventPtr);
228         
229 class iStaticServiceInformation: public iObject
230 {
231 #ifdef SWIG
232         iStaticServiceInformation();
233         ~iStaticServiceInformation();
234 #endif
235 public:
236         virtual SWIG_VOID(RESULT) getName(const eServiceReference &ref, std::string &SWIG_OUTPUT)=0;
237         
238                 // doesn't need to be implemented, should return -1 then.
239         virtual int getLength(const eServiceReference &ref);
240         virtual SWIG_VOID(RESULT) getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT, time_t start_time=-1);
241                 // returns true when not implemented
242         virtual int isPlayable(const eServiceReference &ref, const eServiceReference &ignore);
243
244         virtual int getInfo(const eServiceReference &ref, int w);
245         virtual std::string getInfoString(const eServiceReference &ref,int w);
246
247         virtual int setInfo(const eServiceReference &ref, int w, int v);
248         virtual int setInfoString(const eServiceReference &ref, int w, const char *v);
249 };
250
251 TEMPLATE_TYPEDEF(ePtr<iStaticServiceInformation>, iStaticServiceInformationPtr);
252
253 class iServiceInformation: public iObject
254 {
255 #ifdef SWIG
256         iServiceInformation();
257         ~iServiceInformation();
258 #endif
259 public:
260         virtual SWIG_VOID(RESULT) getName(std::string &SWIG_OUTPUT)=0;
261         virtual SWIG_VOID(RESULT) getEvent(ePtr<eServiceEvent> &SWIG_OUTPUT, int nownext);
262
263         enum {
264                 sIsCrypted,  /* is encrypted (no indication if decrypt was possible) */
265                 sAspect,     /* aspect ratio: 0=4:3, 1=16:9, 2=whatever we need */
266                 sIsMultichannel, /* multichannel *available* (probably not selected) */
267                 
268                         /* "user serviceable info" - they are not reliable. Don't use them for anything except the service menu!
269                            that's also the reason why they are so globally defined. 
270                            
271                            
272                            again - if somebody EVER tries to use this information for anything else than simply displaying it,
273                            i will change this to return a user-readable text like "zero x zero three three" (and change the
274                            exact spelling in every version) to stop that!
275                         */
276                 sVideoPID,
277                 sAudioPID,
278                 sPCRPID,
279                 sPMTPID,
280                 sTXTPID,
281                 
282                 sSID,
283                 sONID,
284                 sTSID,
285                 sNamespace,
286                 sProvider,
287                 
288                 sDescription,
289                 sServiceref,
290                 sTimeCreate,    // unix time or string
291                 
292                 sTitle,
293                 sArtist,
294                 sAlbum,
295                 sComment,
296                 sTracknumber,
297                 sGenre,
298                 sCAIDs,
299                 sVideoType,  // MPEG2 MPEG4
300                 
301                 sTags,  /* space seperated list of tags */
302         };
303         enum { resNA = -1, resIsString = -2, resIsPyObject = -3 };
304
305         virtual int getInfo(int w);
306         virtual std::string getInfoString(int w);
307         virtual PyObject *getInfoObject(int w);
308         
309         virtual int setInfo(int w, int v);
310         virtual int setInfoString(int w, const char *v);
311 };
312
313 TEMPLATE_TYPEDEF(ePtr<iServiceInformation>, iServiceInformationPtr);
314
315 class iFrontendInformation: public iObject
316 {
317 #ifdef SWIG
318         iFrontendInformation();
319         ~iFrontendInformation();
320 #endif
321 public:
322         enum {
323                 bitErrorRate,
324                 signalPower,
325                 signalQuality,
326                 lockState,
327                 syncState,
328                 frontendNumber
329         };
330         virtual int getFrontendInfo(int w)=0;
331         virtual PyObject *getFrontendData(bool original=false)=0;
332 };
333
334 TEMPLATE_TYPEDEF(ePtr<iFrontendInformation>, iFrontendInformationPtr);
335
336 class iPauseableService: public iObject
337 {
338 #ifdef SWIG
339         iPausableService();
340         ~iPausableService();
341 #endif
342 public:
343         virtual RESULT pause()=0;
344         virtual RESULT unpause()=0;
345         
346                 /* hm. */
347         virtual RESULT setSlowMotion(int ratio=0)=0;
348         virtual RESULT setFastForward(int ratio=0)=0;
349 };
350
351 TEMPLATE_TYPEDEF(ePtr<iPauseableService>, iPauseableServicePtr);
352
353 class iSeekableService: public iObject
354 {
355 #ifdef SWIG
356         iSeekableService();
357         ~iSeekableService();
358 #endif
359 public:
360         virtual RESULT getLength(pts_t &SWIG_OUTPUT)=0;
361         virtual RESULT seekTo(pts_t to)=0;
362         enum { dirForward = +1, dirBackward = -1 };
363         virtual RESULT seekRelative(int direction, pts_t to)=0;
364         virtual RESULT getPlayPosition(pts_t &SWIG_OUTPUT)=0;
365                 /* if you want to do several seeks in a row, you can enable the trickmode. 
366                    audio will be switched off, sync will be disabled etc. */
367         virtual RESULT setTrickmode(int trick=0)=0;
368         virtual RESULT isCurrentlySeekable()=0;
369 };
370
371 TEMPLATE_TYPEDEF(ePtr<iSeekableService>, iSeekableServicePtr);
372
373 struct iAudioTrackInfo
374 {
375 #ifndef SWIG
376         std::string m_description;
377         std::string m_language; /* iso639 */
378 #endif
379         std::string getDescription() { return m_description; }
380         std::string getLanguage() { return m_language; }
381 };
382
383 SWIG_ALLOW_OUTPUT_SIMPLE(iAudioTrackInfo);
384
385 class iAudioTrackSelection: public iObject
386 {
387 #ifdef SWIG
388         iAudioTrackSelection();
389         ~iAudioTrackSelection();
390 #endif
391 public:
392         virtual int getNumberOfTracks()=0;
393         virtual RESULT selectTrack(unsigned int i)=0;
394         virtual SWIG_VOID(RESULT) getTrackInfo(struct iAudioTrackInfo &SWIG_OUTPUT, unsigned int n)=0;
395 };
396
397 TEMPLATE_TYPEDEF(ePtr<iAudioTrackSelection>, iAudioTrackSelectionPtr);
398
399 class iAudioChannelSelection: public iObject
400 {
401 #ifdef SWIG
402         iAudioChannelSelection();
403         ~iAudioChannelSelection();
404 #endif
405 public:
406         enum { LEFT, STEREO, RIGHT };
407         virtual int getCurrentChannel()=0;
408         virtual RESULT selectChannel(int i)=0;
409 };
410
411 TEMPLATE_TYPEDEF(ePtr<iAudioChannelSelection>, iAudioChannelSelectionPtr);
412
413 class iAudioDelay: public iObject
414 {
415 #ifdef SWIG
416         iAudioDelay();
417         ~iAudioDelay();
418 #endif
419 public:
420         virtual int getAC3Delay()=0;
421         virtual int getPCMDelay()=0;
422         virtual void setAC3Delay(int)=0;
423         virtual void setPCMDelay(int)=0;
424 };
425
426 TEMPLATE_TYPEDEF(ePtr<iAudioDelay>, iAudioDelayPtr);
427
428 class iRadioText: public iObject
429 {
430 #ifdef SWIG
431         iRadioText();
432         ~iRadioText();
433 #endif
434 public:
435         virtual std::string getRadioText(int x=0)=0;
436 };
437
438 TEMPLATE_TYPEDEF(ePtr<iRadioText>, iRadioTextPtr);
439
440 class iSubserviceList: public iObject
441 {
442 #ifdef SWIG
443         iSubserviceList();
444         ~iSubserviceList();
445 #endif
446 public:
447         virtual int getNumberOfSubservices()=0;
448         virtual SWIG_VOID(RESULT) getSubservice(eServiceReference &SWIG_OUTPUT, unsigned int n)=0;
449 };
450
451 TEMPLATE_TYPEDEF(ePtr<iSubserviceList>, iSubserviceListPtr);
452
453 class iTimeshiftService: public iObject
454 {
455 #ifdef SWIG
456         iTimeshiftService();
457         ~iTimeshiftService();
458 #endif
459 public:
460         virtual RESULT startTimeshift()=0;
461         virtual RESULT stopTimeshift()=0;
462         
463         virtual int isTimeshiftActive()=0;
464                         /* this essentially seeks to the relative end of the timeshift buffer */
465         virtual RESULT activateTimeshift()=0;
466 };
467
468 TEMPLATE_TYPEDEF(ePtr<iTimeshiftService>, iTimeshiftServicePtr);
469
470         /* not related to eCueSheet */
471 class iCueSheet: public iObject
472 {
473 #ifdef SWIG
474         iCueSheet();
475         ~iCueSheet();
476 #endif
477 public:
478                         /* returns a list of (pts, what)-tuples */
479         virtual PyObject *getCutList() = 0;
480         virtual void setCutList(SWIG_PYOBJECT(ePyObject) list) = 0;
481         virtual void setCutListEnable(int enable) = 0;
482         enum { cutIn = 0, cutOut = 1, cutMark = 2 };
483 };
484
485 TEMPLATE_TYPEDEF(ePtr<iCueSheet>, iCueSheetPtr);
486
487 class eWidget;
488 class PyList;
489
490 class iSubtitleOutput: public iObject
491 {
492 public:
493         virtual RESULT enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry)=0;
494         virtual RESULT disableSubtitles(eWidget *parent)=0;
495         virtual PyObject *getSubtitleList()=0;
496         virtual PyObject *getCachedSubtitle()=0;
497 };
498
499 TEMPLATE_TYPEDEF(ePtr<iSubtitleOutput>, iSubtitleOutputPtr);
500
501 class iPlayableService: public iObject
502 {
503 #ifdef SWIG
504         iPlayableService();
505         ~iPlaybleService();
506 #endif
507         friend class iServiceHandler;
508 public:
509         enum
510         {
511                         /* these first two events are magical, and should only
512                            be generated if you know what you're doing. */
513                 evStart,
514                 evEnd,
515                 
516                 evTuneFailed,
517                         // when iServiceInformation is implemented:
518                 evUpdatedEventInfo,
519                 evUpdatedInfo,
520
521                         /* when seek() is implemented: */               
522                 evSeekableStatusChanged, /* for example when timeshifting */
523                 
524                 evEOF,
525                 evSOF, /* bounced against start of file (when seeking backwards) */
526                 
527                         /* only when cueSheet is implemented */
528                 evCuesheetChanged,
529
530                 evUpdatedRadioText
531         };
532 #ifndef SWIG
533         virtual RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)=0;
534 #endif
535         virtual RESULT start()=0;
536         virtual RESULT stop()=0;
537                         /* might have to be changed... */
538         virtual RESULT setTarget(int target)=0;
539         virtual SWIG_VOID(RESULT) seek(ePtr<iSeekableService> &SWIG_OUTPUT)=0;
540         virtual SWIG_VOID(RESULT) pause(ePtr<iPauseableService> &SWIG_OUTPUT)=0;
541         virtual SWIG_VOID(RESULT) info(ePtr<iServiceInformation> &SWIG_OUTPUT)=0;
542         virtual SWIG_VOID(RESULT) audioTracks(ePtr<iAudioTrackSelection> &SWIG_OUTPUT)=0;
543         virtual SWIG_VOID(RESULT) audioChannel(ePtr<iAudioChannelSelection> &SWIG_OUTPUT)=0;
544         virtual SWIG_VOID(RESULT) subServices(ePtr<iSubserviceList> &SWIG_OUTPUT)=0;
545         virtual SWIG_VOID(RESULT) frontendInfo(ePtr<iFrontendInformation> &SWIG_OUTPUT)=0;
546         virtual SWIG_VOID(RESULT) timeshift(ePtr<iTimeshiftService> &SWIG_OUTPUT)=0;
547         virtual SWIG_VOID(RESULT) cueSheet(ePtr<iCueSheet> &SWIG_OUTPUT)=0;
548         virtual SWIG_VOID(RESULT) subtitle(ePtr<iSubtitleOutput> &SWIG_OUTPUT)=0;
549         virtual SWIG_VOID(RESULT) audioDelay(ePtr<iAudioDelay> &SWIG_OUTPUT)=0;
550         virtual SWIG_VOID(RESULT) radioText(ePtr<iRadioText> &SWIG_OUTPUT)=0;
551 };
552
553 TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
554
555 class iRecordableService: public iObject
556 {
557 #ifdef SWIG
558         iRecordableService();
559         ~iRecordableService();
560 #endif
561 public:
562         enum
563         {
564                 evStart,
565                 evStop,
566                 evTunedIn,
567                 evTuneFailed,
568                 evRecordRunning,
569                 evRecordStopped,
570                 evNewProgramInfo,
571                 evRecordFailed
572 //              evDiskFull
573         };
574         enum
575         {
576                 NoError=0,
577                 errOpenRecordFile=-1,
578                 errNoDemuxAvailable=-2,
579                 errNoTsRecorderAvailable=-3,
580                 errDiskFull=-4,
581                 errTuneFailed=-255
582         };
583 #ifndef SWIG
584         virtual RESULT connectEvent(const Slot2<void,iRecordableService*,int> &event, ePtr<eConnection> &connection)=0;
585 #endif
586         virtual RESULT getError(int &)=0;
587         virtual RESULT prepare(const char *filename, time_t begTime=-1, time_t endTime=-1, int eit_event_id=-1)=0;
588         virtual RESULT start()=0;
589         virtual RESULT stop()=0;
590         virtual SWIG_VOID(RESULT) frontendInfo(ePtr<iFrontendInformation> &SWIG_OUTPUT)=0;
591 };
592
593 TEMPLATE_TYPEDEF(ePtr<iRecordableService>, iRecordableServicePtr);
594
595 extern PyObject *New_iRecordableServicePtr(const ePtr<iRecordableService> &ref); // defined in enigma_python.i
596
597 inline PyObject *PyFrom(ePtr<iRecordableService> &c)
598 {
599         return New_iRecordableServicePtr(c);
600 }
601
602 #ifndef SWIG
603 #ifdef PYTHON_REFCOUNT_DEBUG
604 inline ePyObject Impl_New_iRecordableServicePtr(const char* file, int line, const ePtr<iRecordableService> &ptr)
605 {
606         return ePyObject(New_iRecordableServicePtr(ptr), file, line);
607 }
608 #define NEW_iRecordableServicePtr(ptr) Impl_New_iRecordableServicePtr(__FILE__, __LINE__, ptr)
609 #else
610 inline ePyObject Impl_New_iRecordableServicePtr(const ePtr<iRecordableService> &ptr)
611 {
612         return New_iRecordableServicePtr(ptr);
613 }
614 #define NEW_iRecordableServicePtr(ptr) Impl_New_iRecordableServicePtr(ptr)
615 #endif
616 #endif // SWIG
617
618 // TEMPLATE_TYPEDEF(std::list<eServiceReference>, eServiceReferenceList);
619
620 class iMutableServiceList: public iObject
621 {
622 #ifdef SWIG
623         iMutableServiceList();
624         ~iMutableServiceList();
625 #endif
626 public:
627                 /* flush changes */
628         virtual RESULT flushChanges()=0;
629                 /* adds a service to a list */
630         virtual RESULT addService(eServiceReference &ref, eServiceReference before=eServiceReference())=0;
631                 /* removes a service from a list */
632         virtual RESULT removeService(eServiceReference &ref)=0;
633                 /* moves a service in a list, only if list suppports a specific sort method. */
634                 /* pos is the new, absolute position from 0..size-1 */
635         virtual RESULT moveService(eServiceReference &ref, int pos)=0;
636                 /* set name of list, for bouquets this is the visible bouquet name */
637         virtual RESULT setListName(const std::string &name)=0;
638 };
639
640 TEMPLATE_TYPEDEF(ePtr<iMutableServiceList>, iMutableServiceListPtr);
641
642 class iListableService: public iObject
643 {
644 #ifdef SWIG
645         iListableService();
646         ~iListableService();
647 #endif
648 public:
649                 /* legacy interface: get a list */
650         virtual RESULT getContent(std::list<eServiceReference> &list, bool sorted=false)=0;
651         virtual PyObject *getContent(const char* format, bool sorted=false)=0;
652
653                 /* new, shiny interface: streaming. */
654         virtual SWIG_VOID(RESULT) getNext(eServiceReference &SWIG_OUTPUT)=0;
655         
656                 /* use this for sorting. output is not sorted because of either
657                  - performance reasons: the whole list must be buffered or
658                  - the interface would be restricted to a list. streaming
659                    (as well as a future "active" extension) won't be possible.
660                 */
661         virtual int compareLessEqual(const eServiceReference &, const eServiceReference &)=0;
662         
663         virtual SWIG_VOID(RESULT) startEdit(ePtr<iMutableServiceList> &SWIG_OUTPUT)=0;
664 };
665
666 TEMPLATE_TYPEDEF(ePtr<iListableService>, iListableServicePtr);
667
668 #ifndef SWIG
669         /* a helper class which can be used as argument to stl's sort(). */
670 class iListableServiceCompare
671 {
672         ePtr<iListableService> m_list;
673 public:
674         iListableServiceCompare(iListableService *list): m_list(list) { }
675         bool operator()(const eServiceReference &a, const eServiceReference &b)
676         {
677                 return m_list->compareLessEqual(a, b);
678         }
679 };
680 #endif
681
682 class iServiceOfflineOperations: public iObject
683 {
684 #ifdef SWIG
685         iServiceOfflineOperations();
686         ~iServiceOfflineOperations();
687 #endif
688 public:
689                 /* to delete a service, forever. */
690         virtual RESULT deleteFromDisk(int simulate=1)=0;
691         
692                 /* for transferring a service... */
693         virtual SWIG_VOID(RESULT) getListOfFilenames(std::list<std::string> &SWIG_OUTPUT)=0;
694         
695                 // TODO: additional stuff, like a conversion interface?
696 };
697
698 TEMPLATE_TYPEDEF(ePtr<iServiceOfflineOperations>, iServiceOfflineOperationsPtr);
699
700 class iServiceHandler: public iObject
701 {
702 #ifdef SWIG
703         iServiceHandler();
704         ~iServiceHandler();
705 #endif
706 public:
707         virtual SWIG_VOID(RESULT) play(const eServiceReference &, ePtr<iPlayableService> &SWIG_OUTPUT)=0;
708         virtual SWIG_VOID(RESULT) record(const eServiceReference &, ePtr<iRecordableService> &SWIG_OUTPUT)=0;
709         virtual SWIG_VOID(RESULT) list(const eServiceReference &, ePtr<iListableService> &SWIG_OUTPUT)=0;
710         virtual SWIG_VOID(RESULT) info(const eServiceReference &, ePtr<iStaticServiceInformation> &SWIG_OUTPUT)=0;
711         virtual SWIG_VOID(RESULT) offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &SWIG_OUTPUT)=0;
712 };
713
714 TEMPLATE_TYPEDEF(ePtr<iServiceHandler>, iServiceHandlerPtr);
715
716 #endif