/* * kaffeinedvbevents.cpp * * Copyright (C) 2003-2007 Christophe Thommeret * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include "kaffeinedvbevents.h" ShortEvent::ShortEvent() { name=text=""; } ShortEvent::~ShortEvent() { } EventDesc::EventDesc() { loop = 0; nid=sid=tsid=eid=0; tid=sn=lsn=running=0; title=subtitle=""; source=""; shortEvents.setAutoDelete( true ); extEvents.setAutoDelete( true ); } EventDesc::~EventDesc() { shortEvents.clear(); extEvents.clear(); } EventSid::EventSid( int s ) { sid = s; events.setAutoDelete( true ); } EventSid::~EventSid() { TQMutexLocker locker( &mutex ); events.clear(); } void EventSid::remove( EventDesc *d ) { TQMutexLocker locker( &mutex ); events.remove( d ); } EventDesc *EventSid::getEventDesc( int n ) { TQMutexLocker locker( &mutex ); return events.at(n); } EventTsid::EventTsid( int n, int t ) { tsid = t; nid = n; sidList.setAutoDelete( true ); } EventTsid::~EventTsid() { TQMutexLocker locker( &mutex ); sidList.clear(); } EventSid *EventTsid::getNEventSid( int n ) { TQMutexLocker locker( &mutex ); return sidList.at( n ); } EventSid *EventTsid::getEventSid( int sid ) { int i; TQMutexLocker locker( &mutex ); for ( i=0; i<(int)sidList.count(); i++ ) { if ( sidList.at(i)->getSid()==sid ) return sidList.at(i); } EventSid *es = new EventSid( sid ); sidList.append( es ); return es; } EventDesc *EventTsid::getEventDesc( int sid, int n ) { int i; EventSid *es=0; mutex.lock(); for ( i=0; i<(int)sidList.count(); i++ ) { if ( sidList.at(i)->getSid()==sid ) { es = sidList.at(i); break; } } mutex.unlock(); if ( !es ) return 0; return es->getEventDesc( n ); } EventSource::EventSource( TQString src ) { source = src; tsidList.setAutoDelete( true ); } EventSource::~EventSource() { TQMutexLocker locker( &mutex ); tsidList.clear(); } EventTsid *EventSource::getNEventTsid( int n ) { TQMutexLocker locker( &mutex ); return tsidList.at( n ); } EventSid *EventSource::getEventSid( int nid, int tsid, int sid ) { int i; EventTsid *et=0; mutex.lock(); for ( i=0; i<(int)tsidList.count(); i++ ) { if ( tsidList.at(i)->getTsid()==tsid && (nid==0 || tsidList.at(i)->getNid()==nid) ) { et = tsidList.at(i); break; } } if ( !et ) { if ( nid==0) { mutex.unlock(); return 0; } et = new EventTsid( nid, tsid ); tsidList.append( et ); } mutex.unlock(); return et->getEventSid( sid ); } EventDesc *EventSource::getEventDesc( int nid, int tsid, int sid, int n ) { int i; EventTsid *et=0; mutex.lock(); for ( i=0; i<(int)tsidList.count(); i++ ) { if ( tsidList.at(i)->getTsid()==tsid && (nid==0 || tsidList.at(i)->getNid()==nid) ) { et = tsidList.at(i); break; } } mutex.unlock(); if ( !et ) return 0; return et->getEventDesc( sid, n ); } EventTable::EventTable() { srcList.setAutoDelete( true ); connect ( &cleanTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(setClean()) ); cleanTimer.start( 10000 ); epgLoaded = false; } EventTable::~EventTable() { TQMutexLocker locker( &mutex ); srcList.clear(); } void EventTable::saveEpg() { EventSource *esrc; EventTsid *et; EventSid *es; TQPtrList *esEvents; EventDesc *desc; int i, k, j, m, n; TQCString c; int count=0; unsigned char sync=0xff; TQTime t1=TQTime::currentTime(); TQFile f( locateLocal("appdata", "dvbepg.data" ) ); if ( f.open(IO_WriteOnly|IO_Truncate) ) { TQDataStream dt( &f ); for( i=0; igetNTsid(); m++ ) { if ( !(et=esrc->getNEventTsid( m )) ) continue; for ( n=0; ngetNSid(); n++ ) { if ( !(es=et->getNEventSid( n )) ) continue; esEvents = es->getEvents(); es->lock(); for ( j=0; j<(int)esEvents->count(); j++ ) { if ( !(desc=esEvents->at( j )) ) continue; dt << sync; // sync byte c = desc->source.utf8(); dt << c.data(); dt << desc->tid; dt << desc->sid; dt << desc->tsid; dt << desc->nid; dt << desc->sn; dt << desc->lsn; dt << desc->eid; dt << desc->running; dt << desc->startDateTime.toTime_t(); dt << (uint)((desc->duration.hour()*3600)+(desc->duration.minute()*60)+desc->duration.second()); dt << desc->shortEvents.count(); for ( k=0; k<(int)desc->shortEvents.count(); k++ ) { c = desc->shortEvents.at(k)->name.utf8(); dt << c.data(); c = desc->shortEvents.at(k)->text.utf8(); dt << c.data(); } dt << (uint)desc->extEvents.count(); for ( k=0; k<(int)desc->extEvents.count(); k++ ) { c = desc->extEvents.at(k)->utf8(); dt << c.data(); } c = desc->title.utf8(); dt << c.data(); c = desc->subtitle.utf8(); dt << c.data(); ++count; } es->unlock(); } } } f.close(); fprintf( stderr, "Saved epg data : %d events (%d msecs)\n", count, t1.msecsTo(TQTime::currentTime()) ); } } void EventTable::loadEpg() { EventDesc *desc; ShortEvent *sev; EventSid *slist; uint count, tmp, i; #define EPGBUFSIZE 500 char buf[EPGBUFSIZE]; int num=0; unsigned char sync; TQDateTime cur=TQDateTime::currentDateTime(); TQTime t1=TQTime::currentTime(); if ( epgLoaded ) return; epgLoaded = true; TQFile f( locateLocal("appdata", "dvbepg.data" ) ); if ( f.open(IO_ReadOnly) ) { TQDataStream dt( &f ); while (!dt.eof() ) { dt >> sync; if ( sync!=0xff ) { f.close(); fprintf( stderr, "Sync error while loading epg data : %d events loaded\n", num ); return; } desc = new EventDesc(); dt >> tmp; if ( !validString( f, desc, tmp, EPGBUFSIZE, num ) ) return; dt.readRawBytes( buf, tmp ); desc->source = TQString::fromUtf8( buf ); dt >> desc->tid; dt >> desc->sid; dt >> desc->tsid; dt >> desc->nid; dt >> desc->sn; dt >> desc->lsn; dt >> desc->eid; dt >> desc->running; dt >> tmp; desc->startDateTime.setTime_t( tmp ); dt >> tmp; desc->duration = TQTime().addSecs( tmp ); dt >> count; for ( i=0; i> tmp; if ( !validString( f, desc, tmp, EPGBUFSIZE, num ) ) return; dt.readRawBytes( buf, tmp ); sev->name = TQString::fromUtf8( buf ); dt >> tmp; if ( !validString( f, desc, tmp, EPGBUFSIZE, num ) ) return; dt.readRawBytes( buf, tmp ); sev->text = TQString::fromUtf8( buf ); desc->shortEvents.append( sev ); } dt >> count; for ( i=0; i> tmp; if ( !validString( f, desc, tmp, EPGBUFSIZE, num ) ) return; dt.readRawBytes( buf, tmp ); desc->extEvents.append( new TQString( TQString::fromUtf8( buf ) ) ); } dt >> tmp; if ( !validString( f, desc, tmp, EPGBUFSIZE, num ) ) return; dt.readRawBytes( buf, tmp ); desc->title = TQString::fromUtf8( buf ); dt >> tmp; if ( !validString( f, desc, tmp, EPGBUFSIZE, num ) ) return; dt.readRawBytes( buf, tmp ); desc->subtitle = TQString::fromUtf8( buf ); if ( desc->startDateTime.addSecs( (desc->duration.hour()*3600)+(desc->duration.minute()*60)+desc->duration.second() )source )->getEventSid( desc->nid, desc->tsid, desc->sid ); if ( !slist ) continue; slist->lock(); slist->getEvents()->append( desc ); slist->unlock(); ++num; } } f.close(); fprintf( stderr, "Loaded epg data : %d events (%d msecs)\n", num, t1.msecsTo(TQTime::currentTime()) ); } } bool EventTable::validString( TQFile &f, EventDesc *d, int len, int buflen, int nev ) { if ( len<1 || len>buflen ) { f.close(); fprintf( stderr, "Error while loading epg data : %d events loaded\n", nev ); delete d; return false; } return true; } void EventTable::setClean() { start(); } void EventTable::doClean( bool b ) { if ( b ) { if ( cleanTimer.isActive() ) return; cleanTimer.start( 10000 ); } else { cleanTimer.stop(); wait(); } } void EventTable::run() { int k, m, n, sec; EventSource *esrc; EventTsid *et; EventSid *es; EventDesc *desc; TQDateTime dt, cur; setpriority(PRIO_PROCESS, 0, 19); cur = TQDateTime::currentDateTime(); for( k=0; kgetNTsid(); m++ ) { if ( !(et=esrc->getNEventTsid( m )) ) continue; for ( n=0; ngetNSid(); n++ ) { if ( !(es=et->getNEventSid( n )) ) continue; if ( !(desc=es->getEventDesc( 0 )) ) continue; dt = desc->startDateTime; sec = desc->duration.hour()*3600+desc->duration.minute()*60+desc->duration.second(); if ( dt.addSecs( sec )remove( desc ); } } } } EventSource *EventTable::getNEventSource( int n ) { TQMutexLocker locker( &mutex ); return srcList.at( n ); } EventSource *EventTable::getEventSource( TQString src ) { int i; TQMutexLocker locker( &mutex ); for ( i=0; i<(int)srcList.count(); i++ ) { if ( srcList.at(i)->getSource()==src ) return srcList.at(i); } EventSource *es = new EventSource( src ); srcList.append( es ); return es; } EventDesc *EventTable::getEventDesc( TQString src, int nid, int tsid, int sid, int n ) { int i; EventSource *es=0; mutex.lock(); for ( i=0; i<(int)srcList.count(); i++ ) { if ( srcList.at(i)->getSource()==src ) { es = srcList.at(i); break; } } mutex.unlock(); if ( !es ) return 0; return es->getEventDesc( nid, tsid, sid, n ); } KaffeineEpgPlugin::KaffeineEpgPlugin( TQObject* parent, const char* name ) : KParts::Part( parent, name ) { } KaffeineEpgPlugin::~KaffeineEpgPlugin() { } bool KaffeineEpgPlugin::safeLen( unsigned char* buf ) { if ( buf<(secbuf+readSize) ) return true; fprintf( stderr, "EIT (%d:%d) : buffer overflow! Rejected\n", adapter, tuner ); return false; } #include "kaffeinedvbevents.moc"