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