add possibility to get a dict with transponderdata for servicerefs
[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         virtual PyObject *getInfoObject(const eServiceReference &ref, int w);
247         
248         virtual int setInfo(const eServiceReference &ref, int w, int v);
249         virtual int setInfoString(const eServiceReference &ref, int w, const char *v);
250 };
251
252 TEMPLATE_TYPEDEF(ePtr<iStaticServiceInformation>, iStaticServiceInformationPtr);
253
254 class iServiceInformation: public iObject
255 {
256 #ifdef SWIG
257         iServiceInformation();
258         ~iServiceInformation();
259 #endif
260 public:
261         virtual SWIG_VOID(RESULT) getName(std::string &SWIG_OUTPUT)=0;
262         virtual SWIG_VOID(RESULT) getEvent(ePtr<eServiceEvent> &SWIG_OUTPUT, int nownext);
263
264         enum {
265                 sIsCrypted,  /* is encrypted (no indication if decrypt was possible) */
266                 sAspect,     /* aspect ratio: 0=4:3, 1=16:9, 2=whatever we need */
267                 sIsMultichannel, /* multichannel *available* (probably not selected) */
268                 
269                         /* "user serviceable info" - they are not reliable. Don't use them for anything except the service menu!
270                            that's also the reason why they are so globally defined. 
271                            
272                            
273                            again - if somebody EVER tries to use this information for anything else than simply displaying it,
274                            i will change this to return a user-readable text like "zero x zero three three" (and change the
275                            exact spelling in every version) to stop that!
276                         */
277                 sVideoPID,
278                 sAudioPID,
279                 sPCRPID,
280                 sPMTPID,
281                 sTXTPID,
282                 
283                 sSID,
284                 sONID,
285                 sTSID,
286                 sNamespace,
287                 sProvider,
288                 
289                 sDescription,
290                 sServiceref,
291                 sTimeCreate,    // unix time or string
292                 
293                 sTitle,
294                 sArtist,
295                 sAlbum,
296                 sComment,
297                 sTracknumber,
298                 sGenre,
299                 sCAIDs,
300                 sVideoType,  // MPEG2 MPEG4
301                 
302                 sTags,  /* space seperated list of tags */
303                 
304                 sDVBState, /* states as defined in pmt handler (as events there) */
305
306                 sVideoHeight,
307                 sVideoWidth,
308                 
309                 sTransponderData /* transponderdata as python dict */
310         };
311         enum { resNA = -1, resIsString = -2, resIsPyObject = -3 };
312
313         virtual int getInfo(int w);
314         virtual std::string getInfoString(int w);
315         virtual PyObject *getInfoObject(int w);
316         
317         virtual int setInfo(int w, int v);
318         virtual int setInfoString(int w, const char *v);
319 };
320
321 TEMPLATE_TYPEDEF(ePtr<iServiceInformation>, iServiceInformationPtr);
322
323 class iFrontendInformation: public iObject
324 {
325 #ifdef SWIG
326         iFrontendInformation();
327         ~iFrontendInformation();
328 #endif
329 public:
330         enum {
331                 bitErrorRate,
332                 signalPower,
333                 signalQuality,
334                 lockState,
335                 syncState,
336                 frontendNumber
337         };
338         virtual int getFrontendInfo(int w)=0;
339         virtual PyObject *getFrontendData(bool original=false)=0;
340 };
341
342 TEMPLATE_TYPEDEF(ePtr<iFrontendInformation>, iFrontendInformationPtr);
343
344 class iPauseableService: public iObject
345 {
346 #ifdef SWIG
347         iPausableService();
348         ~iPausableService();
349 #endif
350 public:
351         virtual RESULT pause()=0;
352         virtual RESULT unpause()=0;
353         
354                 /* hm. */
355         virtual RESULT setSlowMotion(int ratio=0)=0;
356         virtual RESULT setFastForward(int ratio=0)=0;
357 };
358
359 TEMPLATE_TYPEDEF(ePtr<iPauseableService>, iPauseableServicePtr);
360
361 class iSeekableService: public iObject
362 {
363 #ifdef SWIG
364         iSeekableService();
365         ~iSeekableService();
366 #endif
367 public:
368         virtual RESULT getLength(pts_t &SWIG_OUTPUT)=0;
369         virtual RESULT seekTo(pts_t to)=0;
370         enum { dirForward = +1, dirBackward = -1 };
371         virtual RESULT seekRelative(int direction, pts_t to)=0;
372         virtual RESULT getPlayPosition(pts_t &SWIG_OUTPUT)=0;
373                 /* if you want to do several seeks in a row, you can enable the trickmode. 
374                    audio will be switched off, sync will be disabled etc. */
375         virtual RESULT setTrickmode(int trick=0)=0;
376         virtual RESULT isCurrentlySeekable()=0;
377 };
378
379 TEMPLATE_TYPEDEF(ePtr<iSeekableService>, iSeekableServicePtr);
380
381 struct iAudioTrackInfo
382 {
383 #ifndef SWIG
384         std::string m_description;
385         std::string m_language; /* iso639 */
386 #endif
387         std::string getDescription() { return m_description; }
388         std::string getLanguage() { return m_language; }
389 };
390
391 SWIG_ALLOW_OUTPUT_SIMPLE(iAudioTrackInfo);
392
393 class iAudioTrackSelection: public iObject
394 {
395 #ifdef SWIG
396         iAudioTrackSelection();
397         ~iAudioTrackSelection();
398 #endif
399 public:
400         virtual int getNumberOfTracks()=0;
401         virtual RESULT selectTrack(unsigned int i)=0;
402         virtual SWIG_VOID(RESULT) getTrackInfo(struct iAudioTrackInfo &SWIG_OUTPUT, unsigned int n)=0;
403 };
404
405 TEMPLATE_TYPEDEF(ePtr<iAudioTrackSelection>, iAudioTrackSelectionPtr);
406
407 class iAudioChannelSelection: public iObject
408 {
409 #ifdef SWIG
410         iAudioChannelSelection();
411         ~iAudioChannelSelection();
412 #endif
413 public:
414         enum { LEFT, STEREO, RIGHT };
415         virtual int getCurrentChannel()=0;
416         virtual RESULT selectChannel(int i)=0;
417 };
418
419 TEMPLATE_TYPEDEF(ePtr<iAudioChannelSelection>, iAudioChannelSelectionPtr);
420
421 class iAudioDelay: public iObject
422 {
423 #ifdef SWIG
424         iAudioDelay();
425         ~iAudioDelay();
426 #endif
427 public:
428         virtual int getAC3Delay()=0;
429         virtual int getPCMDelay()=0;
430         virtual void setAC3Delay(int)=0;
431         virtual void setPCMDelay(int)=0;
432 };
433
434 TEMPLATE_TYPEDEF(ePtr<iAudioDelay>, iAudioDelayPtr);
435
436 class iRadioText: public iObject
437 {
438 #ifdef SWIG
439         iRadioText();
440         ~iRadioText();
441 #endif
442 public:
443         virtual std::string getRadioText(int x=0)=0;
444 };
445
446 TEMPLATE_TYPEDEF(ePtr<iRadioText>, iRadioTextPtr);
447
448 class iSubserviceList: public iObject
449 {
450 #ifdef SWIG
451         iSubserviceList();
452         ~iSubserviceList();
453 #endif
454 public:
455         virtual int getNumberOfSubservices()=0;
456         virtual SWIG_VOID(RESULT) getSubservice(eServiceReference &SWIG_OUTPUT, unsigned int n)=0;
457 };
458
459 TEMPLATE_TYPEDEF(ePtr<iSubserviceList>, iSubserviceListPtr);
460
461 class iTimeshiftService: public iObject
462 {
463 #ifdef SWIG
464         iTimeshiftService();
465         ~iTimeshiftService();
466 #endif
467 public:
468         virtual RESULT startTimeshift()=0;
469         virtual RESULT stopTimeshift()=0;
470         
471         virtual int isTimeshiftActive()=0;
472                         /* this essentially seeks to the relative end of the timeshift buffer */
473         virtual RESULT activateTimeshift()=0;
474 };
475
476 TEMPLATE_TYPEDEF(ePtr<iTimeshiftService>, iTimeshiftServicePtr);
477
478         /* not related to eCueSheet */
479 class iCueSheet: public iObject
480 {
481 #ifdef SWIG
482         iCueSheet();
483         ~iCueSheet();
484 #endif
485 public:
486                         /* returns a list of (pts, what)-tuples */
487         virtual PyObject *getCutList() = 0;
488         virtual void setCutList(SWIG_PYOBJECT(ePyObject) list) = 0;
489         virtual void setCutListEnable(int enable) = 0;
490         enum { cutIn = 0, cutOut = 1, cutMark = 2 };
491 };
492
493 TEMPLATE_TYPEDEF(ePtr<iCueSheet>, iCueSheetPtr);
494
495 class eWidget;
496 class PyList;
497
498 class iSubtitleOutput: public iObject
499 {
500 public:
501         virtual RESULT enableSubtitles(eWidget *parent, SWIG_PYOBJECT(ePyObject) entry)=0;
502         virtual RESULT disableSubtitles(eWidget *parent)=0;
503         virtual PyObject *getSubtitleList()=0;
504         virtual PyObject *getCachedSubtitle()=0;
505 };
506
507 TEMPLATE_TYPEDEF(ePtr<iSubtitleOutput>, iSubtitleOutputPtr);
508
509 class iPlayableService: public iObject
510 {
511 #ifdef SWIG
512         iPlayableService();
513         ~iPlaybleService();
514 #endif
515         friend class iServiceHandler;
516 public:
517         enum
518         {
519                         /* these first two events are magical, and should only
520                            be generated if you know what you're doing. */
521                 evStart,
522                 evEnd,
523                 
524                 evTuneFailed,
525                         // when iServiceInformation is implemented:
526                 evUpdatedEventInfo,
527                 evUpdatedInfo,
528
529                         /* when seek() is implemented: */               
530                 evSeekableStatusChanged, /* for example when timeshifting */
531                 
532                 evEOF,
533                 evSOF, /* bounced against start of file (when seeking backwards) */
534                 
535                         /* only when cueSheet is implemented */
536                 evCuesheetChanged,
537
538                 evUpdatedRadioText,
539
540                 evVideoSizeChanged
541         };
542 #ifndef SWIG
543         virtual RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)=0;
544 #endif
545         virtual RESULT start()=0;
546         virtual RESULT stop()=0;
547                         /* might have to be changed... */
548         virtual RESULT setTarget(int target)=0;
549         virtual SWIG_VOID(RESULT) seek(ePtr<iSeekableService> &SWIG_OUTPUT)=0;
550         virtual SWIG_VOID(RESULT) pause(ePtr<iPauseableService> &SWIG_OUTPUT)=0;
551         virtual SWIG_VOID(RESULT) info(ePtr<iServiceInformation> &SWIG_OUTPUT)=0;
552         virtual SWIG_VOID(RESULT) audioTracks(ePtr<iAudioTrackSelection> &SWIG_OUTPUT)=0;
553         virtual SWIG_VOID(RESULT) audioChannel(ePtr<iAudioChannelSelection> &SWIG_OUTPUT)=0;
554         virtual SWIG_VOID(RESULT) subServices(ePtr<iSubserviceList> &SWIG_OUTPUT)=0;
555         virtual SWIG_VOID(RESULT) frontendInfo(ePtr<iFrontendInformation> &SWIG_OUTPUT)=0;
556         virtual SWIG_VOID(RESULT) timeshift(ePtr<iTimeshiftService> &SWIG_OUTPUT)=0;
557         virtual SWIG_VOID(RESULT) cueSheet(ePtr<iCueSheet> &SWIG_OUTPUT)=0;
558         virtual SWIG_VOID(RESULT) subtitle(ePtr<iSubtitleOutput> &SWIG_OUTPUT)=0;
559         virtual SWIG_VOID(RESULT) audioDelay(ePtr<iAudioDelay> &SWIG_OUTPUT)=0;
560         virtual SWIG_VOID(RESULT) radioText(ePtr<iRadioText> &SWIG_OUTPUT)=0;
561 };
562
563 TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
564
565 class iRecordableService: public iObject
566 {
567 #ifdef SWIG
568         iRecordableService();
569         ~iRecordableService();
570 #endif
571 public:
572         enum
573         {
574                 evStart,
575                 evStop,
576                 evTunedIn,
577                 evTuneFailed,
578                 evRecordRunning,
579                 evRecordStopped,
580                 evNewProgramInfo,
581                 evRecordFailed
582 //              evDiskFull
583         };
584         enum
585         {
586                 NoError=0,
587                 errOpenRecordFile=-1,
588                 errNoDemuxAvailable=-2,
589                 errNoTsRecorderAvailable=-3,
590                 errDiskFull=-4,
591                 errTuneFailed=-255
592         };
593 #ifndef SWIG
594         virtual RESULT connectEvent(const Slot2<void,iRecordableService*,int> &event, ePtr<eConnection> &connection)=0;
595 #endif
596         virtual RESULT getError(int &)=0;
597         virtual RESULT prepare(const char *filename, time_t begTime=-1, time_t endTime=-1, int eit_event_id=-1)=0;
598         virtual RESULT start()=0;
599         virtual RESULT stop()=0;
600         virtual SWIG_VOID(RESULT) frontendInfo(ePtr<iFrontendInformation> &SWIG_OUTPUT)=0;
601 };
602
603 TEMPLATE_TYPEDEF(ePtr<iRecordableService>, iRecordableServicePtr);
604
605 extern PyObject *New_iRecordableServicePtr(const ePtr<iRecordableService> &ref); // defined in enigma_python.i
606
607 inline PyObject *PyFrom(ePtr<iRecordableService> &c)
608 {
609         return New_iRecordableServicePtr(c);
610 }
611
612 #ifndef SWIG
613 #ifdef PYTHON_REFCOUNT_DEBUG
614 inline ePyObject Impl_New_iRecordableServicePtr(const char* file, int line, const ePtr<iRecordableService> &ptr)
615 {
616         return ePyObject(New_iRecordableServicePtr(ptr), file, line);
617 }
618 #define NEW_iRecordableServicePtr(ptr) Impl_New_iRecordableServicePtr(__FILE__, __LINE__, ptr)
619 #else
620 inline ePyObject Impl_New_iRecordableServicePtr(const ePtr<iRecordableService> &ptr)
621 {
622         return New_iRecordableServicePtr(ptr);
623 }
624 #define NEW_iRecordableServicePtr(ptr) Impl_New_iRecordableServicePtr(ptr)
625 #endif
626 #endif // SWIG
627
628 // TEMPLATE_TYPEDEF(std::list<eServiceReference>, eServiceReferenceList);
629
630 class iMutableServiceList: public iObject
631 {
632 #ifdef SWIG
633         iMutableServiceList();
634         ~iMutableServiceList();
635 #endif
636 public:
637                 /* flush changes */
638         virtual RESULT flushChanges()=0;
639                 /* adds a service to a list */
640         virtual RESULT addService(eServiceReference &ref, eServiceReference before=eServiceReference())=0;
641                 /* removes a service from a list */
642         virtual RESULT removeService(eServiceReference &ref)=0;
643                 /* moves a service in a list, only if list suppports a specific sort method. */
644                 /* pos is the new, absolute position from 0..size-1 */
645         virtual RESULT moveService(eServiceReference &ref, int pos)=0;
646                 /* set name of list, for bouquets this is the visible bouquet name */
647         virtual RESULT setListName(const std::string &name)=0;
648 };
649
650 TEMPLATE_TYPEDEF(ePtr<iMutableServiceList>, iMutableServiceListPtr);
651
652 class iListableService: public iObject
653 {
654 #ifdef SWIG
655         iListableService();
656         ~iListableService();
657 #endif
658 public:
659 #ifndef SWIG
660                 /* legacy interface: get a list */
661         virtual RESULT getContent(std::list<eServiceReference> &list, bool sorted=false)=0;
662 #endif
663         virtual PyObject *getContent(const char* format, bool sorted=false)=0;
664
665                 /* new, shiny interface: streaming. */
666         virtual SWIG_VOID(RESULT) getNext(eServiceReference &SWIG_OUTPUT)=0;
667         
668                 /* use this for sorting. output is not sorted because of either
669                  - performance reasons: the whole list must be buffered or
670                  - the interface would be restricted to a list. streaming
671                    (as well as a future "active" extension) won't be possible.
672                 */
673         virtual int compareLessEqual(const eServiceReference &, const eServiceReference &)=0;
674         
675         virtual SWIG_VOID(RESULT) startEdit(ePtr<iMutableServiceList> &SWIG_OUTPUT)=0;
676 };
677
678 TEMPLATE_TYPEDEF(ePtr<iListableService>, iListableServicePtr);
679
680 #ifndef SWIG
681         /* a helper class which can be used as argument to stl's sort(). */
682 class iListableServiceCompare
683 {
684         ePtr<iListableService> m_list;
685 public:
686         iListableServiceCompare(iListableService *list): m_list(list) { }
687         bool operator()(const eServiceReference &a, const eServiceReference &b)
688         {
689                 return m_list->compareLessEqual(a, b);
690         }
691 };
692 #endif
693
694 class iServiceOfflineOperations: public iObject
695 {
696 #ifdef SWIG
697         iServiceOfflineOperations();
698         ~iServiceOfflineOperations();
699 #endif
700 public:
701                 /* to delete a service, forever. */
702         virtual RESULT deleteFromDisk(int simulate=1)=0;
703         
704                 /* for transferring a service... */
705         virtual SWIG_VOID(RESULT) getListOfFilenames(std::list<std::string> &SWIG_OUTPUT)=0;
706         
707                 // TODO: additional stuff, like a conversion interface?
708 };
709
710 TEMPLATE_TYPEDEF(ePtr<iServiceOfflineOperations>, iServiceOfflineOperationsPtr);
711
712 class iServiceHandler: public iObject
713 {
714 #ifdef SWIG
715         iServiceHandler();
716         ~iServiceHandler();
717 #endif
718 public:
719         virtual SWIG_VOID(RESULT) play(const eServiceReference &, ePtr<iPlayableService> &SWIG_OUTPUT)=0;
720         virtual SWIG_VOID(RESULT) record(const eServiceReference &, ePtr<iRecordableService> &SWIG_OUTPUT)=0;
721         virtual SWIG_VOID(RESULT) list(const eServiceReference &, ePtr<iListableService> &SWIG_OUTPUT)=0;
722         virtual SWIG_VOID(RESULT) info(const eServiceReference &, ePtr<iStaticServiceInformation> &SWIG_OUTPUT)=0;
723         virtual SWIG_VOID(RESULT) offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &SWIG_OUTPUT)=0;
724 };
725
726 TEMPLATE_TYPEDEF(ePtr<iServiceHandler>, iServiceHandlerPtr);
727
728 #endif