X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/ddc3964ed95d01e72229dc9af968a327cd84e56c..94284f21b07f1756120e8b6f5dd53e485a9ff66d:/lib/dvb/db.cpp diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 1a2cd7df..cdc05fcb 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -17,6 +17,63 @@ eDVBService::~eDVBService() { } +eDVBService &eDVBService::operator=(const eDVBService &s) +{ + m_service_name = s.m_service_name; + m_provider_name = s.m_provider_name; + m_flags = s.m_flags; + m_ca = s.m_ca; + m_cache = s.m_cache; + return *this; +} + +RESULT eDVBService::getName(const eServiceReference &ref, std::string &name) +{ + name = m_service_name; + return 0; +} + +int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query) +{ + int res = 0; + switch (query.m_type) + { + case eDVBChannelQuery::tName: + res = m_service_name.find(query.m_string) != std::string::npos; + break; + case eDVBChannelQuery::tProvider: + res = m_provider_name.find(query.m_string) != std::string::npos; + break; + case eDVBChannelQuery::tType: + res = ref.getServiceType() == query.m_int; + break; + case eDVBChannelQuery::tBouquet: + res = 0; + break; + case eDVBChannelQuery::tSatellitePosition: + res = (ref.getDVBNamespace().get() >> 16) == query.m_int; + break; + case eDVBChannelQuery::tChannelID: + { + eDVBChannelID chid; + ref.getChannelID(chid); + res = chid == query.m_channelid; + break; + } + case eDVBChannelQuery::tAND: + res = checkFilter(ref, *query.m_p1) && checkFilter(ref, *query.m_p2); + break; + case eDVBChannelQuery::tOR: + res = checkFilter(ref, *query.m_p1) || checkFilter(ref, *query.m_p2); + break; + } + + if (query.m_inverse) + return !res; + else + return res; +} + DEFINE_REF(eDVBDB); eDVBDB::eDVBDB() @@ -67,7 +124,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, &orbital_position, &inversion); + sscanf(line+2, "%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &inversion, &orbital_position); sat.frequency = frequency; sat.symbol_rate = symbol_rate; sat.polarisation = polarisation; @@ -209,15 +266,15 @@ eDVBDB::~eDVBDB() const eServiceReferenceDVB &s = i->first; fprintf(f, "%04x:%08x:%04x:%04x:%d:%d\n", s.getServiceID().get(), s.getDVBNamespace().get(), - s.getOriginalNetworkID().get(), s.getTransportStreamID().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()); + fprintf(f, "p:%s", i->second->m_provider_name.c_str()); 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, ",C:%04x", *ca); fprintf(f, "\n"); services++; } @@ -272,3 +329,220 @@ RESULT eDVBDB::getService(const eServiceReferenceDVB &reference, ePtr &query, eDVBChannelQuery *q) +{ + query = new eDVBDBQuery(this, eServiceReference(), q); + return 0; +} + +DEFINE_REF(eDVBDBQuery); + +eDVBDBQuery::eDVBDBQuery(eDVBDB *db, const eServiceReference &source, eDVBChannelQuery *query): m_db(db), m_query(query) +{ + // TODO: use SOURCE ... + m_cursor = m_db->m_services.begin(); +} + +RESULT eDVBDBQuery::getNextResult(eServiceReferenceDVB &ref) +{ + while (m_cursor != m_db->m_services.end()) + { + ref = m_cursor->first; + + int res = (!m_query) || m_cursor->second->checkFilter(ref, *m_query); + + ++m_cursor; + + if (res) + return 0; + } + return 1; +} + +/* ( <==|...> <"string"|int>)[AND (..)] */ + + /* never, NEVER write a parser in C++! */ +RESULT parseExpression(ePtr &res, std::list::const_iterator begin, std::list::const_iterator end) +{ + std::list::const_iterator end_of_exp; + if (*begin == "(") + { + end_of_exp = begin; + while (end_of_exp != end) + if (*end_of_exp == ")") + break; + else + ++end_of_exp; + + if (end_of_exp == end) + { + eDebug("expression parse: end of expression while searching for closing brace"); + return -1; + } + + ++begin; + // begin..end_of_exp + int r = parseExpression(res, begin, end_of_exp); + if (r) + return r; + ++end_of_exp; + + /* we had only one sub expression */ + if (end_of_exp == end) + return 1; + + /* otherwise we have an operator here.. */ + + ePtr r2 = res; + res = new eDVBChannelQuery(); + res->m_p1 = r2; + res->m_inverse = 0; + r2 = 0; + + if (*end_of_exp == "||") + res->m_type = eDVBChannelQuery::tOR; + else if (*end_of_exp == "&&") + res->m_type = eDVBChannelQuery::tAND; + else + { + eDebug("found operator %s, but only && and || are allowed!", end_of_exp->c_str()); + res = 0; + return 1; + } + + ++end_of_exp; + + return parseExpression(res->m_p2, end_of_exp, end); + } + + // "begin" "end" + std::string type, op, val; + + res = new eDVBChannelQuery(); + + int cnt = 0; + while (begin != end) + { + switch (cnt) + { + case 0: + type = *begin; + break; + case 1: + op = *begin; + break; + case 2: + val = *begin; + break; + case 3: + eDebug("malformed query: got '%s', but expected only ", begin->c_str()); + return 1; + } + ++begin; + ++cnt; + } + + if (cnt != 3) + { + eDebug("malformed query: missing stuff"); + res = 0; + 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 + { + 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 == "!=") + res->m_inverse = 1; + else + { + eDebug("invalid operator %s", op.c_str()); + res = 0; + return 1; + } + + res->m_string = val; + res->m_int = atoi(val.c_str()); +// res->m_channelid = eDVBChannelID(val); + + return 0; +} + +RESULT eDVBChannelQuery::compile(ePtr &res, std::string query) +{ + std::list tokens; + + std::string current_token; + +// eDebug("splitting %s....", query.c_str()); + unsigned int i = 0; + const char *splitchars="()"; + int quotemode = 0, lastsplit = 0, lastalnum = 0; + while (i <= query.size()) + { + int c = (i < query.size()) ? query[i] : ' '; + ++i; + + int issplit = !!strchr(splitchars, c); + int isaln = isalnum(c); + int iswhite = c == ' '; + int isquot = c == '\"'; + + if (quotemode) + { + iswhite = issplit = 0; + isaln = lastalnum; + } + + if (issplit || iswhite || isquot || lastsplit || (lastalnum != isaln)) + { + if (current_token.size()) + tokens.push_back(current_token); + current_token.clear(); + } + + if (!(iswhite || isquot)) + current_token += c; + + if (isquot) + quotemode = !quotemode; + lastsplit = issplit; + lastalnum = isaln; + } + +// for (std::list::const_iterator a(tokens.begin()); a != tokens.end(); ++a) +// { +// printf("%s\n", a->c_str()); +// } + + /* 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; */ +} + +DEFINE_REF(eDVBChannelQuery);