use boundFunction from tools
[enigma2.git] / lib / dvb / esection.h
1 #ifndef __esection_h
2 #define __esection_h
3
4 #include <lib/dvb/idemux.h>
5 #include <set>
6
7 class eGTable: public iObject, public Object
8 {
9 DECLARE_REF(eGTable);
10 private:
11         ePtr<iDVBSectionReader> m_reader;
12         eDVBTableSpec m_table;
13         
14         eTimer *m_timeout;
15
16         void sectionRead(const __u8 *data);
17         void timeout();
18         ePtr<eConnection> m_sectionRead_conn;
19 protected:
20         virtual int createTable(int nr, const __u8 *data, unsigned int max)=0;
21 public:
22         Signal1<void, int> tableReady;
23         eGTable();
24         RESULT start(iDVBSectionReader *reader, const eDVBTableSpec &table);
25         RESULT start(iDVBDemux *reader, const eDVBTableSpec &table);
26         RESULT getSpec(eDVBTableSpec &spec) { spec = m_table; return 0; }
27         virtual ~eGTable();
28         int error;
29         int ready;
30 };
31
32 template <class Section>
33 class eTable: public eGTable
34 {
35 private:
36         std::vector<Section*> sections;
37         std::set<int> avail;
38 protected:
39         int createTable(int nr, const __u8 *data, unsigned int max)
40         {
41                 if (avail.find(nr) != avail.end())
42                         delete sections[nr];
43                 sections.resize(max);
44                 
45                 
46                 sections[nr] = new Section(data);
47                 avail.insert(nr);
48
49                 for (unsigned int i = 0; i < max; ++i)
50                         if (avail.find(i) != avail.end())
51                                 printf("+");
52                         else
53                                 printf("-");
54                                 
55                 printf(" %d/%d TID %02x\n", avail.size(), max, data[0]);
56
57                 if (avail.size() == max)
58                 {
59                         printf("done!\n");
60                         return 1;
61                 } else
62                         return 0;
63         }
64 public:
65         std::vector<Section*> &getSections() { return sections; }
66         eTable(): eGTable()
67         {
68         }
69         ~eTable()
70         {
71                 for (typename std::vector<Section*>::iterator i(sections.begin()); i != sections.end(); ++i)
72                         delete *i;
73         }
74 };
75
76 class eAUGTable: public Object
77 {
78 protected:
79         void slotTableReady(int);
80 public:
81         Signal1<void, int> tableReady;
82         virtual void getNext(int err)=0;
83 };
84
85 template <class Table>
86 class eAUTable: public eAUGTable
87 {
88         ePtr<Table> current, next;              // current is READY AND ERRORFREE, next is not yet ready
89         int first;
90         ePtr<iDVBDemux> m_demux;
91         eMainloop *ml;
92 public:
93
94         eAUTable()
95         {
96         }
97
98         ~eAUTable()
99         {
100                 current=next=0;
101         }
102         
103         int begin(eMainloop *m, const eDVBTableSpec &spec, ePtr<iDVBDemux> demux)
104         {
105                 ml = m;
106                 m_demux = demux;
107                 first= 1;
108                 current = 0;
109                 next = new Table();
110                 CONNECT(next->tableReady, eAUTable::slotTableReady);
111                 next->start(demux, spec);
112                 return 0;
113         }
114         
115         int get()
116         {
117                 if (current)
118                 {
119                         /*emit*/ tableReady(0);
120                         return 0;
121                 } else if (!next)
122                 {
123                         /*emit*/ tableReady(-1);
124                         return 0;
125                 } else
126                         return 1;
127         }
128         
129         RESULT getCurrent(ePtr<Table> &ptr)
130         {
131                 if (!current)
132                         return -1;
133                 ptr = current;
134                 return 0;
135         }
136
137 #if 0   
138         void abort()
139         {
140                 eDebug("eAUTable: aborted!");
141                 if (next)
142                         next->abort();
143                 delete next;
144                 next=0;
145         }
146 #endif
147
148         int ready()
149         {
150                 return !!current;
151         }
152         
153         void inject(Table *t)
154         {
155                 next=t;
156                 getNext(0);
157         }
158
159         void getNext(int error)
160         {
161                 current = 0;
162                 if (error)
163                 {
164                         next=0;
165                         if (first)
166                                 /*emit*/ tableReady(error);
167                         first=0;
168                         return;
169                 } else
170                         current=next;
171
172                 next=0;
173                 first=0;
174                 
175                 assert(current->ready);
176                         
177                 /*emit*/ tableReady(0);
178                 
179                 eDVBTableSpec spec;
180
181                 if (current && (!current->getSpec(spec)))
182                 {
183                         next = new Table();
184                         CONNECT(next->tableReady, eAUTable::slotTableReady);
185                         spec.flags &= ~(eDVBTableSpec::tfAnyVersion|eDVBTableSpec::tfThisVersion|eDVBTableSpec::tfHaveTimeout);
186                         next->eGTable::start(m_demux, spec);
187                 }
188         }
189 };
190
191 #endif