}
}
-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)
{
}
else
servicemap.second.erase(tmp--);
+ ret = true;
}
else
{
#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)
if ( data[ptr-1] < 0x40 )
--ptr;
- uniqueEPGKey service( HILO(eit->service_id), HILO(eit->original_network_id), HILO(eit->transport_stream_id) );
+ // Cablecom HACK .. tsid / onid in eit data are incorrect.. so we use
+ // it from running channel (just for current transport stream eit data)
+ bool use_transponder_chid = source == SCHEDULE || (source == NOWNEXT && data[0] == 0x4E);
+ eDVBChannelID chid = channel->channel->getChannelID();
+ uniqueEPGKey service( HILO(eit->service_id),
+ use_transponder_chid ? chid.original_network_id.get() : HILO(eit->original_network_id),
+ use_transponder_chid ? chid.transport_stream_id.get() : HILO(eit->transport_stream_id));
+
eit_event_struct* eit_event = (eit_event_struct*) (data+ptr);
int eit_event_size;
int duration;
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;
}
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 )
{
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
RESULT eEPGCache::startTimeQuery(const eServiceReference &service, time_t begin, int minutes)
{
+ singleLock s(cache_lock);
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 = 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;
}
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);
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)
{
}
if (inc_refcount)
Py_INCREF(tmp);
- PyTuple_SET_ITEM(tuple, pos++, tmp);
+ PyTuple_SET_ITEM(tuple, tpos++, tmp);
}
}
// 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
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))
}
if (minutes)
{
- Lock();
+ singleLock s(cache_lock);
if (!startTimeQuery(ref, stime, minutes))
{
while ( m_timemap_cursor != m_timemap_end )
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 if (forceReturnOne && handleEvent(0, dest_list, argstring, argcount, service, nowTime, service_name, convertFunc, convertFuncArgs))
+ return 0; // error
}
else
{
eServiceEvent evt;
- Event *ev=0;
+ const eventData *ev_data=0;
if (stime)
{
+ singleLock s(cache_lock);
if (type == 2)
- lookupEventId(ref, event_id, ev);
+ lookupEventId(ref, event_id, ev_data);
else
- lookupEventTime(ref, stime, ev, type);
- if (ev)
+ lookupEventTime(ref, stime, ev_data, type);
+ if (ev_data)
{
const eServiceReferenceDVB &dref = (const eServiceReferenceDVB&)ref;
- evt.parseFrom(ev, (dref.getTransportStreamID().get()<<16)|dref.getOriginalNetworkID().get());
+ Event ev((uint8_t*)ev_data->get());
+ 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_data)
+ {
+ 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)
tmp = service_name;
inc_refcount = true;
break;
+ default: // ignore unknown
+ eDebug("fillTuple2 unknown '%c'... insert None in Result", argstring[pos]);
}
if (!tmp)
{
}
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;
}
{
// create servive event
eServiceEvent ptr;
- Event *ev=0;
+ const eventData *ev_data=0;
if (needServiceEvent)
{
- if (lookupEventId(ref, evid, ev))
+ if (lookupEventId(ref, evid, ev_data))
eDebug("event not found !!!!!!!!!!!");
else
{
const eServiceReferenceDVB &dref = (const eServiceReferenceDVB&)ref;
- ptr.parseFrom(ev, (dref.getTransportStreamID().get()<<16)|dref.getOriginalNetworkID().get());
+ Event ev((uint8_t*)ev_data->get());
+ ptr.parseFrom(&ev, (dref.getTransportStreamID().get()<<16)|dref.getOriginalNetworkID().get());
}
}
// create service name
// create tuple
ePyObject tuple = PyTuple_New(argcount);
// fill tuple
- fillTuple2(tuple, argstring, argcount, evit->second, ev ? &ptr : 0, service_name, service_reference);
+ fillTuple2(tuple, argstring, argcount, evit->second, ev_data ? &ptr : 0, service_name, service_reference);
PyList_Append(ret, tuple);
Py_DECREF(tuple);
--maxcount;