X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/1f3788c5e1a47fa9b0412902acba38c86b53bb63..7e3fc622d3a9dfcec4009d3fff223c6303e497ab:/lib/dvb/db.cpp diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 64ef6ed7..f3d44821 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -12,13 +12,19 @@ DEFINE_REF(eDVBService); -RESULT eBouquet::addService(const eServiceReference &ref) +RESULT eBouquet::addService(const eServiceReference &ref, eServiceReference before) { list::iterator it = std::find(m_services.begin(), m_services.end(), ref); if ( it != m_services.end() ) return -1; - m_services.push_back(ref); + if (before.valid()) + { + it = std::find(m_services.begin(), m_services.end(), before); + m_services.insert(it, ref); + } + else + m_services.push_back(ref); return 0; } @@ -75,24 +81,6 @@ RESULT eBouquet::flushChanges() { eServiceReference tmp = *i; std::string str = tmp.path; - if ( (i->flags&eServiceReference::flagDirectory) == eServiceReference::flagDirectory ) - { - unsigned int p1 = str.find("FROM BOUQUET \""); - if (p1 == std::string::npos) - { - eDebug("doof... kaputt"); - continue; - } - str.erase(0, p1+14); - p1 = str.find("\""); - if (p1 == std::string::npos) - { - eDebug("doof2... kaputt"); - continue; - } - str.erase(p1); - tmp.path=str; - } if ( fprintf(f, "#SERVICE %s\r\n", tmp.toString().c_str()) < 0 ) goto err; if ( i->name.length() ) @@ -114,21 +102,13 @@ RESULT eBouquet::setListName(const std::string &name) } eDVBService::eDVBService() - :m_flags(0) + :m_cache(0), m_flags(0) { - memset(m_cache, -1, sizeof(m_cache)); } eDVBService::~eDVBService() { -} - -bool eDVBService::cacheEmpty() -{ - for (int i=0; i < cacheMax; ++i) - if (m_cache[i] != -1) - return false; - return true; + delete [] m_cache; } eDVBService &eDVBService::operator=(const eDVBService &s) @@ -137,8 +117,8 @@ eDVBService &eDVBService::operator=(const eDVBService &s) m_service_name_sort = s.m_service_name_sort; m_provider_name = s.m_provider_name; m_flags = s.m_flags; -// m_ca = s.m_ca; - memcpy(m_cache, s.m_cache, sizeof(m_cache)); + m_ca = s.m_ca; + copyCache(s.m_cache); return *this; } @@ -170,7 +150,7 @@ RESULT eDVBService::getEvent(const eServiceReference &ref, ePtr & return eEPGCache::getInstance()->lookupEventTime(ref, start_time, ptr); } -bool eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore) +int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore) { ePtr res_mgr; if ( eDVBResourceManager::getInstance( res_mgr ) ) @@ -182,7 +162,7 @@ bool eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferen ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); return res_mgr->canAllocateChannel(chid, chid_ignore); } - return false; + return 0; } int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query) @@ -232,15 +212,47 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ return res; } -int eDVBService::getCachePID(cacheID id) +bool eDVBService::cacheEmpty() +{ + if (m_cache) + for (int i=0; i < cacheMax; ++i) + if (m_cache[i] != -1) + return false; + return true; +} + +void eDVBService::initCache() { - if (id >= cacheMax) + m_cache = new int[cacheMax]; + memset(m_cache, -1, sizeof(int) * cacheMax); +} + +void eDVBService::copyCache(int *source) +{ + if (source) + { + if (!m_cache) + m_cache = new int[cacheMax]; + memcpy(m_cache, source, cacheMax * sizeof(int)); + } + else + { + delete [] m_cache; + m_cache = 0; + } +} + +int eDVBService::getCacheEntry(cacheID id) +{ + if (id >= cacheMax || !m_cache) return -1; return m_cache[id]; } -void eDVBService::setCachePID(cacheID id, int pid) +void eDVBService::setCacheEntry(cacheID id, int pid) { + if (!m_cache) + initCache(); if (id < cacheMax) m_cache[id] = pid; } @@ -425,14 +437,14 @@ void eDVBDB::reloadServicelist() } else if (p == 'c') { int cid, val; - sscanf(v.c_str(), "%02d%04x", &cid, &val); - s->m_cache[cid]=val; - }/* else if (p == 'C') + sscanf(v.c_str(), "%02d%x", &cid, &val); + s->setCacheEntry((eDVBService::cacheID)cid,val); + } else if (p == 'C') { int val; sscanf(v.c_str(), "%04x", &val); - s->m_ca.insert(val); - }*/ + s->m_ca.push_front((uint16_t)val); + } } addService(ref, s); } @@ -517,15 +529,16 @@ void eDVBDB::saveServicelist() // write cached pids for (int x=0; x < eDVBService::cacheMax; ++x) - if (i->second->m_cache[x] != -1) - fprintf(f, ",c:%02d%04x", x, i->second->m_cache[x]); + { + int entry = i->second->getCacheEntry((eDVBService::cacheID)x); + if (entry != -1) + fprintf(f, ",c:%02d%04x", x, entry); + } -/* // write cached ca pids - for (std::set::const_iterator ca(i->second->m_ca.begin()); + for (CAID_LIST::const_iterator ca(i->second->m_ca.begin()); ca != i->second->m_ca.end(); ++ca) fprintf(f, ",C:%04x", *ca); -*/ if (i->second->m_flags) fprintf(f, ",f:%x", i->second->m_flags); @@ -602,7 +615,7 @@ void eDVBDB::loadBouquet(const char *path) break; if (line[0]=='#') { - if (!strncmp(line, "#SERVICE ", 9) || !strncmp(line, "#SERVICE: ", 10)) + if (!strncmp(line, "#SERVICE", 8)) { int offs = line[8] == ':' ? 10 : 9; eServiceReference tmp(line+offs); @@ -611,29 +624,48 @@ void eDVBDB::loadBouquet(const char *path) eDebug("only DVB Bouquets supported"); continue; } - if ( (tmp.flags&eServiceReference::flagDirectory) == eServiceReference::flagDirectory ) + if ( tmp.flags&eServiceReference::canDescent ) { unsigned int pos = tmp.path.rfind('/'); + char buf[256]; + std::string path = tmp.path; if ( pos != std::string::npos ) - tmp.path.erase(0, pos+1); - if (tmp.path.empty()) + path.erase(0, pos+1); + if (path.empty()) { eDebug("Bouquet load failed.. no filename given.."); continue; } - loadBouquet(tmp.path.c_str()); - char buf[256]; - snprintf(buf, 256, "(type == %d) FROM BOUQUET \"%s\" ORDER BY bouquet", tmp.data[0], tmp.path.c_str()); - tmp.path = buf; + pos = path.find("FROM BOUQUET "); + if (pos != std::string::npos) + { + char endchr = path[pos+13]; + if (endchr != '"') + { + eDebug("ignore invalid bouquet '%s' (only \" are allowed)", + tmp.toString().c_str()); + continue; + } + char *beg = &path[pos+14]; + char *end = strchr(beg, endchr); + path.assign(beg, end - beg); + } + else + { + snprintf(buf, 256, "FROM BOUQUET \"%s\" ORDER BY bouquet", path.c_str()); + tmp.path = buf; + } + loadBouquet(path.c_str()); } list.push_back(tmp); e = &list.back(); read_descr=true; ++entries; } - else if (read_descr && !strncmp(line, "#DESCRIPTION ", 13)) + else if (read_descr && !strncmp(line, "#DESCRIPTION", 12)) { - e->name = line+13; + int offs = line[12] == ':' ? 14 : 13; + e->name = line+offs; read_descr=false; } else if (!strncmp(line, "#NAME ", 6)) @@ -662,7 +694,7 @@ void eDVBDB::reloadBouquets() ref.type=1; ref.flags=7; ref.data[0]=1; - ref.path="(type == 1) FROM BOUQUET \"userbouquet.favourites.tv\" ORDER BY bouquet"; + ref.path="FROM BOUQUET \"userbouquet.favourites.tv\" ORDER BY bouquet"; eBouquet &parent = m_bouquets["bouquets.tv"]; parent.m_services.push_back(ref); parent.flushChanges(); @@ -678,7 +710,7 @@ void eDVBDB::reloadBouquets() ref.type=1; ref.flags=7; ref.data[0]=2; - ref.path="(type == 2) FROM BOUQUET \"userbouquet.favourites.radio\" ORDER BY bouquet"; + ref.path="FROM BOUQUET \"userbouquet.favourites.radio\" ORDER BY bouquet"; eBouquet &parent = m_bouquets["bouquets.radio"]; parent.m_services.push_back(ref); parent.flushChanges(); @@ -732,13 +764,15 @@ RESULT eDVBDB::removeServices(eDVBChannelID chid, unsigned int orbpos) bool remove=true; int system; it->second.m_frontendParameters->getSystem(system); - if ( orbpos != 0xFFFFFFFF && system == iDVBFrontend::feSatellite ) + if ( system == iDVBFrontend::feSatellite ) { eDVBFrontendParametersSatellite sat; it->second.m_frontendParameters->getDVBS(sat); if ((unsigned int)sat.orbital_position != orbpos) remove=false; } + else if (orbpos != 0xFFFFFFFF) // do not remove -C or -T transponders when a orbital position is given.. + remove=false; if ( remove && chid.dvbnamespace != eNs && chid.dvbnamespace != ch.dvbnamespace ) remove=false; if ( remove && chid.original_network_id != eOnid && chid.original_network_id != ch.original_network_id ) @@ -984,21 +1018,43 @@ eDVBDBQueryBase::eDVBDBQueryBase(eDVBDB *db, const eServiceReference &source, eD int eDVBDBQueryBase::compareLessEqual(const eServiceReferenceDVB &a, const eServiceReferenceDVB &b) { ePtr a_service, b_service; - int sortmode = m_query ? m_query->m_sort : eDVBChannelQuery::tName; if ((sortmode == eDVBChannelQuery::tName) || (sortmode == eDVBChannelQuery::tProvider)) { - if (m_db->getService(a, a_service)) + if (a.name.empty() && m_db->getService(a, a_service)) return 1; - if (m_db->getService(b, b_service)) + if (b.name.empty() && m_db->getService(b, b_service)) return 1; } switch (sortmode) { case eDVBChannelQuery::tName: - return a_service->m_service_name_sort < b_service->m_service_name_sort; + 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: @@ -1095,12 +1151,16 @@ int eDVBDBListQuery::compareLessEqual(const eServiceReferenceDVB &a, const eServ y -= 3600; return x < y; } - return a.name < b.name; + std::string aa = a.name, bb = b.name; + makeUpper(aa); + makeUpper(bb); + return aa < bb; } eDVBDBSatellitesQuery::eDVBDBSatellitesQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query) :eDVBDBListQuery(db, source, query) { + std::set found; for (std::map >::iterator it(m_db->m_services.begin()); it != m_db->m_services.end(); ++it) { @@ -1108,15 +1168,9 @@ eDVBDBSatellitesQuery::eDVBDBSatellitesQuery(eDVBDB *db, const eServiceReference if (res) { unsigned int dvbnamespace = it->first.getDVBNamespace().get()&0xFFFF0000; - bool found=0; - for (std::list::iterator i(m_list.begin()); i != m_list.end(); ++i) - if ( (i->getDVBNamespace().get()&0xFFFF0000) == dvbnamespace ) - { - found=true; - break; - } - if (!found) + if (found.find(dvbnamespace) == found.end()) { + found.insert(dvbnamespace); eServiceReferenceDVB ref; ref.setDVBNamespace(dvbnamespace); ref.flags=eServiceReference::flagDirectory; @@ -1153,26 +1207,19 @@ eDVBDBSatellitesQuery::eDVBDBSatellitesQuery(eDVBDB *db, const eServiceReference eDVBDBProvidersQuery::eDVBDBProvidersQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query) :eDVBDBListQuery(db, source, query) { + std::set found; for (std::map >::iterator it(m_db->m_services.begin()); it != m_db->m_services.end(); ++it) { int res = it->second->checkFilter(it->first, *query); if (res) { - bool found=0; - const char *provider_name = it->second->m_provider_name.length() ? it->second->m_provider_name.c_str() : "Unknown"; - - for (std::list::iterator i(m_list.begin()); i != m_list.end(); ++i) - if (i->name == provider_name) - { - found=true; - break; - } - if (!found) + if (found.find(std::string(provider_name)) == found.end()) { + found.insert(std::string(provider_name)); eServiceReferenceDVB ref; char buf[64]; ref.name=provider_name; @@ -1218,10 +1265,7 @@ RESULT parseExpression(ePtr &res, std::list::cons std::list::const_iterator end_of_exp; if (begin == end) - { - eDebug("empty expression!"); return 0; - } if (*begin == "(") { @@ -1333,9 +1377,18 @@ RESULT parseExpression(ePtr &res, std::list::cons } res->m_string = val; - res->m_int = atoi(val.c_str()); -// res->m_channelid = eDVBChannelID(val); - + + if (res->m_type == eDVBChannelQuery::tChannelID) + { + int ns, tsid, onid; + if (sscanf(val.c_str(), "%08x%04x%04x", &ns, &tsid, &onid) == 3) + res->m_channelid = eDVBChannelID(eDVBNamespace(ns), eTransportStreamID(tsid), eOriginalNetworkID(onid)); + else + eDebug("couldn't parse channelid !! format should be hex NNNNNNNNTTTTOOOO (namespace, tsid, onid)"); + } + else + res->m_int = atoi(val.c_str()); + return 0; }