+descriptorMap eventData::descriptors;
+
+extern const uint32_t crc32_table[256];
+
+eventData::eventData(const eit_event_struct* e, int size, int type)
+ :ByteSize(size), type(type)
+{
+ if (!e)
+ return;
+ std::list<__u32> d;
+ __u8 *data = (__u8*)e;
+ int ptr=10;
+ int descriptors_length = (data[ptr++]&0x0F) << 8;
+ descriptors_length |= data[ptr++];
+ while ( descriptors_length > 0 )
+ {
+ int descr_len = data[ptr+1] + 2;
+ __u8 *descr = new __u8[descr_len];
+ unsigned int crc=0;
+ int cnt=0;
+ while(cnt < descr_len && descriptors_length > 0)
+ {
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ data[ptr]) & 0xff];
+ descr[cnt++] = data[ptr++];
+ --descriptors_length;
+ }
+ descriptorMap::iterator it =
+ descriptors.find(crc);
+ if ( it == descriptors.end() )
+ {
+ CacheSize+=descr_len;
+ descriptors[crc] = descriptorPair(1, descr);
+ }
+ else
+ {
+ ++it->second.first;
+ delete [] descr;
+ }
+ d.push_back(crc);
+ }
+ ByteSize = 12+d.size()*4;
+ EITdata = new __u8[ByteSize];
+ CacheSize+=ByteSize;
+ memcpy(EITdata, (__u8*) e, 12);
+ __u32 *p = (__u32*)(EITdata+12);
+ for (std::list<__u32>::iterator it(d.begin()); it != d.end(); ++it)
+ *p++ = *it;
+}
+
+const eit_event_struct* eventData::get() const
+{
+ static __u8 *data=NULL;
+ if ( data )
+ delete [] data;
+
+ int bytes = 12;
+ std::list<__u8*> d;
+
+// cnt needed bytes
+ int tmp = ByteSize-12;
+ __u32 *p = (__u32*)(EITdata+12);
+ while(tmp>0)
+ {
+ descriptorMap::iterator it =
+ descriptors.find(*p++);
+ if ( it != descriptors.end() )
+ {
+ d.push_back(it->second.second);
+ bytes += it->second.second[1];
+ }
+ bytes += 2; // descr_type, descr_len
+ tmp-=4;
+ }
+
+// copy eit_event header to buffer
+ data = new __u8[bytes];
+ memcpy(data, EITdata, 12);
+
+ tmp=12;
+// copy all descriptors to buffer
+ for(std::list<__u8*>::iterator it(d.begin()); it != d.end(); ++it)
+ {
+ int b=(*it)[1]+2;
+ memcpy(data+tmp, *it, b);
+ tmp+=b;
+ }
+
+ return (eit_event_struct*)data;
+}
+
+eventData::~eventData()
+{
+ if ( ByteSize )
+ {
+ CacheSize-=ByteSize;
+ ByteSize-=12;
+ __u32 *d = (__u32*)(EITdata+12);
+ while(ByteSize)
+ {
+ descriptorMap::iterator it =
+ descriptors.find(*d++);
+ if ( it != descriptors.end() )
+ {
+ descriptorPair &p = it->second;
+ if (!--p.first) // no more used descriptor
+ {
+ CacheSize -= p.second[1]+2;
+ delete [] p.second; // free descriptor memory
+ descriptors.erase(it); // remove entry from descriptor map
+ }
+ }
+ ByteSize-=4;
+ }
+ delete [] EITdata;
+ }
+}
+
+void eventData::load(FILE *f)
+{
+ int size=0;
+ int id=0;
+ __u8 header[2];
+ descriptorPair p;
+ fread(&size, sizeof(int), 1, f);
+ while(size)
+ {
+ fread(&id, sizeof(__u32), 1, f);
+ fread(&p.first, sizeof(int), 1, f);
+ fread(header, 2, 1, f);
+ int bytes = header[1]+2;
+ p.second = new __u8[bytes];
+ p.second[0] = header[0];
+ p.second[1] = header[1];
+ fread(p.second+2, bytes-2, 1, f);
+ descriptors[id]=p;
+ --size;
+ CacheSize+=bytes;
+ }
+}
+
+void eventData::save(FILE *f)
+{
+ int size=descriptors.size();
+ descriptorMap::iterator it(descriptors.begin());
+ fwrite(&size, sizeof(int), 1, f);
+ while(size)
+ {
+ fwrite(&it->first, sizeof(__u32), 1, f);
+ fwrite(&it->second.first, sizeof(int), 1, f);
+ fwrite(it->second.second, it->second.second[1]+2, 1, f);
+ ++it;
+ --size;
+ }
+}