i think runLoop is better :)
[enigma2.git] / lib / dvb / epgcache.cpp
index 350e90ed143562d6877cfd9aa74d1a0e0e3dd2d6..e2583d728e925a86f58b32467a64bbfdcd748c06 100644 (file)
@@ -623,7 +623,7 @@ void eEPGCache::thread()
        nice(4);
        load();
        cleanLoop();
-       exec();
+       runLoop();
        save();
 }
 
@@ -1004,7 +1004,7 @@ void eEPGCache::channel_data::readData( const __u8 *data)
        }
 }
 
-RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, const eventData *&result )
+RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, const eventData *&result, int direction)
 // if t == -1 we search the current event...
 {
        singleLock s(cache_lock);
@@ -1016,20 +1016,24 @@ RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, co
        {
                if (t==-1)
                        t = time(0)+eDVBLocalTimeHandler::getInstance()->difference();
-               timeMap::iterator i = It->second.second.lower_bound(t);  // find > or equal
+               timeMap::iterator i = direction <= 0 ? It->second.second.lower_bound(t) :  // find > or equal
+                       It->second.second.upper_bound(t); // just >
                if ( i != It->second.second.end() )
                {
-                       if ( i->second->getStartTime() != t )
+                       if ( direction < 0 || (direction == 0 && i->second->getStartTime() > t) )
                        {
                                timeMap::iterator x = i;
                                --x;
                                if ( x != It->second.second.end() )
                                {
                                        time_t start_time = x->second->getStartTime();
-                                       if (t < start_time)
-                                               return -1;
-                                       if (t > (start_time+x->second->getDuration()))
-                                               return -1;
+                                       if (direction >= 0)
+                                       {
+                                               if (t < start_time)
+                                                       return -1;
+                                               if (t > (start_time+x->second->getDuration()))
+                                                       return -1;
+                                       }
                                        i = x;
                                }
                                else
@@ -1042,31 +1046,31 @@ RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, co
        return -1;
 }
 
-RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, const eit_event_struct *&result )
+RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, const eit_event_struct *&result, int direction)
 {
        singleLock s(cache_lock);
        const eventData *data=0;
-       RESULT ret = lookupEventTime(service, t, data);
+       RESULT ret = lookupEventTime(service, t, data, direction);
        if ( !ret && data )
                result = data->get();
        return ret;
 }
 
-RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, Event *& result )
+RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, Event *& result, int direction)
 {
        singleLock s(cache_lock);
        const eventData *data=0;
-       RESULT ret = lookupEventTime(service, t, data);
+       RESULT ret = lookupEventTime(service, t, data, direction);
        if ( !ret && data )
                result = new Event((uint8_t*)data->get());
        return ret;
 }
 
-RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, ePtr<eServiceEvent> &result )
+RESULT eEPGCache::lookupEventTime(const eServiceReference &service, time_t t, ePtr<eServiceEvent> &result, int direction)
 {
        singleLock s(cache_lock);
        const eventData *data=0;
-       RESULT ret = lookupEventTime(service, t, data);
+       RESULT ret = lookupEventTime(service, t, data, direction);
        if ( !ret && data )
        {
                Event ev((uint8_t*)data->get());
@@ -1264,21 +1268,26 @@ PyObject *handleEvent(ePtr<eServiceEvent> &ptr, PyObject *dest_list, char* argst
        if (convertFunc)
        {
                fillTuple(convertFuncArgs, argstring, argcount, service, ptr, nowTime, service_name);
-               PyObject *result = PyEval_CallObject(convertFunc, convertFuncArgs);
+               PyObject *result = PyObject_CallObject(convertFunc, convertFuncArgs);
                if (result == NULL)
                {
+                       if (service_name)
+                               Py_DECREF(service_name);
                        if (nowTime)
                                Py_DECREF(nowTime);
                        Py_DECREF(convertFuncArgs);
+                       Py_DECREF(dest_list);
                        return result;
                }
                PyList_Append(dest_list, result);
+               Py_DECREF(result);
        }
        else
        {
                PyObject *tuple = PyTuple_New(argcount);
                fillTuple(tuple, argstring, argcount, service, ptr, nowTime, service_name);
                PyList_Append(dest_list, tuple);
+               Py_DECREF(tuple);
        }
        return 0;
 }
@@ -1369,46 +1378,27 @@ PyObject *eEPGCache::lookupEvent(PyObject *list, PyObject *convertFunc)
                        int tupleSize=PyTuple_Size(item);
                        int tupleIt=0;
                        PyObject *service=NULL;
-                       PyObject *service_name=NULL;
-                       eServiceReference ref;
-                       char *refstr=NULL;
-                       while(tupleSize > tupleIt)
+                       while(tupleSize > tupleIt)  // parse query args
                        {
                                PyObject *entry=PyTuple_GET_ITEM(item, tupleIt); // borrowed reference!
                                switch(tupleIt++)
                                {
                                        case 0:
                                        {
-                                               refstr = PyString_AS_STRING(entry);
-                                               ref = eServiceReference(refstr);
-                                               if (must_get_service_name)
+                                               if (!PyString_Check(entry))
                                                {
-                                                       service = entry;
-                                                       ePtr<iStaticServiceInformation> sptr;
-                                                       eServiceCenterPtr ptr;
-                                                       eServiceCenter::getPrivInstance(ptr);
-                                                       if (ptr)
-                                                       {
-                                                               ptr->info(ref, sptr);
-                                                               if (sptr)
-                                                               {
-                                                                       std::string name;
-                                                                       sptr->getName(ref, name);
-                                                                       if (name.length())
-                                                                               service_name = PyString_FromString(name.c_str());
-                                                               }
-                                                       }
-                                                       if (!service_name)
-                                                               service_name = PyString_FromString("<n/a>");
+                                                       eDebug("tuple entry 0 is no a string");
+                                                       continue;
                                                }
+                                               service = entry;
                                                break;
                                        }
                                        case 1:
                                                type=PyInt_AsLong(entry);
-                                               if (type < 0 || type > 1)
+                                               if (type < -1 || type > 2)
                                                {
                                                        eDebug("unknown type %d", type);
-                                                       goto nextListEntry;
+                                                       continue;
                                                }
                                                break;
                                        case 2:
@@ -1422,41 +1412,61 @@ PyObject *eEPGCache::lookupEvent(PyObject *list, PyObject *convertFunc)
                                                break;
                                }
                        }
-                       if (refstr)
+                       eServiceReference ref(PyString_AS_STRING(service));
+                       if (ref.type != eServiceReference::idDVB)
+                       {
+                               eDebug("service reference for epg query is not valid");
+                               continue;
+                       }
+                       PyObject *service_name=NULL;
+                       if (must_get_service_name)
                        {
-                               if (minutes)
+                               ePtr<iStaticServiceInformation> sptr;
+                               eServiceCenterPtr service_center;
+                               eServiceCenter::getPrivInstance(service_center);
+                               if (service_center)
                                {
-                                       Lock();
-                                       if (!startTimeQuery(ref, stime, minutes))
+                                       service_center->info(ref, sptr);
+                                       if (sptr)
                                        {
-                                               ePtr<eServiceEvent> ptr;
-                                               while (!getNextTimeEntry(ptr))
-                                               {
-                                                       PyObject *ret = handleEvent(ptr, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs);
-                                                       if (ret)
-                                                               return ret;
-                                               }
+                                               std::string name;
+                                               sptr->getName(ref, name);
+                                               if (name.length())
+                                                       service_name = PyString_FromString(name.c_str());
                                        }
-                                       else
-                                               eDebug("startTimeQuery failed %s", refstr);
-                                       Unlock();
                                }
-                               else
+                               if (!service_name)
+                                       service_name = PyString_FromString("<n/a>");
+                       }
+                       if (minutes)
+                       {
+                               Lock();
+                               if (!startTimeQuery(ref, stime, minutes))
                                {
                                        ePtr<eServiceEvent> ptr;
-                                       if (stime)
+                                       while (!getNextTimeEntry(ptr))
                                        {
-                                               if (type == 0)
-                                                       lookupEventTime(ref, stime, ptr);
-                                               else // type == 1
-                                                       lookupEventId(ref, event_id, ptr);
+                                               PyObject *ret = handleEvent(ptr, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs);
+                                               if (ret)
+                                                       return ret;
                                        }
-                                       PyObject *ret = handleEvent(ptr, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs);
-                                       if (ret)
-                                               return ret;
                                }
+                               Unlock();
+                       }
+                       else
+                       {
+                               ePtr<eServiceEvent> ptr;
+                               if (stime)
+                               {
+                                       if (type == 2)
+                                               lookupEventId(ref, event_id, ptr);
+                                       else
+                                               lookupEventTime(ref, stime, ptr, type);
+                               }
+                               PyObject *ret = handleEvent(ptr, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs);
+                               if (ret)
+                                       return ret;
                        }
-nextListEntry:
                        if (service_name)
                                Py_DECREF(service_name);
                }
@@ -1467,3 +1477,7 @@ nextListEntry:
                Py_DECREF(nowTime);
        return dest_list;
 }
+
+
+
+