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