diff options
-rw-r--r-- | p2pvr/scanner/Jamfile.jam | 3 | ||||
-rw-r--r-- | p2pvr/scanner/dvbSiReaderHelper.cpp | 6 | ||||
-rw-r--r-- | p2pvr/scanner/dvbSiReaderHelper.h | 4 | ||||
-rw-r--r-- | p2pvr/scanner/eitRows.cpp | 109 | ||||
-rw-r--r-- | p2pvr/scanner/eitRows.h | 39 | ||||
-rw-r--r-- | p2pvr/scanner/serviceRows.cpp | 87 | ||||
-rw-r--r-- | p2pvr/scanner/serviceRows.h | 28 |
7 files changed, 106 insertions, 170 deletions
diff --git a/p2pvr/scanner/Jamfile.jam b/p2pvr/scanner/Jamfile.jam index 81fdb9d..e7af082 100644 --- a/p2pvr/scanner/Jamfile.jam +++ b/p2pvr/scanner/Jamfile.jam @@ -14,8 +14,7 @@ lib p2pvr-scan-p2 : serviceRows.cpp dvbSiReaderHelper.cpp : - <library>../../project2//p2common - <library>boost_regex + <library>../../project2/common//p2common ; # ScannerICE - the ICE test app diff --git a/p2pvr/scanner/dvbSiReaderHelper.cpp b/p2pvr/scanner/dvbSiReaderHelper.cpp index 330b1eb..1737921 100644 --- a/p2pvr/scanner/dvbSiReaderHelper.cpp +++ b/p2pvr/scanner/dvbSiReaderHelper.cpp @@ -16,9 +16,9 @@ const std::string DvbSiReaderHelper::ISO10646("ISO-10646"); const std::string DvbSiReaderHelper::EitEncoding("ISO6937"); const std::string DvbSiReaderHelper::UTF8("UTF8"); -DvbSiReaderHelper::DvbSiReaderHelper(const xmlpp::Element * p) : - demux(p, "demux", false, "/dev/dvb/adapter0/demux0"), - timeout(p, "timeout", false, 10000), +DvbSiReaderHelper::DvbSiReaderHelper(const ScriptNodePtr p) : + demux(p, "demux", "/dev/dvb/adapter0/demux0"), + timeout(p, "timeout", 10000), fd_epg(0) { } diff --git a/p2pvr/scanner/dvbSiReaderHelper.h b/p2pvr/scanner/dvbSiReaderHelper.h index d82ab29..bdcc3b6 100644 --- a/p2pvr/scanner/dvbSiReaderHelper.h +++ b/p2pvr/scanner/dvbSiReaderHelper.h @@ -1,14 +1,14 @@ #ifndef DVBSIREADERHELPER_H #define DVBSIREADERHELPER_H -#include "xmlObjectLoader.h" +#include "scripts.h" #include "variables.h" class RowProcessor; class DvbSiReaderHelper { public: - DvbSiReaderHelper(const xmlpp::Element * p); + DvbSiReaderHelper(const ScriptNodePtr p); ~DvbSiReaderHelper(); const Variable demux; diff --git a/p2pvr/scanner/eitRows.cpp b/p2pvr/scanner/eitRows.cpp index 23e8cfe..6f1934a 100644 --- a/p2pvr/scanner/eitRows.cpp +++ b/p2pvr/scanner/eitRows.cpp @@ -88,45 +88,20 @@ EitRows::loadComplete(const CommonObjects *) { } -void -EitRows::setFilter(const Glib::ustring &) +EitRowState::EitRowState() : + current(NULL) { } -unsigned int -EitRows::columnCount() const +const Columns & +EitRowState::getColumns() const { - return 1; -} - -const Glib::ustring & -EitRows::getColumnName(unsigned int) const { - return title; -} - -VariableType -EitRows::getCurrentValue(const Glib::ustring &) const { - return current->title; -} - -VariableType -EitRows::getCurrentValue(unsigned int) const { - return current->title; -} - -bool -EitRows::isNull(unsigned int ) const { - return false; -} - -bool -EitRows::isNull(const Glib::ustring & ) const { - return false; + return columns; } #define returnAttr(name) if (attrName == #name) return boost::bind(getMember<EitProgram, VariableType>, &EitProgram::name, boost::ref(current)) -RowSet::RowAttribute -EitRows::resolveAttr(const Glib::ustring & attrName) const { +RowState::RowAttribute +EitRowState::resolveAttr(const Glib::ustring & attrName) const { returnAttr(serviceID); returnAttr(eventID); returnAttr(title); @@ -158,10 +133,9 @@ EitRows::resolveAttr(const Glib::ustring & attrName) const { DECLARE_LOADER("eitrows", EitRows); -EitRows::EitRows(const xmlpp::Element * p) : +EitRows::EitRows(const ScriptNodePtr p) : RowSet(p), - DvbSiReaderHelper(p), - current(NULL) + DvbSiReaderHelper(p) { } @@ -169,15 +143,15 @@ EitRows::~EitRows() { } -static int time_offset = 0; -static int chan_filter = 0; +static int time_offset = 0; +static int chan_filter = 0; static int chan_filter_mask = 0; static Glib::RefPtr<Glib::Regex> episodeRegex = Glib::Regex::create("[ (]+(?:\\w+ )?([0-9]+)(?: of |/)([0-9]+)[.)]+"); static Glib::RefPtr<Glib::Regex> yearRegex = Glib::Regex::create("\\(([0-9]{4})[ )]+"); static Glib::RefPtr<Glib::Regex> flagsRegex = Glib::Regex::create("[ []+([A-Z,]+)\\]"); void -EitRows::parseEventDescription(const u_char *data) const { +EitRows::parseEventDescription(const u_char * data, EitProgram * current) const { assert(GetDescriptorTag(data) == 0x4D); const struct descr_short_event *evtdesc = reinterpret_cast<const struct descr_short_event *>(data); @@ -240,25 +214,25 @@ EitRows::parseEventDescription(const u_char *data) const { } if (title) { boost::algorithm::trim_if(*title, isspace); - current->title = title; + current->title = *title; } if (subtitle) { boost::algorithm::trim_if(*subtitle, isspace); if (!subtitle->empty()) { - current->subtitle = subtitle; + current->subtitle = *subtitle; } } if (desc) { boost::algorithm::trim_if(*desc, isspace); if (!desc->empty()) { - current->desc1 = desc; + current->desc1 = *desc; } } } /* Parse 0x4E Extended Event Descriptor. {{{ */ void -EitRows::parseLongEventDescription(const u_char *data) const { +EitRows::parseLongEventDescription(const u_char * data, EitProgram * current) const { assert(GetDescriptorTag(data) == 0x4E); const struct descr_extended_event *levt = reinterpret_cast<const struct descr_extended_event *>(data); bool non_empty = (levt->descriptor_number || levt->last_descriptor_number || levt->length_of_items || levt->data[0]); @@ -274,21 +248,21 @@ EitRows::parseLongEventDescription(const u_char *data) const { const struct item_extended_event *name = reinterpret_cast<const struct item_extended_event *>(p); size_t name_len = name->item_description_length; assert(p + ITEM_EXTENDED_EVENT_LEN + name_len < data_end); - current->desc1 = convert((const char *)name->data, name_len); + current->desc1 = *convert((const char *)name->data, name_len); p += ITEM_EXTENDED_EVENT_LEN + name_len; const struct item_extended_event *value = reinterpret_cast<const struct item_extended_event *>(p); size_t value_len = value->item_description_length; assert(p + ITEM_EXTENDED_EVENT_LEN + value_len < data_end); - current->desc2 = convert((const char *)value->data, value_len); + current->desc2 = *convert((const char *)value->data, value_len); p += ITEM_EXTENDED_EVENT_LEN + value_len; } const struct item_extended_event *text = reinterpret_cast<const struct item_extended_event *>(p); size_t len = text->item_description_length; if (non_empty && len) { - current->desc3 = convert((const char *)text->data, len); + current->desc3 = *convert((const char *)text->data, len); } } @@ -300,7 +274,7 @@ EitRows::parseLongEventDescription(const u_char *data) const { only output the first one of each (XMLTV can't cope with more than one) */ void -EitRows::parseComponentDescription(const u_char *data) const { +EitRows::parseComponentDescription(const u_char * data, EitProgram * current) const { assert(GetDescriptorTag(data) == 0x50); const struct descr_component *dc = reinterpret_cast<const struct descr_component *>(data); @@ -325,7 +299,7 @@ EitRows::parseComponentDescription(const u_char *data) const { } /*}}}*/ void -EitRows::parseContentDescription(const u_char *data) const { +EitRows::parseContentDescription(const u_char * data, EitProgram * current) const { assert(GetDescriptorTag(data) == 0x54); const struct descr_content * dc = reinterpret_cast<const struct descr_content *>(data); for (const u_char * p = reinterpret_cast<const u_char*>(&dc->data); p < data + DESCR_GEN_LEN + dc->descriptor_length; p += NIBBLE_CONTENT_LEN) { @@ -337,7 +311,7 @@ EitRows::parseContentDescription(const u_char *data) const { } void -EitRows::parseRatingDescription(const u_char *data) const { +EitRows::parseRatingDescription(const u_char * data, EitProgram * current) const { assert(GetDescriptorTag(data) == 0x55); const struct descr_parental_rating * pr = reinterpret_cast<const struct descr_parental_rating *>(data); for (const u_char * p = reinterpret_cast<const u_char *>(&pr->data); p < data + DESCR_GEN_LEN + pr->descriptor_length; p += PARENTAL_RATING_ITEM_LEN) { @@ -362,7 +336,7 @@ int parsePrivateDataSpecifier(const u_char *data) { /* Parse 0x76 Content Identifier Descriptor. {{{ */ /* See ETSI TS 102 323, section 12 */ void -EitRows::parseContentIdentifierDescription(const u_char *data) const { +EitRows::parseContentIdentifierDescription(const u_char * data, EitProgram * current) const { assert(GetDescriptorTag(data) == 0x76); const struct descr_content_identifier *ci = reinterpret_cast<const struct descr_content_identifier *>(data); for (const u_char * p = reinterpret_cast<const u_char *>(&ci->data); p < data + DESCR_GEN_LEN + ci->descriptor_length; p += DESCR_GEN_LEN + ci->descriptor_length) { @@ -404,7 +378,7 @@ EitRows::parseContentIdentifierDescription(const u_char *data) const { 'new', 'subtitles', 'rating', 'star-rating' */ void -EitRows::parseDescription(const u_char * data, size_t len) const { +EitRows::parseDescription(const u_char * data, size_t len, EitProgram * current) const { int pds = 0; for (const u_char * p = data; p < data + len; p += DESCR_GEN_LEN + GetDescriptorLength(p)) { const struct descr_gen *desc = reinterpret_cast<const struct descr_gen *>(p); @@ -413,21 +387,21 @@ EitRows::parseDescription(const u_char * data, size_t len) const { break; case 0x4D: //short evt desc, [title] [sub-title] // there can be multiple language versions of these - parseEventDescription(p); + parseEventDescription(p, current); break; case 0x4E: //long evt descriptor [desc] - parseLongEventDescription(p); + parseLongEventDescription(p, current); break; case 0x50: //component desc [language] [video] [audio] [subtitles] - parseComponentDescription(p); + parseComponentDescription(p, current); break; case 0x53: // CA Identifier Descriptor break; case 0x54: // content desc [category] - parseContentDescription(p); + parseContentDescription(p, current); break; case 0x55: // Parental Rating Descriptor [rating] - parseRatingDescription(p); + parseRatingDescription(p, current); break; case 0x5f: // Private Data Specifier pds = parsePrivateDataSpecifier(p); @@ -452,7 +426,7 @@ EitRows::parseDescription(const u_char * data, size_t len) const { case 0x86: // Eacem Stream Identifier Descriptor break; case 0x76: // Content identifier descriptor - parseContentIdentifierDescription(p); + parseContentIdentifierDescription(p, current); break; default: break; @@ -491,6 +465,7 @@ EitRows::parseInfoTable(const u_char *data, size_t len, const RowProcessor * rp) len -= 4; //remove CRC // For each event listing + EitRowState state; bool found = false; for (const u_char *p = reinterpret_cast<const u_char *>(&e->data); p < data + len; p += EIT_EVENT_LEN + GetEITDescriptorsLoopLength(p)) { const struct eit_event *evt = reinterpret_cast<const struct eit_event *>(p); @@ -512,7 +487,7 @@ EitRows::parseInfoTable(const u_char *data, size_t len, const RowProcessor * rp) BcdCharToInt(evt->start_time_m), BcdCharToInt(evt->start_time_s)); EitProgram results; - current = &results; + state.current = &results; results.startTime = startTime; results.stopTime = startTime + boost::posix_time::time_duration( BcdCharToInt(evt->duration_h), @@ -528,9 +503,8 @@ EitRows::parseInfoTable(const u_char *data, size_t len, const RowProcessor * rp) results.serviceID = HILO(e->service_id); results.eventID = HILO(evt->event_id); - parseDescription(reinterpret_cast<const u_char *>(&evt->data), GetEITDescriptorsLoopLength(evt)); - rp->rowReady(); - rowNum += 1; + parseDescription(reinterpret_cast<const u_char *>(&evt->data), GetEITDescriptorsLoopLength(evt), &results); + state.process(rp); found = true; } return found; @@ -555,17 +529,10 @@ EitRows::filterInput(int fd) const } void -EitRows::execute(const RowProcessor * rp) const +EitRows::execute(const Glib::ustring &, const RowProcessor * rp) const { - try { - openInput(); - readTables(rp); - closeInput(); - seenPrograms.clear(); - } - catch (...) { - seenPrograms.clear(); - throw; - } + openInput(); + readTables(rp); + closeInput(); } diff --git a/p2pvr/scanner/eitRows.h b/p2pvr/scanner/eitRows.h index bc44568..1d76c2d 100644 --- a/p2pvr/scanner/eitRows.h +++ b/p2pvr/scanner/eitRows.h @@ -1,7 +1,7 @@ #ifndef EITROWS_H #define EITROWS_H -#include "xmlObjectLoader.h" +#include "scripts.h" #include "rowSet.h" #include "variables.h" #include "dvbSiReaderHelper.h" @@ -10,19 +10,11 @@ class EitProgram; class EitRows : public RowSet, DvbSiReaderHelper { public: - EitRows(const xmlpp::Element * p); + EitRows(const ScriptNodePtr p); ~EitRows(); - void execute(const RowProcessor *) const; + void execute(const Glib::ustring &, const RowProcessor *) const; void loadComplete(const CommonObjects *); - void setFilter(const Glib::ustring &); - unsigned int columnCount() const; - const Glib::ustring & getColumnName(unsigned int) const; - VariableType getCurrentValue(const Glib::ustring &) const; - VariableType getCurrentValue(unsigned int) const; - bool isNull(unsigned int ) const; - bool isNull(const Glib::ustring & ) const; - RowAttribute resolveAttr(const Glib::ustring & attrName) const; private: class SeenProgram { @@ -37,16 +29,27 @@ class EitRows : public RowSet, DvbSiReaderHelper { void filterInput(int fd) const; bool parseInfoTable(const u_char *data, size_t len, const RowProcessor *) const; - void parseEventDescription(const u_char *data) const; - void parseLongEventDescription(const u_char *data) const; - void parseComponentDescription(const u_char *data) const; - void parseContentDescription(const u_char *data) const; - void parseRatingDescription(const u_char *data) const; - void parseContentIdentifierDescription(const u_char *data) const; - void parseDescription(const u_char * data, size_t len) const; + void parseEventDescription(const u_char *data, EitProgram * current) const; + void parseLongEventDescription(const u_char *data, EitProgram * current) const; + void parseComponentDescription(const u_char *data, EitProgram * current) const; + void parseContentDescription(const u_char *data, EitProgram * current) const; + void parseRatingDescription(const u_char *data, EitProgram * current) const; + void parseContentIdentifierDescription(const u_char *data, EitProgram * current) const; + void parseDescription(const u_char * data, size_t len, EitProgram * current) const; +}; +class EitRowState : public RowState { + public: + EitRowState(); + const Columns & getColumns() const; + RowAttribute resolveAttr(const Glib::ustring & attrName) const; + + private: + Columns columns; + friend class EitRows; mutable EitProgram * current; }; + #endif diff --git a/p2pvr/scanner/serviceRows.cpp b/p2pvr/scanner/serviceRows.cpp index 3489f72..39a0cd7 100644 --- a/p2pvr/scanner/serviceRows.cpp +++ b/p2pvr/scanner/serviceRows.cpp @@ -30,41 +30,15 @@ ServiceRows::loadComplete(const CommonObjects *) { } -void -ServiceRows::setFilter(const Glib::ustring &) +ServiceRowState::ServiceRowState() : + current(NULL) { } -unsigned int -ServiceRows::columnCount() const +const Columns & +ServiceRowState::getColumns() const { - return 1; -} - -static Glib::ustring name("name"); -const Glib::ustring & -ServiceRows::getColumnName(unsigned int) const { - return ::name; -} - -VariableType -ServiceRows::getCurrentValue(const Glib::ustring &) const { - return current->name; -} - -VariableType -ServiceRows::getCurrentValue(unsigned int) const { - return current->name; -} - -bool -ServiceRows::isNull(unsigned int ) const { - return false; -} - -bool -ServiceRows::isNull(const Glib::ustring & ) const { - return false; + return columns; } SimpleMessageException(NoSuchAttribute); @@ -74,8 +48,8 @@ getMember(M C::*t, C * p) { return p->*t; } #define returnAttr(name) if (attrName == #name) return boost::bind(getMember<Service, VariableType>, &Service::name, boost::ref(current)) -RowSet::RowAttribute -ServiceRows::resolveAttr(const Glib::ustring & attrName) const { +RowState::RowAttribute +ServiceRowState::resolveAttr(const Glib::ustring & attrName) const { returnAttr(serviceID); returnAttr(name); returnAttr(type); @@ -87,7 +61,7 @@ ServiceRows::resolveAttr(const Glib::ustring & attrName) const { DECLARE_LOADER("servicerows", ServiceRows); -ServiceRows::ServiceRows(const xmlpp::Element * e) : +ServiceRows::ServiceRows(const ScriptNodePtr e) : RowSet(e), DvbSiReaderHelper(e) { @@ -114,18 +88,11 @@ ServiceRows::filterInput(int fd) const } void -ServiceRows::execute(const RowProcessor * rp) const +ServiceRows::execute(const Glib::ustring &, const RowProcessor * rp) const { - try { - openInput(); - readTables(rp); - closeInput(); - seenServices.clear(); - } - catch (...) { - seenServices.clear(); - throw; - } + openInput(); + readTables(rp); + closeInput(); } bool @@ -136,34 +103,32 @@ ServiceRows::parseInfoTable(const u_char * data, size_t len, const RowProcessor // For each event listing bool found = false; + ServiceRowState state; for (const u_char * p = e->serviceData; p < data + len; ) { const struct si * sid = reinterpret_cast<const struct si *>(p); int sID = be16toh(sid->serviceid); bool seen = (seenServices.find(sID) != seenServices.end()); - size_t dll = HILO(sid->desc_loop_len); - Service serv; - for (p = sid->descData; p < sid->descData + dll; p += DESCR_GEN_LEN + GetDescriptorLength(p)) { - if (!seen) { - current = &serv; + if (!seen) { + size_t dll = HILO(sid->desc_loop_len); + Service serv; + state.current = &serv; + for (p = sid->descData; p < sid->descData + dll; p += DESCR_GEN_LEN + GetDescriptorLength(p)) { serv.serviceID = sID; serv.transportID = be16toh(e->transport_stream_id); const struct descr_gen *desc = reinterpret_cast<const struct descr_gen *>(p); switch (GetDescriptorTag(desc)) { case 0x48: // Service descriptor - parseServiceDescriptor(p, GetDescriptorLength(desc)); + parseServiceDescriptor(p, GetDescriptorLength(desc), &serv); break; case 0x73: // Service authority descriptor - parseServiceAuthDescriptor(p, GetDescriptorLength(desc)); + parseServiceAuthDescriptor(p, GetDescriptorLength(desc), &serv); break; default: break; } } - } - if (!seen) { seenServices.insert(sID); - rp->rowReady(); - rowNum += 1; + state.process(rp); found = true; } } @@ -171,18 +136,18 @@ ServiceRows::parseInfoTable(const u_char * data, size_t len, const RowProcessor } void -ServiceRows::parseServiceDescriptor(const u_char * p, size_t) const +ServiceRows::parseServiceDescriptor(const u_char * p, size_t, Service * current) const { current->type = p[2]; if (p[3]) { - current->providerName = convert((const char *)(p + 4), p[3]); + current->providerName = *convert((const char *)(p + 4), p[3]); } - current->name = convert((const char *)(p + 5 + p[3]), p[4 + p[3]]); + current->name = *convert((const char *)(p + 5 + p[3]), p[4 + p[3]]); } void -ServiceRows::parseServiceAuthDescriptor(const u_char * p, size_t len) const +ServiceRows::parseServiceAuthDescriptor(const u_char * p, size_t len, Service * current) const { - current->defaultAuthority = convert((const char *)(p + 2), len); + current->defaultAuthority = *convert((const char *)(p + 2), len); } diff --git a/p2pvr/scanner/serviceRows.h b/p2pvr/scanner/serviceRows.h index 7ad2457..0fbd119 100644 --- a/p2pvr/scanner/serviceRows.h +++ b/p2pvr/scanner/serviceRows.h @@ -1,7 +1,7 @@ #ifndef SERVICEROWS_H #define SERVICEROWS_H -#include "xmlObjectLoader.h" +#include "scripts.h" #include "rowSet.h" #include "variables.h" #include "dvbSiReaderHelper.h" @@ -10,19 +10,11 @@ class Service; class ServiceRows : public RowSet, DvbSiReaderHelper { public: - ServiceRows(const xmlpp::Element * p); + ServiceRows(const ScriptNodePtr p); ~ServiceRows(); - void execute(const RowProcessor *) const; + void execute(const Glib::ustring &, const RowProcessor *) const; void loadComplete(const CommonObjects *); - void setFilter(const Glib::ustring &); - unsigned int columnCount() const; - const Glib::ustring & getColumnName(unsigned int) const; - VariableType getCurrentValue(const Glib::ustring &) const; - VariableType getCurrentValue(unsigned int) const; - bool isNull(unsigned int ) const; - bool isNull(const Glib::ustring & ) const; - RowAttribute resolveAttr(const Glib::ustring & attrName) const; private: typedef std::set<int> SeenServices; @@ -30,9 +22,19 @@ class ServiceRows : public RowSet, DvbSiReaderHelper { void filterInput(int fd) const; bool parseInfoTable(const u_char *data, size_t len, const RowProcessor *) const; - void parseServiceDescriptor(const u_char *data, size_t len) const; - void parseServiceAuthDescriptor(const u_char *data, size_t len) const; + void parseServiceDescriptor(const u_char *data, size_t len, Service * current) const; + void parseServiceAuthDescriptor(const u_char *data, size_t len, Service * current) const; +}; + +class ServiceRowState : public RowState { + public: + ServiceRowState(); + const Columns & getColumns() const; + RowAttribute resolveAttr(const Glib::ustring & attrName) const; + private: + Columns columns; + friend class ServiceRows; mutable Service * current; }; |