lookupEvent returns one entry for every service event though no event in
[enigma2.git] / lib / dvb / epgcache.cpp
index 3bc850600511ddccc0ccb6803d788c2d3ccbfb61..e08d81a51f8ea2bb63592b9858c7e31365ddeb79 100644 (file)
@@ -372,8 +372,9 @@ void eEPGCache::DVBChannelStateChanged(iDVBChannel *chan)
        }
 }
 
-void eEPGCache::FixOverlapping(std::pair<eventMap,timeMap> &servicemap, time_t TM, int duration, const timeMap::iterator &tm_it, const uniqueEPGKey &service)
+bool eEPGCache::FixOverlapping(std::pair<eventMap,timeMap> &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<eventMap,timeMap> &servicemap, time_t T
                        }
                        else
                                servicemap.second.erase(tmp--);
+                       ret = true;
                }
                else
                {
@@ -434,12 +436,14 @@ void eEPGCache::FixOverlapping(std::pair<eventMap,timeMap> &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<const time_t, eventData*>( 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
@@ -1386,13 +1397,13 @@ RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, co
                        It->second.second.upper_bound(t); // just >
                if ( i != It->second.second.end() )
                {
-                       if ( direction < 0 || (direction == 0 && i->second->getStartTime() > t) )
+                       if ( direction < 0 || (direction == 0 && i->first > t) )
                        {
                                timeMap::iterator x = i;
                                --x;
                                if ( x != It->second.second.end() )
                                {
-                                       time_t start_time = x->second->getStartTime();
+                                       time_t start_time = x->first;
                                        if (direction >= 0)
                                        {
                                                if (t < start_time)
@@ -1508,34 +1519,36 @@ RESULT eEPGCache::lookupEventId(const eServiceReference &service, int event_id,
 RESULT eEPGCache::startTimeQuery(const eServiceReference &service, time_t begin, int minutes)
 {
        const eServiceReferenceDVB &ref = (const eServiceReferenceDVB&)handleGroup(service);
+       if (begin == -1)
+               begin = eDVBLocalTimeHandler::getInstance()->nowTime();
        Lock();
        eventCache::iterator It = eventDB.find(ref);
        if ( It != eventDB.end() && It->second.second.size() )
        {
-               m_timemap_end = minutes != -1 ? It->second.second.upper_bound(begin+minutes*60) : It->second.second.end();
-               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->second->getStartTime() != 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->second->getStartTime();
-                                               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;
                                }
                        }
                }
+
+               if (minutes != -1)
+                       m_timemap_end = It->second.second.lower_bound(begin+minutes*60);
                else
-                       m_timemap_cursor = It->second.second.begin();
+                       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);
        }
        Unlock();
        return -1;
@@ -1582,7 +1595,7 @@ RESULT eEPGCache::getNextTimeEntry(ePtr<eServiceEvent> &result)
        return -1;
 }
 
-void fillTuple(ePyObject tuple, char *argstring, int argcount, ePyObject service, ePtr<eServiceEvent> &ptr, ePyObject nowTime, ePyObject service_name )
+void fillTuple(ePyObject tuple, char *argstring, int argcount, ePyObject service, eServiceEvent *ptr, ePyObject nowTime, ePyObject service_name )
 {
        ePyObject tmp;
        int pos=0;
@@ -1636,7 +1649,7 @@ void fillTuple(ePyObject tuple, char *argstring, int argcount, ePyObject service
        }
 }
 
-int handleEvent(ePtr<eServiceEvent> &ptr, ePyObject dest_list, char* argstring, int argcount, ePyObject service, ePyObject nowTime, ePyObject service_name, ePyObject convertFunc, ePyObject convertFuncArgs)
+int handleEvent(eServiceEvent *ptr, ePyObject dest_list, char* argstring, int argcount, ePyObject service, ePyObject nowTime, ePyObject service_name, ePyObject convertFunc, ePyObject convertFuncArgs)
 {
        if (convertFunc)
        {
@@ -1690,7 +1703,7 @@ int handleEvent(ePtr<eServiceEvent> &ptr, ePyObject dest_list, char* argstring,
 //    +1 = event after given start_time
 //   the third
 //      when type is eventid it is the event_id
-//      when type is time then it is the start_time ( 0 for now_time )
+//      when type is time then it is the start_time ( -1 for now_time )
 //   the fourth is the end_time .. ( optional .. for query all events in time range)
 
 PyObject *eEPGCache::lookupEvent(ePyObject list, ePyObject convertFunc)
@@ -1794,6 +1807,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)
                        {
@@ -1856,29 +1873,39 @@ PyObject *eEPGCache::lookupEvent(ePyObject list, ePyObject convertFunc)
                                Lock();
                                if (!startTimeQuery(ref, stime, minutes))
                                {
-                                       ePtr<eServiceEvent> ptr;
-                                       while (!getNextTimeEntry(ptr))
+                                       while ( m_timemap_cursor != m_timemap_end )
                                        {
-                                               if (handleEvent(ptr, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs))
+                                               Event ev((uint8_t*)m_timemap_cursor++->second->get());
+                                               eServiceEvent evt;
+                                               evt.parseFrom(&ev, currentQueryTsidOnid);
+                                               if (handleEvent(&evt, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs))
                                                {
                                                        Unlock();
                                                        return 0;  // error
                                                }
                                        }
                                }
+                               else
+                                       handleEvent(0, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs);
                                Unlock();
                        }
                        else
                        {
-                               ePtr<eServiceEvent> ptr;
+                               eServiceEvent evt;
+                               Event *ev=0;
                                if (stime)
                                {
                                        if (type == 2)
-                                               lookupEventId(ref, event_id, ptr);
+                                               lookupEventId(ref, event_id, ev);
                                        else
-                                               lookupEventTime(ref, stime, ptr, type);
+                                               lookupEventTime(ref, stime, ev, type);
+                                       if (ev)
+                                       {
+                                               const eServiceReferenceDVB &dref = (const eServiceReferenceDVB&)ref;
+                                               evt.parseFrom(ev, (dref.getTransportStreamID().get()<<16)|dref.getOriginalNetworkID().get());
+                                       }
                                }
-                               if (handleEvent(ptr, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs))
+                               if (handleEvent(ev ? &evt : 0, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs))
                                        return 0; // error
                        }
                        if (service_changed)
@@ -1896,7 +1923,7 @@ skip_entry:
        return dest_list;
 }
 
-void fillTuple2(ePyObject tuple, const char *argstring, int argcount, eventData *evData, ePtr<eServiceEvent> &ptr, ePyObject service_name, ePyObject service_reference)
+void fillTuple2(ePyObject tuple, const char *argstring, int argcount, eventData *evData, eServiceEvent *ptr, ePyObject service_name, ePyObject service_reference)
 {
        ePyObject tmp;
        int pos=0;
@@ -2234,12 +2261,17 @@ PyObject *eEPGCache::search(ePyObject arg)
                                        if (ref.valid())
                                        {
                                        // create servive event
-                                               ePtr<eServiceEvent> ptr;
+                                               eServiceEvent ptr;
+                                               Event *ev=0;
                                                if (needServiceEvent)
                                                {
-                                                       lookupEventId(ref, evid, ptr);
-                                                       if (!ptr)
+                                                       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)
@@ -2287,7 +2319,7 @@ PyObject *eEPGCache::search(ePyObject arg)
                                        // create tuple
                                                ePyObject tuple = PyTuple_New(argcount);
                                        // fill tuple
-                                               fillTuple2(tuple, argstring, argcount, evit->second, ptr, service_name, service_reference);
+                                               fillTuple2(tuple, argstring, argcount, evit->second, ev ? &ptr : 0, service_name, service_reference);
                                                PyList_Append(ret, tuple);
                                                Py_DECREF(tuple);
                                                --maxcount;
@@ -2471,7 +2503,7 @@ void eEPGCache::privateSectionRead(const uniqueEPGKey &current_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 )
@@ -2482,6 +2514,7 @@ void eEPGCache::privateSectionRead(const uniqueEPGKey &current_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;
                                        }
                                }
 ////////////////////////////////////////////