From 9601afa4595961b441dc4cd7d3275b9255e9c443 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 3 Aug 2017 00:34:53 +0100 Subject: Internalise the core of SI table parsers into the DVB lib --- p2pvr/dvb/siParsers/event.cpp | 2 + p2pvr/dvb/siParsers/network.cpp | 2 + p2pvr/dvb/siParsers/programAssociation.cpp | 2 + p2pvr/dvb/siParsers/programMap.cpp | 2 + p2pvr/dvb/siParsers/service.cpp | 2 + p2pvr/dvb/siParsers/table.cpp | 6 ++ p2pvr/dvb/siParsers/table.h | 112 +++----------------------- p2pvr/dvb/siParsers/table.impl.h | 121 +++++++++++++++++++++++++++++ 8 files changed, 148 insertions(+), 101 deletions(-) create mode 100644 p2pvr/dvb/siParsers/table.impl.h diff --git a/p2pvr/dvb/siParsers/event.cpp b/p2pvr/dvb/siParsers/event.cpp index 6e290c0..435fee1 100644 --- a/p2pvr/dvb/siParsers/event.cpp +++ b/p2pvr/dvb/siParsers/event.cpp @@ -1,4 +1,5 @@ #include +#include "table.impl.h" #include #include #include @@ -263,6 +264,7 @@ SiEpgParser::ParseSiTable(const EventInformation * eit, ::DVBSI::EitInformationP HandleTable(e); }); } +template bool DLL_PUBLIC SiTableParser::ParseInfoTable(const u_char * data, size_t len); } } diff --git a/p2pvr/dvb/siParsers/network.cpp b/p2pvr/dvb/siParsers/network.cpp index cca7e9f..56b4396 100644 --- a/p2pvr/dvb/siParsers/network.cpp +++ b/p2pvr/dvb/siParsers/network.cpp @@ -1,4 +1,5 @@ #include "network.h" +#include "table.impl.h" #include #include #include @@ -297,6 +298,7 @@ SiNetworkInformationParser::parseDescriptor_ServiceList(::DVBSI::NetworkTranspor data += sizeof(ServiceListDescriptor); } } +template bool DLL_PUBLIC SiTableParser::ParseInfoTable(const u_char * data, size_t len); } } diff --git a/p2pvr/dvb/siParsers/programAssociation.cpp b/p2pvr/dvb/siParsers/programAssociation.cpp index c3faf3a..709dba6 100644 --- a/p2pvr/dvb/siParsers/programAssociation.cpp +++ b/p2pvr/dvb/siParsers/programAssociation.cpp @@ -1,4 +1,5 @@ #include "programAssociation.h" +#include "table.impl.h" namespace P2PVR { namespace DVBSI { @@ -27,6 +28,7 @@ SiProgramAssociationParser::ParseSiTable(const ProgramAssociationSection * pas, (*pam)[ntohs(sd->program_number)] = HILO(sd->pid); }); } +template bool DLL_PUBLIC SiTableParser::ParseInfoTable(const u_char * data, size_t len); } } diff --git a/p2pvr/dvb/siParsers/programMap.cpp b/p2pvr/dvb/siParsers/programMap.cpp index 90bb8cf..c2f9482 100644 --- a/p2pvr/dvb/siParsers/programMap.cpp +++ b/p2pvr/dvb/siParsers/programMap.cpp @@ -1,4 +1,5 @@ #include "programMap.h" +#include "table.impl.h" #include namespace P2PVR { @@ -46,6 +47,7 @@ SiProgramMapParser::ParseSiTable(const struct ProgramMap * pm, ::DVBSI::ProgramM pms = ParseDescriptors(pms->data, HILO(pms->ES_info_length)); } } +template bool DLL_PUBLIC SiTableParser::ParseInfoTable(const u_char * data, size_t len); } } diff --git a/p2pvr/dvb/siParsers/service.cpp b/p2pvr/dvb/siParsers/service.cpp index 6f4e27b..4334b1c 100644 --- a/p2pvr/dvb/siParsers/service.cpp +++ b/p2pvr/dvb/siParsers/service.cpp @@ -1,4 +1,5 @@ #include "service.h" +#include "table.impl.h" #include namespace P2PVR { @@ -68,6 +69,7 @@ SiServicesParser::parseDescriptor_DefaultAuthority(::DVBSI::ServicePtr s, const { s->DefaultAuthority = *convert((const char *)p, len); } +template bool DLL_PUBLIC SiTableParser::ParseInfoTable(const u_char * data, size_t len); } } diff --git a/p2pvr/dvb/siParsers/table.cpp b/p2pvr/dvb/siParsers/table.cpp index 40af5fb..4baa7a5 100644 --- a/p2pvr/dvb/siParsers/table.cpp +++ b/p2pvr/dvb/siParsers/table.cpp @@ -32,6 +32,12 @@ SiTableParserBase::CurrentRawData() const return *currentRawData; } +bool +SiTableParserBase::IsFinished() const +{ + return ((incomplete == 0) && (startTime < (time(NULL) - 10))); +} + SiTableParserBase::StrPtr SiTableParserBase::convert(const char * txt, size_t len) { diff --git a/p2pvr/dvb/siParsers/table.h b/p2pvr/dvb/siParsers/table.h index 821bf93..bbf84f6 100644 --- a/p2pvr/dvb/siParsers/table.h +++ b/p2pvr/dvb/siParsers/table.h @@ -34,6 +34,8 @@ class DLL_PUBLIC SiTableParserBase : public P2PVR::RawDataClient { bool NewData(const P2PVR::Data & bytes, const Ice::Current&); + virtual bool IsFinished() const; + static StrPtr convert(const char * txt, size_t len); static const std::string ISO10646; @@ -97,113 +99,21 @@ class SiTableParser : public SiTableParserBase { virtual uint8_t LastTableId(const TableType * t) { return t->header.tableid; } virtual uint8_t FirstTableId(const TableType * t) { return t->header.tableid; } - bool ParseInfoTable(const u_char * data, size_t len) - { - const u_char * dataEnd = data + len; - while (data < dataEnd) { - auto siTable = reinterpret_cast(data); - if (siTable->header.current_next_indicator == 1 // current only, please. - && CheckTableId(siTable->header.tableid)) { // only tables we're interested in, please. - std::lock_guard g(lock); - uint16_t contentId = ntohs(siTable->header.content_id); - ContentType & content = contents[contentId]; - uint8_t sectionNumber = siTable->header.section_number >> SectionNumberShift(); - TableTargetSections & targetTableSections = boost::get<1>(content); - TargetSections & targetSections = targetTableSections[siTable->header.tableid]; - boost::get<0>(targetSections) = siTable->header.last_section_number >> SectionNumberShift(); - Sections & seen = boost::get<1>(targetSections); - if (seen.find(sectionNumber) == seen.end()) { - auto & obj = boost::get<0>(content); - if (!obj) { - obj = TargetType(new typename TargetType::element_type()); - incomplete += 1; - } - ParseSiTable(siTable, obj); - seen.insert(sectionNumber); - bool complete = true; - for (int tid = FirstTableId(siTable); tid <= LastTableId(siTable); tid += 1) { - TableTargetSections::const_iterator tts = targetTableSections.find(tid); - if (tts == targetTableSections.end()) { - complete = false; - break; - } - if (boost::get<1>(tts->second).size() <= boost::get<0>(tts->second)) { - complete = false; - break; - } - } - if (complete) { - if (HandleTable(obj)) { - targetTableSections.clear(); - } - else { - obj = TargetType(); - } - incomplete -= 1; - } - } - } - data += HILO(siTable->header.section_length) + 4; - } - return IsFinished(); - } - - virtual bool IsFinished() const - { - return ((incomplete == 0) && (startTime < (time(NULL) - 10))); - } - - static void ParseDescriptor(const SiDescriptorHeader * descriptor) - { - (void)descriptor; - // Logger()->messagef(LOG_DEBUG, "Dropped descriptor with tag 0x%02x", descriptor->tag); - return; - } - - template - static void ParseDescriptor(const SiDescriptorHeader * descriptor, u_char tag, boost::function parser, OtherParers ... otherParers) - { - if (tag == descriptor->tag) { - parser(descriptor->data, descriptor->length); - } - else { - ParseDescriptor(descriptor, otherParers...); - } - } + bool ParseInfoTable(const u_char * data, size_t len); + + static void ParseDescriptor(const SiDescriptorHeader * descriptor); + + template + static void ParseDescriptor(const SiDescriptorHeader * descriptor, u_char tag, const boost::function & parser, const OtherParsers & ... otherParsers); template - static const NextData * ParseDescriptors(const u_char * data, size_t len, Parsers ... parsers) - { - auto end = data + len; - while (data < end) { - auto descriptor = reinterpret_cast(data); - ParseDescriptor(descriptor, parsers...); - data += descriptor->length + 2; - } - return reinterpret_cast(end); - } + static const NextData * ParseDescriptors(const u_char * data, size_t len, const Parsers & ... parsers); template - static void LoopOver(const u_char * data, size_t len, boost::function parser) - { - auto end = data + len; - while (data < end) { - auto loopData = reinterpret_cast(data); - parser(loopData); - data += HILO(loopData->descriptors_length) + (loopData->data - data); - } - } + static void LoopOver(const u_char * data, size_t len, const boost::function & parser); template - static void LoopOverSection(const u_char * data, size_t len, boost::function parser) - { - auto end = data + len; - while (data < end) { - auto loopData = reinterpret_cast(data); - parser(loopData); - data += sizeof(LoopContent); - } - } + static void LoopOverSection(const u_char * data, size_t len, const boost::function & parser); virtual bool CheckTableId(u_char tableId) const = 0; virtual void ParseSiTable(const TableType *, TargetType) = 0; diff --git a/p2pvr/dvb/siParsers/table.impl.h b/p2pvr/dvb/siParsers/table.impl.h new file mode 100644 index 0000000..c5fed98 --- /dev/null +++ b/p2pvr/dvb/siParsers/table.impl.h @@ -0,0 +1,121 @@ +#include "table.h" + +namespace P2PVR { + namespace DVBSI { + template + bool + SiTableParser::ParseInfoTable(const u_char * data, size_t len) + { + const u_char * dataEnd = data + len; + while (data < dataEnd) { + auto siTable = reinterpret_cast(data); + if (siTable->header.current_next_indicator == 1 // current only, please. + && CheckTableId(siTable->header.tableid)) { // only tables we're interested in, please. + std::lock_guard g(lock); + uint16_t contentId = ntohs(siTable->header.content_id); + ContentType & content = contents[contentId]; + uint8_t sectionNumber = siTable->header.section_number >> SectionNumberShift(); + TableTargetSections & targetTableSections = boost::get<1>(content); + TargetSections & targetSections = targetTableSections[siTable->header.tableid]; + boost::get<0>(targetSections) = siTable->header.last_section_number >> SectionNumberShift(); + Sections & seen = boost::get<1>(targetSections); + if (seen.find(sectionNumber) == seen.end()) { + auto & obj = boost::get<0>(content); + if (!obj) { + obj = TargetType(new typename TargetType::element_type()); + incomplete += 1; + } + ParseSiTable(siTable, obj); + seen.insert(sectionNumber); + bool complete = true; + for (int tid = FirstTableId(siTable); tid <= LastTableId(siTable); tid += 1) { + TableTargetSections::const_iterator tts = targetTableSections.find(tid); + if (tts == targetTableSections.end()) { + complete = false; + break; + } + if (boost::get<1>(tts->second).size() <= boost::get<0>(tts->second)) { + complete = false; + break; + } + } + if (complete) { + if (HandleTable(obj)) { + targetTableSections.clear(); + } + else { + obj = TargetType(); + } + incomplete -= 1; + } + } + } + data += HILO(siTable->header.section_length) + 4; + } + return IsFinished(); + } + + template + void + SiTableParser::ParseDescriptor(const SiDescriptorHeader * descriptor) + { + (void)descriptor; + // Logger()->messagef(LOG_DEBUG, "Dropped descriptor with tag 0x%02x", descriptor->tag); + return; + } + + template + template + void + SiTableParser::ParseDescriptor(const SiDescriptorHeader * descriptor, u_char tag, const boost::function & parser, const OtherParsers & ... otherParsers) + { + if (tag == descriptor->tag) { + parser(descriptor->data, descriptor->length); + } + else { + ParseDescriptor(descriptor, otherParsers...); + } + } + + template + template + const NextData * + SiTableParser::ParseDescriptors(const u_char * data, size_t len, const Parsers & ... parsers) + { + auto end = data + len; + while (data < end) { + auto descriptor = reinterpret_cast(data); + ParseDescriptor(descriptor, parsers...); + data += descriptor->length + 2; + } + return reinterpret_cast(end); + } + + template + template + void + SiTableParser::LoopOver(const u_char * data, size_t len, const boost::function & parser) + { + auto end = data + len; + while (data < end) { + auto loopData = reinterpret_cast(data); + parser(loopData); + data += HILO(loopData->descriptors_length) + (loopData->data - data); + } + } + + template + template + void + SiTableParser::LoopOverSection(const u_char * data, size_t len, const boost::function & parser) + { + auto end = data + len; + while (data < end) { + auto loopData = reinterpret_cast(data); + parser(loopData); + data += sizeof(LoopContent); + } + } + } +} + -- cgit v1.2.3