summaryrefslogtreecommitdiff
path: root/p2pvr/dvb/siParsers/table.impl.h
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2017-08-03 00:34:53 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2017-08-03 00:34:53 +0100
commit9601afa4595961b441dc4cd7d3275b9255e9c443 (patch)
tree1f6a37dd73543ed49c11a029ebd9f7d8618c11fc /p2pvr/dvb/siParsers/table.impl.h
parentProvide more comprehensive video stats, not just size (diff)
downloadp2pvr-9601afa4595961b441dc4cd7d3275b9255e9c443.tar.bz2
p2pvr-9601afa4595961b441dc4cd7d3275b9255e9c443.tar.xz
p2pvr-9601afa4595961b441dc4cd7d3275b9255e9c443.zip
Internalise the core of SI table parsers into the DVB lib
Diffstat (limited to 'p2pvr/dvb/siParsers/table.impl.h')
-rw-r--r--p2pvr/dvb/siParsers/table.impl.h121
1 files changed, 121 insertions, 0 deletions
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 <class TableType, class TargetType, class Key>
+ bool
+ SiTableParser<TableType, TargetType, Key>::ParseInfoTable(const u_char * data, size_t len)
+ {
+ const u_char * dataEnd = data + len;
+ while (data < dataEnd) {
+ auto siTable = reinterpret_cast<const TableType *>(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<std::mutex> 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 <class TableType, class TargetType, class Key>
+ void
+ SiTableParser<TableType, TargetType, Key>::ParseDescriptor(const SiDescriptorHeader * descriptor)
+ {
+ (void)descriptor;
+ // Logger()->messagef(LOG_DEBUG, "Dropped descriptor with tag 0x%02x", descriptor->tag);
+ return;
+ }
+
+ template <class TableType, class TargetType, class Key>
+ template <typename ... OtherParsers>
+ void
+ SiTableParser<TableType, TargetType, Key>::ParseDescriptor(const SiDescriptorHeader * descriptor, u_char tag, const boost::function<void(const u_char *, size_t)> & parser, const OtherParsers & ... otherParsers)
+ {
+ if (tag == descriptor->tag) {
+ parser(descriptor->data, descriptor->length);
+ }
+ else {
+ ParseDescriptor(descriptor, otherParsers...);
+ }
+ }
+
+ template <class TableType, class TargetType, class Key>
+ template <typename NextData, typename ... Parsers>
+ const NextData *
+ SiTableParser<TableType, TargetType, Key>::ParseDescriptors(const u_char * data, size_t len, const Parsers & ... parsers)
+ {
+ auto end = data + len;
+ while (data < end) {
+ auto descriptor = reinterpret_cast<const SiDescriptorHeader *>(data);
+ ParseDescriptor(descriptor, parsers...);
+ data += descriptor->length + 2;
+ }
+ return reinterpret_cast<const NextData *>(end);
+ }
+
+ template <class TableType, class TargetType, class Key>
+ template<typename LoopContent>
+ void
+ SiTableParser<TableType, TargetType, Key>::LoopOver(const u_char * data, size_t len, const boost::function<void(const LoopContent *)> & parser)
+ {
+ auto end = data + len;
+ while (data < end) {
+ auto loopData = reinterpret_cast<const LoopContent *>(data);
+ parser(loopData);
+ data += HILO(loopData->descriptors_length) + (loopData->data - data);
+ }
+ }
+
+ template <class TableType, class TargetType, class Key>
+ template<typename LoopContent>
+ void
+ SiTableParser<TableType, TargetType, Key>::LoopOverSection(const u_char * data, size_t len, const boost::function<void(const LoopContent *)> & parser)
+ {
+ auto end = data + len;
+ while (data < end) {
+ auto loopData = reinterpret_cast<const LoopContent *>(data);
+ parser(loopData);
+ data += sizeof(LoopContent);
+ }
+ }
+ }
+}
+