X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/761cde6e77261e8ee7680510705b6283a734c2af..d87e3beb37390b59d288ae1cb43d9f887754ed56:/lib/dvb/epgcache.cpp diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp index 81b96a82..885ffc86 100644 --- a/lib/dvb/epgcache.cpp +++ b/lib/dvb/epgcache.cpp @@ -372,8 +372,9 @@ void eEPGCache::DVBChannelStateChanged(iDVBChannel *chan) } } -void eEPGCache::FixOverlapping(std::pair &servicemap, time_t TM, int duration, const timeMap::iterator &tm_it, const uniqueEPGKey &service) +bool eEPGCache::FixOverlapping(std::pair &servicemap, time_t TM, int duration, const timeMap::iterator &tm_it, const uniqueEPGKey &service) { + bool ret = false; timeMap::iterator tmp = tm_it; while ((tmp->first+tmp->second->getDuration()-300) > TM) { @@ -406,6 +407,7 @@ void eEPGCache::FixOverlapping(std::pair &servicemap, time_t T } else servicemap.second.erase(tmp--); + ret = true; } else { @@ -434,12 +436,14 @@ void eEPGCache::FixOverlapping(std::pair &servicemap, time_t T #endif delete tmp->second; servicemap.second.erase(tmp++); + ret = true; } else ++tmp; if (tmp == servicemap.second.end()) break; } + return ret; } void eEPGCache::sectionRead(const __u8 *data, int source, channel_data *channel) @@ -523,7 +527,11 @@ void eEPGCache::sectionRead(const __u8 *data, int source, channel_data *channel) eventData *tmp = ev_it->second; ev_it->second = tm_it_tmp->second = new eventData(eit_event, eit_event_size, source); - FixOverlapping(servicemap, TM, duration, tm_it_tmp, service); + if (FixOverlapping(servicemap, TM, duration, tm_it_tmp, service)) + { + prevEventIt = servicemap.first.end(); + prevTimeIt = servicemap.second.end(); + } delete tmp; goto next; } @@ -596,8 +604,6 @@ void eEPGCache::sectionRead(const __u8 *data, int source, channel_data *channel) tm_it=prevTimeIt=servicemap.second.insert( prevTimeIt, std::pair( TM, evt ) ); } - FixOverlapping(servicemap, TM, duration, tm_it, service); - #ifdef EPG_DEBUG if ( consistencyCheck ) { @@ -617,6 +623,11 @@ void eEPGCache::sectionRead(const __u8 *data, int source, channel_data *channel) ev_it->first, event_id ); } #endif + if (FixOverlapping(servicemap, TM, duration, tm_it, service)) + { + prevEventIt = servicemap.first.end(); + prevTimeIt = servicemap.second.end(); + } } next: #ifdef EPG_DEBUG @@ -1507,42 +1518,37 @@ RESULT eEPGCache::lookupEventId(const eServiceReference &service, int event_id, RESULT eEPGCache::startTimeQuery(const eServiceReference &service, time_t begin, int minutes) { + singleLock s(cache_lock); const eServiceReferenceDVB &ref = (const eServiceReferenceDVB&)handleGroup(service); - Lock(); + if (begin == -1) + begin = eDVBLocalTimeHandler::getInstance()->nowTime(); eventCache::iterator It = eventDB.find(ref); if ( It != eventDB.end() && It->second.second.size() ) { - if ( begin != -1 ) + m_timemap_cursor = It->second.second.lower_bound(begin); + if ( m_timemap_cursor != It->second.second.end() ) { - m_timemap_cursor = It->second.second.lower_bound(begin); - if ( m_timemap_cursor != It->second.second.end() ) + if ( m_timemap_cursor->first != begin ) { - if ( m_timemap_cursor->first != begin ) + timeMap::iterator x = m_timemap_cursor; + --x; + if ( x != It->second.second.end() ) { - timeMap::iterator x = m_timemap_cursor; - --x; - if ( x != It->second.second.end() ) - { - time_t start_time = x->first; - if ( begin > start_time && begin < (start_time+x->second->getDuration())) - m_timemap_cursor = x; - } + time_t start_time = x->first; + if ( begin > start_time && begin < (start_time+x->second->getDuration())) + m_timemap_cursor = x; } } } - else - m_timemap_cursor = It->second.second.begin(); - if (minutes != -1 && m_timemap_cursor != It->second.second.end()) - m_timemap_end = It->second.second.upper_bound(m_timemap_cursor->first+minutes*60); + if (minutes != -1) + m_timemap_end = It->second.second.lower_bound(begin+minutes*60); else m_timemap_end = It->second.second.end(); currentQueryTsidOnid = (ref.getTransportStreamID().get()<<16) | ref.getOriginalNetworkID().get(); - Unlock(); - return 0; + return m_timemap_cursor == m_timemap_end ? -1 : 0; } - Unlock(); return -1; } @@ -1590,11 +1596,12 @@ RESULT eEPGCache::getNextTimeEntry(ePtr &result) void fillTuple(ePyObject tuple, char *argstring, int argcount, ePyObject service, eServiceEvent *ptr, ePyObject nowTime, ePyObject service_name ) { ePyObject tmp; - int pos=0; - while(pos < argcount) + int spos=0, tpos=0; + char c; + while(spos < argcount) { bool inc_refcount=false; - switch(argstring[pos]) + switch((c=argstring[spos++])) { case '0': // PyLong 0 tmp = PyLong_FromLong(0); @@ -1629,6 +1636,12 @@ void fillTuple(ePyObject tuple, char *argstring, int argcount, ePyObject service case 'N': // service name tmp = service_name; inc_refcount = true; + break; + case 'X': + ++argcount; + continue; + default: // ignore unknown + eDebug("fillTuple unknown '%c'... insert 'None' in result", c); } if (!tmp) { @@ -1637,7 +1650,7 @@ void fillTuple(ePyObject tuple, char *argstring, int argcount, ePyObject service } if (inc_refcount) Py_INCREF(tmp); - PyTuple_SET_ITEM(tuple, pos++, tmp); + PyTuple_SET_ITEM(tuple, tpos++, tmp); } } @@ -1686,6 +1699,9 @@ int handleEvent(eServiceEvent *ptr, ePyObject dest_list, char* argstring, int ar // R = Service Reference // N = Service Name // n = Short Service Name +// X = Return a minimum of one tuple per service in the result list... even when no event was found. +// The returned tuple is filled with all available infos... non avail is filled as None +// The position and existence of 'X' in the format string has no influence on the result tuple... its completely ignored.. // then for each service follows a tuple // first tuple entry is the servicereference (as string... use the ref.toString() function) // the second is the type of query @@ -1732,6 +1748,11 @@ PyObject *eEPGCache::lookupEvent(ePyObject list, ePyObject convertFunc) argcount = strlen(argstring); // eDebug("have %d args('%s')", argcount, argstring); } + + bool forceReturnOne = strchr(argstring, 'X') ? true : false; + if (forceReturnOne) + --argcount; + if (convertFunc) { if (!PyCallable_Check(convertFunc)) @@ -1799,6 +1820,10 @@ PyObject *eEPGCache::lookupEvent(ePyObject list, ePyObject convertFunc) break; } } + + if (minutes && stime == -1) + stime = eDVBLocalTimeHandler::getInstance()->nowTime(); + eServiceReference ref(handleGroup(eServiceReference(PyString_AS_STRING(service)))); if (ref.type != eServiceReference::idDVB) { @@ -1858,7 +1883,7 @@ PyObject *eEPGCache::lookupEvent(ePyObject list, ePyObject convertFunc) } if (minutes) { - Lock(); + singleLock s(cache_lock); if (!startTimeQuery(ref, stime, minutes)) { while ( m_timemap_cursor != m_timemap_end ) @@ -1867,13 +1892,11 @@ PyObject *eEPGCache::lookupEvent(ePyObject list, ePyObject convertFunc) eServiceEvent evt; evt.parseFrom(&ev, currentQueryTsidOnid); if (handleEvent(&evt, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs)) - { - Unlock(); return 0; // error - } } } - Unlock(); + else if (forceReturnOne && handleEvent(0, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs)) + return 0; // error } else { @@ -1881,6 +1904,7 @@ PyObject *eEPGCache::lookupEvent(ePyObject list, ePyObject convertFunc) Event *ev=0; if (stime) { + singleLock s(cache_lock); if (type == 2) lookupEventId(ref, event_id, ev); else @@ -1891,7 +1915,12 @@ PyObject *eEPGCache::lookupEvent(ePyObject list, ePyObject convertFunc) evt.parseFrom(ev, (dref.getTransportStreamID().get()<<16)|dref.getOriginalNetworkID().get()); } } - if (handleEvent(ev ? &evt : 0, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs)) + if (ev) + { + if (handleEvent(&evt, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs)) + return 0; // error + } + else if (forceReturnOne && handleEvent(0, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs)) return 0; // error } if (service_changed) @@ -1954,6 +1983,8 @@ void fillTuple2(ePyObject tuple, const char *argstring, int argcount, eventData tmp = service_name; inc_refcount = true; break; + default: // ignore unknown + eDebug("fillTuple2 unknown '%c'... insert None in Result", argstring[pos]); } if (!tmp) { @@ -2081,16 +2112,14 @@ PyObject *eEPGCache::search(ePyObject arg) } else { - PyErr_SetString(PyExc_StandardError, - "type error"); + PyErr_SetString(PyExc_StandardError, "type error"); eDebug("tuple arg 4 is not a valid service reference string"); return NULL; } } else { - PyErr_SetString(PyExc_StandardError, - "type error"); + PyErr_SetString(PyExc_StandardError, "type error"); eDebug("tuple arg 4 is not a string"); return NULL; } @@ -2253,6 +2282,11 @@ PyObject *eEPGCache::search(ePyObject arg) { if (lookupEventId(ref, evid, ev)) eDebug("event not found !!!!!!!!!!!"); + else + { + const eServiceReferenceDVB &dref = (const eServiceReferenceDVB&)ref; + ptr.parseFrom(ev, (dref.getTransportStreamID().get()<<16)|dref.getOriginalNetworkID().get()); + } } // create service name if (!service_name) @@ -2484,7 +2518,7 @@ void eEPGCache::privateSectionRead(const uniqueEPGKey ¤t_service, const __ int sid = data[ptr++] << 8; sid |= data[ptr++]; -// WORKAROUND for wrong transmitted epg data (01.08.2006) +// WORKAROUND for wrong transmitted epg data (01.10.2007) if ( onid == 0x85 ) { switch( (tsid << 16) | sid ) @@ -2495,6 +2529,7 @@ void eEPGCache::privateSectionRead(const uniqueEPGKey ¤t_service, const __ case 0x0300f5: sid = 0xdc; break; case 0x0400d2: sid = 0xe2; tsid = 0x11; break; case 0x1100d3: sid = 0xe3; break; + case 0x0100d4: sid = 0xe4; tsid = 4; break; } } ////////////////////////////////////////////