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