tables: don't retry more than 5*nr times.
[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         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                 current=next=0;
102         }
103         
104         int begin(eMainloop *m, const eDVBTableSpec &spec, ePtr<iDVBDemux> demux)
105         {
106                 ml = m;
107                 m_demux = demux;
108                 first= 1;
109                 current = 0;
110                 next = new Table();
111                 CONNECT(next->tableReady, eAUTable::slotTableReady);
112                 next->start(demux, spec);
113                 return 0;
114         }
115         
116         int get()
117         {
118                 if (current)
119                 {
120                         /*emit*/ tableReady(0);
121                         return 0;
122                 } else if (!next)
123                 {
124                         /*emit*/ tableReady(-1);
125                         return 0;
126                 } else
127                         return 1;
128         }
129         
130         RESULT getCurrent(ePtr<Table> &ptr)
131         {
132                 if (!current)
133                         return -1;
134                 ptr = current;
135                 return 0;
136         }
137
138 #if 0   
139         void abort()
140         {
141                 eDebug("eAUTable: aborted!");
142                 if (next)
143                         next->abort();
144                 delete next;
145                 next=0;
146         }
147 #endif
148
149         int ready()
150         {
151                 return !!current;
152         }
153         
154         void inject(Table *t)
155         {
156                 next=t;
157                 getNext(0);
158         }
159
160         void getNext(int error)
161         {
162                 current = 0;
163                 if (error)
164                 {
165                         next=0;
166                         if (first)
167                                 /*emit*/ tableReady(error);
168                         first=0;
169                         return;
170                 } else
171                         current=next;
172
173                 next=0;
174                 first=0;
175                 
176                 assert(current->ready);
177                         
178                 /*emit*/ tableReady(0);
179                 
180                 eDVBTableSpec spec;
181
182                 if (current && (!current->getSpec(spec)))
183                 {
184                         next = new Table();
185                         CONNECT(next->tableReady, eAUTable::slotTableReady);
186                         spec.flags &= ~(eDVBTableSpec::tfAnyVersion|eDVBTableSpec::tfThisVersion|eDVBTableSpec::tfHaveTimeout);
187                         next->eGTable::start(m_demux, spec);
188                 }
189         }
190 };
191
192 #endif