X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/fe813cde98c0c550137b47dd7a75ec2d4d9e6f34..ebd60cac96b17be4c6fb0c64c7c43b4ef715c3e3:/lib/dvb/db.cpp diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 067b0032..a5a9a456 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -2,10 +2,11 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include DEFINE_REF(eDVBService); @@ -20,6 +21,7 @@ eDVBService::~eDVBService() eDVBService &eDVBService::operator=(const eDVBService &s) { m_service_name = s.m_service_name; + 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; @@ -44,7 +46,7 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ switch (query.m_type) { case eDVBChannelQuery::tName: - res = m_service_name.find(query.m_string) != std::string::npos; + res = m_service_name_sort.find(query.m_string) != std::string::npos; break; case eDVBChannelQuery::tProvider: res = m_provider_name.find(query.m_string) != std::string::npos; @@ -94,7 +96,8 @@ void eDVBService::setCachePID(cacheID id, int pid) DEFINE_REF(eDVBDB); -eDVBDB::eDVBDB() + /* THIS CODE IS BAD. it should be replaced by somethine better. */ +void eDVBDB::load() { eDebug("---- opening lame channel db"); FILE *f=fopen("lamedb", "rt"); @@ -114,7 +117,7 @@ eDVBDB::eDVBDB() fclose(f); return; } - + // clear all transponders while (!feof(f)) @@ -128,10 +131,10 @@ eDVBDB::eDVBDB() if (original_network_id == -1) continue; eDVBChannelID channelid = eDVBChannelID( - eDVBNamespace(dvb_namespace), - eTransportStreamID(transport_stream_id), + eDVBNamespace(dvb_namespace), + eTransportStreamID(transport_stream_id), eOriginalNetworkID(original_network_id)); - + ePtr feparm = new eDVBFrontendParameters; while (!feof(f)) { @@ -142,7 +145,7 @@ eDVBDB::eDVBDB() { eDVBFrontendParametersSatellite sat; int frequency, symbol_rate, polarisation, fec, orbital_position, inversion; - sscanf(line+2, "%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &inversion, &orbital_position); + sscanf(line+2, "%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion); sat.frequency = frequency; sat.symbol_rate = symbol_rate; sat.polarisation = polarisation; @@ -152,8 +155,23 @@ eDVBDB::eDVBDB() // ... // t.setSatellite(frequency, symbol_rate, polarisation, fec, sat, inversion); feparm->setDVBS(sat); - } - if (line[1]=='c') + } else if (line[1]=='t') + { + eDVBFrontendParametersTerrestrial ter; + int frequency, bandwidth, code_rate_HP, code_rate_LP, modulation, transmission_mode, guard_interval, hierarchy, inversion; + sscanf(line+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &bandwidth, &code_rate_HP, &code_rate_LP, &modulation, &transmission_mode, &guard_interval, &hierarchy, &inversion); + ter.frequency = frequency; + ter.bandwidth = bandwidth; + ter.code_rate_HP = code_rate_HP; + ter.code_rate_LP = code_rate_LP; + ter.modulation = modulation; + ter.transmission_mode = transmission_mode; + ter.guard_interval = guard_interval; + ter.hierarchy = hierarchy; + ter.inversion = inversion; + + feparm->setDVBT(ter); + } else if (line[1]=='c') { int frequency, symbol_rate, inversion=0, modulation=3; sscanf(line+2, "%d:%d:%d:%d", &frequency, &symbol_rate, &inversion, &modulation); @@ -168,9 +186,9 @@ eDVBDB::eDVBDB() eDebug("services invalid, no services"); return; } - + // clear all services - + int count=0; while (!feof(f)) @@ -185,7 +203,7 @@ eDVBDB::eDVBDB() if (service_number == -1) continue; ePtr s = new eDVBService; - eServiceReferenceDVB ref = + eServiceReferenceDVB ref = eServiceReferenceDVB( eDVBNamespace(dvb_namespace), eTransportStreamID(transport_stream_id), @@ -196,7 +214,11 @@ eDVBDB::eDVBDB() fgets(line, 256, f); if (strlen(line)) line[strlen(line)-1]=0; - s->m_service_name=line; + + s->m_service_name = line; + s->m_service_name_sort = removeDVBChars(line); + makeUpper(s->m_service_name_sort); + fgets(line, 256, f); if (strlen(line)) line[strlen(line)-1]=0; @@ -243,18 +265,17 @@ eDVBDB::eDVBDB() } eDebug("loaded %d services", count); - + fclose(f); - } -eDVBDB::~eDVBDB() +void eDVBDB::save() { eDebug("---- saving lame channel db"); FILE *f=fopen("lamedb", "wt"); int channels=0, services=0; if (!f) - eFatal("couldn't save lame channel db!"); + eFatal("couldn't save lame channel db!"); fprintf(f, "eDVB services /3/\n"); fprintf(f, "transponders\n"); for (std::map::const_iterator i(m_channels.begin()); @@ -262,37 +283,53 @@ eDVBDB::~eDVBDB() { const eDVBChannelID &chid = i->first; const channel &ch = i->second; - + fprintf(f, "%08x:%04x:%04x\n", chid.dvbnamespace.get(), chid.transport_stream_id.get(), chid.original_network_id.get()); eDVBFrontendParametersSatellite sat; + eDVBFrontendParametersTerrestrial ter; if (!ch.m_frontendParameters->getDVBS(sat)) { - fprintf(f, "\ts %d:%d:%d:%d:%d:%d\n", + fprintf(f, "\ts %d:%d:%d:%d:%d:%d\n", sat.frequency, sat.symbol_rate, - sat.polarisation, sat.fec, sat.inversion, - sat.orbital_position); + sat.polarisation, sat.fec, sat.orbital_position, + sat.inversion); + } + if (!ch.m_frontendParameters->getDVBT(ter)) + { + fprintf(f, "\tt %d:%d:%d:%d:%d:%d:%d:%d:%d\n", + ter.frequency, ter.bandwidth, ter.code_rate_HP, + ter.code_rate_LP, ter.modulation, ter.transmission_mode, + ter.guard_interval, ter.hierarchy, ter.inversion); } fprintf(f, "/\n"); channels++; } fprintf(f, "end\nservices\n"); - + for (std::map >::iterator i(m_services.begin()); i != m_services.end(); ++i) { const eServiceReferenceDVB &s = i->first; - fprintf(f, "%04x:%08x:%04x:%04x:%d:%d\n", - s.getServiceID().get(), s.getDVBNamespace().get(), - s.getTransportStreamID().get(),s.getOriginalNetworkID().get(), + fprintf(f, "%04x:%08x:%04x:%04x:%d:%d\n", + s.getServiceID().get(), s.getDVBNamespace().get(), + s.getTransportStreamID().get(),s.getOriginalNetworkID().get(), s.getServiceType(), 0); - + fprintf(f, "%s\n", i->second->m_service_name.c_str()); fprintf(f, "p:%s", i->second->m_provider_name.c_str()); + + // write cached pids + for (std::map::const_iterator ca(i->second->m_cache.begin()); + ca != i->second->m_cache.end(); ++ca) + fprintf(f, ",c:%02d%04x", ca->first, ca->second); + + // write cached ca pids for (std::set::const_iterator ca(i->second->m_ca.begin()); ca != i->second->m_ca.end(); ++ca) fprintf(f, ",C:%04x", *ca); + fprintf(f, "\n"); services++; } @@ -301,6 +338,16 @@ eDVBDB::~eDVBDB() fclose(f); } +eDVBDB::eDVBDB() +{ + load(); +} + +eDVBDB::~eDVBDB() +{ +// save(); +} + RESULT eDVBDB::addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm) { channel ch; @@ -374,10 +421,62 @@ RESULT eDVBDBQuery::getNextResult(eServiceReferenceDVB &ref) if (res) return 0; } + + ref = eServiceReferenceDVB(); return 1; } -/* ( <==|...> <"string"|int>)[AND (..)] */ +int eDVBDBQuery::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)) + return 1; + if (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; + 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 1; + case eDVBChannelQuery::tSatellitePosition: + return (a.getDVBNamespace().get() >> 16) < (b.getDVBNamespace().get() >> 16); + default: + return 1; + } + return 0; +} + +/* ( <==|...> <"string"|int>)[||,&& (..)] */ + +static int decodeType(const std::string &type) +{ + if (type == "name") + return eDVBChannelQuery::tName; + else if (type == "provider") + return eDVBChannelQuery::tProvider; + else if (type == "type") + return eDVBChannelQuery::tType; + else if (type == "bouquet") + return eDVBChannelQuery::tBouquet; + else if (type == "satellitePosition") + return eDVBChannelQuery::tSatellitePosition; + else if (type == "channelID") + return eDVBChannelQuery::tChannelID; + else + return -1; +} /* never, NEVER write a parser in C++! */ RESULT parseExpression(ePtr &res, std::list::const_iterator begin, std::list::const_iterator end) @@ -407,12 +506,16 @@ RESULT parseExpression(ePtr &res, std::list::cons /* we had only one sub expression */ if (end_of_exp == end) - return 1; + { + eDebug("only one sub expression"); + return 0; + } /* otherwise we have an operator here.. */ ePtr r2 = res; res = new eDVBChannelQuery(); + res->m_sort = 0; res->m_p1 = r2; res->m_inverse = 0; r2 = 0; @@ -437,6 +540,7 @@ RESULT parseExpression(ePtr &res, std::list::cons std::string type, op, val; res = new eDVBChannelQuery(); + res->m_sort = 0; int cnt = 0; while (begin != end) @@ -467,27 +571,15 @@ RESULT parseExpression(ePtr &res, std::list::cons return 1; } - if (type == "name") - res->m_type = eDVBChannelQuery::tName; - else if (type == "provider") - res->m_type = eDVBChannelQuery::tProvider; - else if (type == "type") - res->m_type = eDVBChannelQuery::tType; - else if (type == "bouquet") - res->m_type = eDVBChannelQuery::tBouquet; - else if (type == "satellitePosition") - res->m_type = eDVBChannelQuery::tSatellitePosition; - else if (type == "channelID") - res->m_type = eDVBChannelQuery::tChannelID; - else + res->m_type = decodeType(type); + + if (res->m_type == -1) { eDebug("malformed query: invalid type %s", type.c_str()); res = 0; return 1; } - eDebug("type is %d, nice!", res->m_type); - if (op == "==") res->m_inverse = 0; else if (op == "!=") @@ -512,7 +604,7 @@ RESULT eDVBChannelQuery::compile(ePtr &res, std::string query) std::string current_token; -// eDebug("splitting %s....", query.c_str()); + eDebug("splitting %s....", query.c_str()); unsigned int i = 0; const char *splitchars="()"; int quotemode = 0, lastsplit = 0, lastalnum = 0; @@ -552,15 +644,45 @@ RESULT eDVBChannelQuery::compile(ePtr &res, std::string query) // { // printf("%s\n", a->c_str()); // } + + int sort = eDVBChannelQuery::tName; + /* check for "ORDER BY ..." */ + if (tokens.size() > 2) + { + std::list::iterator i = tokens.end(); + --i; --i; --i; + if (*i == "ORDER") + { + ++i; + if (*i == "BY") + { + ++i; + sort = decodeType(*i); + tokens.pop_back(); // ... + tokens.pop_back(); // BY + tokens.pop_back(); // ORDER + } else + sort = -1; + } + } + + if (sort == -1) + { + eWarning("ORDER BY .. string invalid."); + res = 0; + return -1; + } + + eDebug("sort by %d", sort); /* now we recursivly parse that. */ - return parseExpression(res, tokens.begin(), tokens.end()); -/* - res = new eDVBChannelQuery(); - res->m_type = eDVBChannelQuery::tName; - res->m_inverse = 0; - res->m_string = query; - return 0; */ + int r = parseExpression(res, tokens.begin(), tokens.end()); + + if (res) + res->m_sort = sort; + + eDebug("return: %d", r); + return r; } DEFINE_REF(eDVBChannelQuery);