diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2017-08-03 00:34:53 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2017-08-03 00:34:53 +0100 |
commit | 9601afa4595961b441dc4cd7d3275b9255e9c443 (patch) | |
tree | 1f6a37dd73543ed49c11a029ebd9f7d8618c11fc /p2pvr/dvb/siParsers/table.impl.h | |
parent | Provide more comprehensive video stats, not just size (diff) | |
download | p2pvr-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.h | 121 |
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); + } + } + } +} + |