+ eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
+ std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_services.find(service));
+ if (it != m_services.end())
+ {
+ m_services.erase(it);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+RESULT eDVBDB::removeServices(int dvb_namespace, int tsid, int onid, unsigned int orb_pos)
+{
+ return removeServices(eDVBChannelID(eDVBNamespace(dvb_namespace), eTransportStreamID(tsid), eOriginalNetworkID(onid)), orb_pos);
+}
+
+RESULT eDVBDB::removeServices(eDVBChannelID chid, unsigned int orbpos)
+{
+ RESULT ret=-1;
+ eDVBNamespace eNs;
+ eTransportStreamID eTsid;
+ eOriginalNetworkID eOnid;
+ std::map<eDVBChannelID, channel>::iterator it(m_channels.begin());
+ std::set<eDVBChannelID> removed_chids;
+ while (it != m_channels.end())
+ {
+ const eDVBChannelID &ch = it->first;
+ bool remove=true;
+ int system;
+ it->second.m_frontendParameters->getSystem(system);
+ if ( system == iDVBFrontend::feSatellite )
+ {
+ eDVBFrontendParametersSatellite sat;
+ it->second.m_frontendParameters->getDVBS(sat);
+ if ((unsigned int)sat.orbital_position != orbpos)
+ remove=false;
+ }
+ if ( remove && chid.dvbnamespace != eNs )
+ {
+ if (system == iDVBFrontend::feCable && chid.dvbnamespace.get() == (int)0xFFFF0000)
+ ;
+ else if (system == iDVBFrontend::feTerrestrial && chid.dvbnamespace.get() == (int)0xEEEE0000)
+ ;
+ else if ( chid.dvbnamespace != ch.dvbnamespace )
+ remove=false;
+ }
+ if ( remove && chid.original_network_id != eOnid && chid.original_network_id != ch.original_network_id )
+ remove=false;
+ if ( remove && chid.transport_stream_id != eTsid && chid.transport_stream_id != ch.transport_stream_id )
+ remove=false;
+ if ( remove )
+ {
+ eDebug("remove %08x %04x %04x",
+ ch.dvbnamespace.get(),
+ ch.original_network_id.get(),
+ ch.transport_stream_id.get());
+ removed_chids.insert(it->first);
+ m_channels.erase(it++);
+ }
+ else
+ ++it;
+ }
+ if (!removed_chids.empty())
+ {
+ std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator service(m_services.begin());
+ while(service != m_services.end())
+ {
+ eDVBChannelID chid;
+ service->first.getChannelID(chid);
+ std::set<eDVBChannelID>::iterator it(removed_chids.find(chid));
+ if (it != removed_chids.end())
+ m_services.erase(service++);
+ else
+ ++service;
+ ret=0;
+ }
+ }
+ return ret;
+}
+
+RESULT eDVBDB::addFlag(const eServiceReference &ref, unsigned int flagmask)
+{
+ if (ref.type == eServiceReference::idDVB)
+ {
+ eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
+ std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_services.find(service));
+ if (it != m_services.end())
+ it->second->m_flags |= ~flagmask;
+ return 0;
+ }
+ return -1;
+}
+
+RESULT eDVBDB::removeFlag(const eServiceReference &ref, unsigned int flagmask)
+{
+ if (ref.type == eServiceReference::idDVB)
+ {
+ eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
+ std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_services.find(service));
+ if (it != m_services.end())
+ it->second->m_flags &= ~flagmask;
+ return 0;
+ }
+ return -1;
+}
+
+RESULT eDVBDB::removeFlags(unsigned int flagmask, int dvb_namespace, int tsid, int onid, unsigned int orb_pos)
+{
+ return removeFlags(flagmask, eDVBChannelID(eDVBNamespace(dvb_namespace), eTransportStreamID(tsid), eOriginalNetworkID(onid)), orb_pos);
+}
+
+RESULT eDVBDB::removeFlags(unsigned int flagmask, eDVBChannelID chid, unsigned int orbpos)
+{
+ eDVBNamespace eNs;
+ eTransportStreamID eTsid;
+ eOriginalNetworkID eOnid;
+ std::map<eDVBChannelID, channel>::iterator it(m_channels.begin());
+ std::set<eDVBChannelID> removed_chids;
+ while (it != m_channels.end())
+ {
+ const eDVBChannelID &ch = it->first;
+ bool remove=true;
+ int system;
+ it->second.m_frontendParameters->getSystem(system);
+ if ( orbpos != 0xFFFFFFFF && system == iDVBFrontend::feSatellite )
+ {
+ eDVBFrontendParametersSatellite sat;
+ it->second.m_frontendParameters->getDVBS(sat);
+ if ((unsigned int)sat.orbital_position != orbpos)
+ remove=false;
+ }
+ if ( remove && chid.dvbnamespace != eNs )
+ {
+ if (system == iDVBFrontend::feCable && chid.dvbnamespace.get() == (int)0xFFFF0000)
+ ;
+ else if (system == iDVBFrontend::feTerrestrial && chid.dvbnamespace.get() == (int)0xEEEE0000)
+ ;
+ else if ( chid.dvbnamespace != ch.dvbnamespace )
+ remove=false;
+ }
+ if ( remove && chid.original_network_id != eOnid && chid.original_network_id != ch.original_network_id )
+ remove=false;
+ if ( remove && chid.transport_stream_id != eTsid && chid.transport_stream_id != ch.transport_stream_id )
+ remove=false;
+ if ( remove )
+ removed_chids.insert(it->first);
+ ++it;
+ }
+ if (!removed_chids.empty())
+ {
+ std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator service(m_services.begin());
+ while(service != m_services.end())
+ {
+ eDVBChannelID chid;
+ service->first.getChannelID(chid);
+ std::set<eDVBChannelID>::iterator it(removed_chids.find(chid));
+ if (it != removed_chids.end())
+ service->second->m_flags &= ~flagmask;
+ ++service;
+ }
+ }
+ return 0;
+}
+
+RESULT eDVBDB::addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm)
+{
+ channel ch;
+ assert(feparm);
+ ch.m_frontendParameters = feparm;
+ m_channels.insert(std::pair<eDVBChannelID, channel>(id, ch));
+ return 0;
+}
+
+RESULT eDVBDB::removeChannel(const eDVBChannelID &id)
+{
+ m_channels.erase(id);
+ return 0;
+}
+
+RESULT eDVBDB::getChannelFrontendData(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &parm)
+{
+ std::map<eDVBChannelID, channel>::iterator i = m_channels.find(id);
+ if (i == m_channels.end())
+ {
+ parm = 0;
+ return -ENOENT;
+ }
+ parm = i->second.m_frontendParameters;
+ return 0;
+}
+
+RESULT eDVBDB::addService(const eServiceReferenceDVB &serviceref, eDVBService *service)
+{
+ std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it(m_services.find(serviceref));
+ if (it == m_services.end())
+ m_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(serviceref, service));
+ return 0;
+}
+
+RESULT eDVBDB::getService(const eServiceReferenceDVB &reference, ePtr<eDVBService> &service)
+{
+ std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator i;
+ i = m_services.find(reference);
+ if (i == m_services.end())
+ {
+ service = 0;
+ return -ENOENT;
+ }
+ service = i->second;
+ return 0;
+}
+
+RESULT eDVBDB::flush()
+{
+ saveServicelist();
+ return 0;
+}
+
+RESULT eDVBDB::getBouquet(const eServiceReference &ref, eBouquet* &bouquet)
+{
+ std::string str = ref.path;
+ if (str.empty())
+ {
+ eDebug("getBouquet failed.. no path given!");
+ return -1;
+ }
+ size_t pos = str.find("FROM BOUQUET \"");
+ if ( pos != std::string::npos )
+ {
+ str.erase(0, pos+14);
+ pos = str.find('"');
+ if ( pos != std::string::npos )
+ str.erase(pos);
+ else
+ str.clear();
+ }
+ if (str.empty())
+ {
+ eDebug("getBouquet failed.. couldn't parse bouquet name");
+ return -1;
+ }
+ std::map<std::string, eBouquet>::iterator i =
+ m_bouquets.find(str);
+ if (i == m_bouquets.end())
+ {
+ bouquet = 0;
+ return -ENOENT;
+ }
+ bouquet = &i->second;
+ return 0;
+}
+
+RESULT eDVBDB::startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *q, const eServiceReference &source)
+{
+ if ( source.path.find("FROM") != std::string::npos )
+ {
+ if ( source.path.find("BOUQUET") != std::string::npos )
+ query = new eDVBDBBouquetQuery(this, source, q);
+ else if ( source.path.find("SATELLITES") != std::string::npos )
+ query = new eDVBDBSatellitesQuery(this, source, q);
+ else if ( source.path.find("PROVIDERS") != std::string::npos )
+ query = new eDVBDBProvidersQuery(this, source, q);
+ else
+ eFatal("invalid query %s", source.toString().c_str());
+ }
+ else
+ query = new eDVBDBQuery(this, source, q);
+ return 0;
+}
+
+eServiceReference eDVBDB::searchReference(int tsid, int onid, int sid)
+{
+ eServiceID Sid(sid);
+ eTransportStreamID Tsid(tsid);
+ eOriginalNetworkID Onid(onid);
+ for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator sit(m_services.begin());
+ sit != m_services.end(); ++sit)
+ {
+ if (sit->first.getTransportStreamID() == Tsid &&
+ sit->first.getOriginalNetworkID() == Onid &&
+ sit->first.getServiceID() == Sid)
+ return sit->first;
+ }
+ return eServiceReference();
+}
+
+DEFINE_REF(eDVBDBQueryBase);
+
+eDVBDBQueryBase::eDVBDBQueryBase(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)
+ :m_db(db), m_query(query), m_source(source)
+{
+}
+
+int eDVBDBQueryBase::compareLessEqual(const eServiceReferenceDVB &a, const eServiceReferenceDVB &b)
+{
+ ePtr<eDVBService> a_service, b_service;
+ int sortmode = m_query ? m_query->m_sort : eDVBChannelQuery::tName;
+
+ if ((sortmode == eDVBChannelQuery::tName) || (sortmode == eDVBChannelQuery::tProvider))
+ {
+ if (a.name.empty() && m_db->getService(a, a_service))
+ return 1;
+ if (b.name.empty() && m_db->getService(b, b_service))
+ return 1;
+ }
+
+ switch (sortmode)
+ {
+ case eDVBChannelQuery::tName:
+ if (a_service)
+ {
+ if (b_service)
+ return a_service->m_service_name_sort < b_service->m_service_name_sort;
+ else
+ {
+ std::string str = b.name;
+ makeUpper(str);
+ return a_service->m_service_name_sort < str;
+ }
+ }
+ else if (b_service)
+ {
+ std::string str = a.name;
+ makeUpper(str);
+ return str < b_service->m_service_name_sort;
+ }
+ else
+ {
+ std::string aa = a.name, bb = b.name;
+ makeUpper(aa);
+ makeUpper(bb);
+ return aa < bb;
+ }
+ case eDVBChannelQuery::tProvider:
+ return a_service->m_provider_name < b_service->m_provider_name;
+ case eDVBChannelQuery::tType:
+ return a.getServiceType() < b.getServiceType();
+ case eDVBChannelQuery::tBouquet:
+ return 0;
+ case eDVBChannelQuery::tSatellitePosition:
+ return (a.getDVBNamespace().get() >> 16) < (b.getDVBNamespace().get() >> 16);
+ default:
+ return 1;
+ }
+ return 0;
+}
+
+eDVBDBQuery::eDVBDBQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)
+ :eDVBDBQueryBase(db, source, query)
+{
+ m_cursor = m_db->m_services.begin();
+}
+
+RESULT eDVBDBQuery::getNextResult(eServiceReferenceDVB &ref)
+{
+ while (m_cursor != m_db->m_services.end())
+ {
+ ePtr<eDVBService> service = m_cursor->second;
+ if (service->isHidden())
+ ++m_cursor;
+ else
+ {
+ ref = m_cursor->first;
+
+ int res = (!m_query) || service->checkFilter(ref, *m_query);
+
+ ++m_cursor;
+
+ if (res)
+ return 0;
+ }
+ }
+
+ ref.type = eServiceReference::idInvalid;
+
+ return 1;
+}
+
+eDVBDBBouquetQuery::eDVBDBBouquetQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query)
+ :eDVBDBQueryBase(db, source, query), m_cursor(db->m_bouquets[query->m_bouquet_name].m_services.begin())
+{
+}
+
+RESULT eDVBDBBouquetQuery::getNextResult(eServiceReferenceDVB &ref)
+{
+ eBouquet &bouquet = m_db->m_bouquets[m_query->m_bouquet_name];
+ std::list<eServiceReference> &list = bouquet.m_services;
+ while (m_cursor != list.end())
+ {
+ ref = *((eServiceReferenceDVB*)&(*m_cursor));
+
+ std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator it =
+ m_db->m_services.find(ref);
+
+ int res = (!m_query) || it == m_db->m_services.end() || !(it->second->isHidden() && it->second->checkFilter(ref, *m_query));