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