mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-27 23:42:58 +02:00
eitd: Reduce sectionsd memory requirements:
* Various EPG related strings (language- and country keys, audio descriptions) come with a pretty low variance. Cache them, and use an index instead of allocating redundant strings for each and every SIevent. * Storing content classifications in native format instead of std::string removes quite some memory overhead, too. This saves about 250 bytes of RAM for every event cached, resulting in a considerably reduced sectionsd memory footprint. Conflicts: src/eitd/xmlutil.cpp
This commit is contained in:
@@ -30,6 +30,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <dvbsi++/descriptor_tag.h>
|
#include <dvbsi++/descriptor_tag.h>
|
||||||
#include <dvbsi++/short_event_descriptor.h>
|
#include <dvbsi++/short_event_descriptor.h>
|
||||||
#include <dvbsi++/extended_event_descriptor.h>
|
#include <dvbsi++/extended_event_descriptor.h>
|
||||||
@@ -42,7 +44,9 @@
|
|||||||
#include "SIutils.hpp"
|
#include "SIutils.hpp"
|
||||||
#include "SIevents.hpp"
|
#include "SIevents.hpp"
|
||||||
|
|
||||||
const std::string languangeOFF = "OFF";
|
#include <OpenThreads/Thread>
|
||||||
|
#include <OpenThreads/Condition>
|
||||||
|
#include <OpenThreads/ScopedLock>
|
||||||
|
|
||||||
struct descr_generic_header {
|
struct descr_generic_header {
|
||||||
unsigned descriptor_tag : 8;
|
unsigned descriptor_tag : 8;
|
||||||
@@ -74,6 +78,71 @@ inline unsigned min(unsigned a, unsigned b)
|
|||||||
return b < a ? b : a;
|
return b < a ? b : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static OpenThreads::Mutex countryMutex;
|
||||||
|
static std::vector<std::string> countryVector;
|
||||||
|
|
||||||
|
unsigned int getCountryIndex(const std::string &country)
|
||||||
|
{
|
||||||
|
unsigned int ix = 0;
|
||||||
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(countryMutex);
|
||||||
|
if (!countryVector.size()) {
|
||||||
|
countryVector.push_back("DEU"); // 0
|
||||||
|
countryVector.push_back("FRA"); // 1
|
||||||
|
countryVector.push_back("ITA"); // 2
|
||||||
|
countryVector.push_back("ESP"); // 3
|
||||||
|
}
|
||||||
|
for (std::vector<std::string>::iterator it = countryVector.begin(); it != countryVector.end(); ++it, ++ix)
|
||||||
|
if (*it == country)
|
||||||
|
return ix;
|
||||||
|
countryVector.push_back(country);
|
||||||
|
return ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OpenThreads::Mutex componentMutex;
|
||||||
|
static std::vector<std::string> componentVector;
|
||||||
|
static std::map<std::string,unsigned int> componentMap;
|
||||||
|
|
||||||
|
void SIcomponent::setComponent(const std::string &component_description)
|
||||||
|
{
|
||||||
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(componentMutex);
|
||||||
|
if (!componentVector.size()) {
|
||||||
|
componentMap[""] = 0;
|
||||||
|
componentVector.push_back("");
|
||||||
|
}
|
||||||
|
std::map<std::string,unsigned int>::const_iterator it = componentMap.find(component_description);
|
||||||
|
if (it == componentMap.end()) {
|
||||||
|
component = componentVector.size();
|
||||||
|
componentMap[component_description] = component;
|
||||||
|
componentVector.push_back(component_description);
|
||||||
|
} else
|
||||||
|
component = it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SIcomponent::getComponentName() const
|
||||||
|
{
|
||||||
|
if (component < componentVector.size())
|
||||||
|
return componentVector[component].c_str();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
SIparentalRating::SIparentalRating(const std::string &cc, unsigned char rate)
|
||||||
|
{
|
||||||
|
rating=rate;
|
||||||
|
countryCode=getCountryIndex(cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SIparentalRating::dump(void) const
|
||||||
|
{
|
||||||
|
printf("Rating: %s %hhu (+3)\n", countryVector[countryCode].c_str(), rating);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SIparentalRating::saveXML(FILE *file) const
|
||||||
|
{
|
||||||
|
if(fprintf(file, "\t\t\t<parental_rating country=\"%s\" rating=\"%hhu\"/>\n", countryVector[countryCode].c_str(), rating)<0)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
SIevent::SIevent(const t_original_network_id _original_network_id, const t_transport_stream_id _transport_stream_id, const t_service_id _service_id,
|
SIevent::SIevent(const t_original_network_id _original_network_id, const t_transport_stream_id _transport_stream_id, const t_service_id _service_id,
|
||||||
const unsigned short _event_id)
|
const unsigned short _event_id)
|
||||||
{
|
{
|
||||||
@@ -131,16 +200,20 @@ void SIevent::parse(Event &event)
|
|||||||
times.insert(SItime(start_time, duration));
|
times.insert(SItime(start_time, duration));
|
||||||
const DescriptorList &dlist = *event.getDescriptors();
|
const DescriptorList &dlist = *event.getDescriptors();
|
||||||
for (DescriptorConstIterator dit = dlist.begin(); dit != dlist.end(); ++dit) {
|
for (DescriptorConstIterator dit = dlist.begin(); dit != dlist.end(); ++dit) {
|
||||||
uint8_t dtype = (*dit)->getTag();
|
switch ((*dit)->getTag()) {
|
||||||
if(dtype == SHORT_EVENT_DESCRIPTOR) {
|
case SHORT_EVENT_DESCRIPTOR:
|
||||||
|
{
|
||||||
const ShortEventDescriptor *d = (ShortEventDescriptor*) *dit;
|
const ShortEventDescriptor *d = (ShortEventDescriptor*) *dit;
|
||||||
std::string lang = d->getIso639LanguageCode();
|
std::string lang = d->getIso639LanguageCode();
|
||||||
std::transform(lang.begin(), lang.end(), lang.begin(), tolower);
|
std::transform(lang.begin(), lang.end(), lang.begin(), tolower);
|
||||||
int table = getCountryCodeDefaultMapping(lang);
|
int table = getCountryCodeDefaultMapping(lang);
|
||||||
setName(lang, stringDVBUTF8(d->getEventName(), table, tsidonid));
|
unsigned int _lang = getLangIndex(lang);
|
||||||
setText(lang, stringDVBUTF8(d->getText(), table, tsidonid));
|
setName(_lang, stringDVBUTF8(d->getEventName(), table, tsidonid));
|
||||||
|
setText(_lang, stringDVBUTF8(d->getText(), table, tsidonid));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if(dtype == EXTENDED_EVENT_DESCRIPTOR) {
|
case EXTENDED_EVENT_DESCRIPTOR:
|
||||||
|
{
|
||||||
const ExtendedEventDescriptor *d = (ExtendedEventDescriptor*) *dit;
|
const ExtendedEventDescriptor *d = (ExtendedEventDescriptor*) *dit;
|
||||||
std::string lang = d->getIso639LanguageCode();
|
std::string lang = d->getIso639LanguageCode();
|
||||||
std::transform(lang.begin(), lang.end(), lang.begin(), tolower);
|
std::transform(lang.begin(), lang.end(), lang.begin(), tolower);
|
||||||
@@ -154,20 +227,22 @@ void SIevent::parse(Event &event)
|
|||||||
item.append("\n");
|
item.append("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
appendExtendedText(lang, stringDVBUTF8(d->getText(), table, tsidonid));
|
appendExtendedText(getLangIndex(lang), stringDVBUTF8(d->getText(), table, tsidonid));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if(dtype == CONTENT_DESCRIPTOR) {
|
case CONTENT_DESCRIPTOR:
|
||||||
|
{
|
||||||
const ContentDescriptor * d = (ContentDescriptor *) *dit;
|
const ContentDescriptor * d = (ContentDescriptor *) *dit;
|
||||||
const ContentClassificationList *clist = d->getClassifications();
|
const ContentClassificationList *clist = d->getClassifications();
|
||||||
for (ContentClassificationConstIterator cit = clist->begin(); cit != clist->end(); ++cit) {
|
ssize_t off = classifications.reserve(clist->size() * 2);
|
||||||
ContentClassification * c = *cit;
|
for (ContentClassificationConstIterator cit = clist->begin(); cit != clist->end(); ++cit)
|
||||||
char content = c->getContentNibbleLevel1() << 4 | c->getContentNibbleLevel2();
|
off = classifications.set(off,
|
||||||
contentClassification += content;
|
(*cit)->getContentNibbleLevel1() << 4 | (*cit)->getContentNibbleLevel2(),
|
||||||
char user = c->getUserNibble1() << 4 | c->getUserNibble2();
|
(*cit)->getUserNibble1() << 4 | (*cit)->getUserNibble2());
|
||||||
userClassification += user;
|
break;
|
||||||
}
|
}
|
||||||
}
|
case COMPONENT_DESCRIPTOR:
|
||||||
else if(dtype == COMPONENT_DESCRIPTOR) {
|
{
|
||||||
const ComponentDescriptor *d = (ComponentDescriptor*)*dit;
|
const ComponentDescriptor *d = (ComponentDescriptor*)*dit;
|
||||||
SIcomponent c;
|
SIcomponent c;
|
||||||
c.streamContent = d->getStreamContent();
|
c.streamContent = d->getStreamContent();
|
||||||
@@ -176,11 +251,13 @@ void SIevent::parse(Event &event)
|
|||||||
std::string lang = d->getIso639LanguageCode();
|
std::string lang = d->getIso639LanguageCode();
|
||||||
std::transform(lang.begin(), lang.end(), lang.begin(), tolower);
|
std::transform(lang.begin(), lang.end(), lang.begin(), tolower);
|
||||||
int table = getCountryCodeDefaultMapping(lang);
|
int table = getCountryCodeDefaultMapping(lang);
|
||||||
c.component = stringDVBUTF8(d->getText(), table, tsidonid);
|
c.setComponent(stringDVBUTF8(d->getText(), table, tsidonid));
|
||||||
//components.insert(c);
|
//components.insert(c);
|
||||||
components.push_back(c);
|
components.push_back(c);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if(dtype == PARENTAL_RATING_DESCRIPTOR) {
|
case PARENTAL_RATING_DESCRIPTOR:
|
||||||
|
{
|
||||||
const ParentalRatingDescriptor *d = (ParentalRatingDescriptor*) *dit;
|
const ParentalRatingDescriptor *d = (ParentalRatingDescriptor*) *dit;
|
||||||
const ParentalRatingList *plist = d->getParentalRatings();
|
const ParentalRatingList *plist = d->getParentalRatings();
|
||||||
for (ParentalRatingConstIterator it = plist->begin(); it != plist->end(); ++it) {
|
for (ParentalRatingConstIterator it = plist->begin(); it != plist->end(); ++it) {
|
||||||
@@ -188,8 +265,10 @@ void SIevent::parse(Event &event)
|
|||||||
//ratings.insert(p);
|
//ratings.insert(p);
|
||||||
ratings.push_back(p);
|
ratings.push_back(p);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if(dtype == LINKAGE_DESCRIPTOR) {
|
case LINKAGE_DESCRIPTOR:
|
||||||
|
{
|
||||||
const LinkageDescriptor * d = (LinkageDescriptor *) *dit;
|
const LinkageDescriptor * d = (LinkageDescriptor *) *dit;
|
||||||
SIlinkage l;
|
SIlinkage l;
|
||||||
l.linkageType = d->getLinkageType();
|
l.linkageType = d->getLinkageType();
|
||||||
@@ -199,11 +278,16 @@ void SIevent::parse(Event &event)
|
|||||||
const PrivateDataByteVector *privateData = d->getPrivateDataBytes();
|
const PrivateDataByteVector *privateData = d->getPrivateDataBytes();
|
||||||
l.name = convertDVBUTF8((const char*)&((*privateData)[0]), privateData->size(), 1, tsidonid);
|
l.name = convertDVBUTF8((const char*)&((*privateData)[0]), privateData->size(), 1, tsidonid);
|
||||||
linkage_descs.insert(linkage_descs.end(), l);
|
linkage_descs.insert(linkage_descs.end(), l);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#if 0 // TODO ? vps was never used
|
#if 0 // TODO ? vps was never used
|
||||||
else if(dtype == PDC_DESCRIPTOR) {
|
case PDC_DESCRIPTOR) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,15 +341,16 @@ void SIevent::parseShortEventDescriptor(const uint8_t *buf, unsigned maxlen)
|
|||||||
|
|
||||||
std::string language(lang);
|
std::string language(lang);
|
||||||
int table = getCountryCodeDefaultMapping(language);
|
int table = getCountryCodeDefaultMapping(language);
|
||||||
|
unsigned int _language = getLangIndex(language);
|
||||||
|
|
||||||
buf+=sizeof(struct descr_short_event_header);
|
buf+=sizeof(struct descr_short_event_header);
|
||||||
if(evt->event_name_length)
|
if(evt->event_name_length)
|
||||||
setName(language, convertDVBUTF8((const char*) buf, evt->event_name_length, table, tsidonid));
|
setName(_language, convertDVBUTF8((const char*) buf, evt->event_name_length, table, tsidonid));
|
||||||
|
|
||||||
buf+=evt->event_name_length;
|
buf+=evt->event_name_length;
|
||||||
unsigned char textlength=*((unsigned char *)buf);
|
unsigned char textlength=*((unsigned char *)buf);
|
||||||
if(textlength > 2)
|
if(textlength > 2)
|
||||||
setText(language, convertDVBUTF8((const char*) (++buf), textlength, table, tsidonid));
|
setText(_language, convertDVBUTF8((const char*) (++buf), textlength, table, tsidonid));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIevent::parseExtendedEventDescriptor(const uint8_t *buf, unsigned maxlen)
|
void SIevent::parseExtendedEventDescriptor(const uint8_t *buf, unsigned maxlen)
|
||||||
@@ -284,6 +369,7 @@ void SIevent::parseExtendedEventDescriptor(const uint8_t *buf, unsigned maxlen)
|
|||||||
|
|
||||||
std::string language(lang);
|
std::string language(lang);
|
||||||
int table = getCountryCodeDefaultMapping(language);
|
int table = getCountryCodeDefaultMapping(language);
|
||||||
|
unsigned int _language = getLangIndex(language);
|
||||||
|
|
||||||
unsigned char *items=(unsigned char *)(buf+sizeof(struct descr_extended_event_header));
|
unsigned char *items=(unsigned char *)(buf+sizeof(struct descr_extended_event_header));
|
||||||
while(items < (unsigned char *)(buf + sizeof(struct descr_extended_event_header) + evt->length_of_items)) {
|
while(items < (unsigned char *)(buf + sizeof(struct descr_extended_event_header) + evt->length_of_items)) {
|
||||||
@@ -303,7 +389,7 @@ void SIevent::parseExtendedEventDescriptor(const uint8_t *buf, unsigned maxlen)
|
|||||||
items+=1+*items;
|
items+=1+*items;
|
||||||
}
|
}
|
||||||
if(*items)
|
if(*items)
|
||||||
appendExtendedText(language, convertDVBUTF8((const char *)(items+1), min(maxlen-(items+1-buf), (*items)), table, tsidonid));
|
appendExtendedText(_language, convertDVBUTF8((const char *)(items+1), min(maxlen-(items+1-buf), (*items)), table, tsidonid));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIevent::parseContentDescriptor(const uint8_t *buf, unsigned maxlen)
|
void SIevent::parseContentDescriptor(const uint8_t *buf, unsigned maxlen)
|
||||||
@@ -311,13 +397,8 @@ void SIevent::parseContentDescriptor(const uint8_t *buf, unsigned maxlen)
|
|||||||
struct descr_generic_header *cont=(struct descr_generic_header *)buf;
|
struct descr_generic_header *cont=(struct descr_generic_header *)buf;
|
||||||
if(cont->descriptor_length+sizeof(struct descr_generic_header)>maxlen)
|
if(cont->descriptor_length+sizeof(struct descr_generic_header)>maxlen)
|
||||||
return;
|
return;
|
||||||
|
ssize_t off = classifications.reserve(cont->descriptor_length);
|
||||||
const uint8_t *classification=buf+sizeof(struct descr_generic_header);
|
classifications.set(off, buf + sizeof(struct descr_generic_header), cont->descriptor_length);
|
||||||
while(classification <= buf+sizeof(struct descr_generic_header)+cont->descriptor_length-2) {
|
|
||||||
contentClassification+=std::string((const char *)classification, 1);
|
|
||||||
userClassification+=std::string((const char *)classification+1, 1);
|
|
||||||
classification+=2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIevent::parseComponentDescriptor(const uint8_t *buf, unsigned maxlen)
|
void SIevent::parseComponentDescriptor(const uint8_t *buf, unsigned maxlen)
|
||||||
@@ -339,6 +420,7 @@ void SIevent::parseParentalRatingDescriptor(const uint8_t *buf, unsigned maxlen)
|
|||||||
s+=4;
|
s+=4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIevent::parseLinkageDescriptor(const uint8_t *buf, unsigned maxlen)
|
void SIevent::parseLinkageDescriptor(const uint8_t *buf, unsigned maxlen)
|
||||||
{
|
{
|
||||||
if(maxlen>=sizeof(struct descr_linkage_header)) {
|
if(maxlen>=sizeof(struct descr_linkage_header)) {
|
||||||
@@ -351,34 +433,30 @@ char SIevent::getFSK() const
|
|||||||
{
|
{
|
||||||
for (SIparentalRatings::const_iterator it = ratings.begin(); it != ratings.end(); ++it)
|
for (SIparentalRatings::const_iterator it = ratings.begin(); it != ratings.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->countryCode == "DEU")
|
if (it->countryCode == 0 /*"DEU"*/) {
|
||||||
{
|
|
||||||
if ((it->rating >= 0x01) && (it->rating <= 0x0F))
|
if ((it->rating >= 0x01) && (it->rating <= 0x0F))
|
||||||
return (it->rating + 3); // 0x01 to 0x0F minimum age = rating + 3 years
|
return (it->rating + 3); // 0x01 to 0x0F minimum age = rating + 3 years
|
||||||
else
|
|
||||||
return (it->rating == 0 ? 0 : 18); // return FSK 18 for : 0x10 to 0xFF defined by the broadcaster
|
return (it->rating == 0 ? 0 : 18); // return FSK 18 for : 0x10 to 0xFF defined by the broadcaster
|
||||||
}else if( it->countryCode == "FRA" && it->rating == 0x10)// workaround for ITA ESP FRA fsk.
|
}
|
||||||
{
|
if( it->countryCode == 1 /*"FRA"*/ && it->rating == 0x10) {
|
||||||
|
// workaround for ITA ESP FRA fsk.
|
||||||
return 0;
|
return 0;
|
||||||
}else if(it->countryCode == "ITA" && it->rating == 1)
|
}
|
||||||
{
|
if(it->countryCode == 2 /*"ITA"*/ && it->rating == 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}else if( it->countryCode == "ESP" )
|
}
|
||||||
{
|
if( it->countryCode == 3 /*"ESP"*/ ) {
|
||||||
if(it->rating == 0x10 || it->rating == 0x11)
|
if(it->rating == 0x10 || it->rating == 0x11)
|
||||||
return 0;
|
return 0;
|
||||||
else if(it->rating == 0x12)
|
if(it->rating == 0x12)
|
||||||
return 18;
|
return 18;
|
||||||
else
|
|
||||||
return (it->rating + 1);
|
return (it->rating + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!ratings.empty())
|
if (!ratings.empty())
|
||||||
{
|
{
|
||||||
if ((ratings.begin()->rating >= 0x01) && (ratings.begin()->rating <= 0x0F))
|
if ((ratings.begin()->rating >= 0x01) && (ratings.begin()->rating <= 0x0F))
|
||||||
return (ratings.begin()->rating + 3);
|
return (ratings.begin()->rating + 3);
|
||||||
else
|
|
||||||
return (ratings.begin()->rating == 0 ? 0 : 18);
|
return (ratings.begin()->rating == 0 ? 0 : 18);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,81 +466,110 @@ char SIevent::getFSK() const
|
|||||||
std::string SIevent::getName() const
|
std::string SIevent::getName() const
|
||||||
{
|
{
|
||||||
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
||||||
std::map<std::string, std::string>::const_iterator it = langName.begin() ;
|
if (langData.size())
|
||||||
if (it != langName.end()) return it->second;
|
return langData.begin()->text[SILangData::langName];
|
||||||
else return("");
|
return "";
|
||||||
} else {
|
} else {
|
||||||
std::string retval;
|
std::string retval;
|
||||||
SIlanguage::filter(langName, 1, retval);
|
SIlanguage::filter(langData, SILangData::langName, 1, retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIevent::setName(const std::string &lang, const std::string &name)
|
void SIevent::setName(const std::string &lang, const std::string &name)
|
||||||
|
{
|
||||||
|
setName(getLangIndex(lang), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SIevent::setName(unsigned int lang, const std::string &name)
|
||||||
{
|
{
|
||||||
std::string tmp = name;
|
std::string tmp = name;
|
||||||
std::replace(tmp.begin(), tmp.end(), '\n', ' ');
|
std::replace(tmp.begin(), tmp.end(), '\n', ' ');
|
||||||
//printf("setName: lang %s text %s\n", lang.c_str(), name.c_str());
|
|
||||||
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode())
|
||||||
langName[languangeOFF] = tmp; //name;
|
lang = 0;
|
||||||
} else {
|
|
||||||
langName[lang] = tmp; //name;
|
for (std::list<SILangData>::iterator it = langData.begin(); it != langData.end(); ++it)
|
||||||
|
if (it->lang == lang) {
|
||||||
|
it->text[SILangData::langName] = tmp;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SILangData ld;
|
||||||
|
ld.lang = lang;
|
||||||
|
ld.text[SILangData::langName] = tmp;
|
||||||
|
langData.push_back(ld);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SIevent::getText() const
|
std::string SIevent::getText() const
|
||||||
{
|
{
|
||||||
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
||||||
std::map<std::string, std::string>::const_iterator it = langText.begin() ;
|
if (langData.size())
|
||||||
if (it != langText.end()) return it->second;
|
return langData.begin()->text[SILangData::langText];
|
||||||
else return("");
|
return "";
|
||||||
} else {
|
|
||||||
std::string retval;
|
|
||||||
SIlanguage::filter(langText, 0, retval);
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
std::string retval;
|
||||||
|
SIlanguage::filter(langData, SILangData::langText, 0, retval);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIevent::setText(const std::string &lang, const std::string &text)
|
void SIevent::setText(const std::string &lang, const std::string &text)
|
||||||
{
|
{
|
||||||
//printf("setText: lang %s text %s\n", lang.c_str(), text.c_str());
|
setText(getLangIndex(lang), text);
|
||||||
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
|
||||||
langText[languangeOFF] = text;
|
|
||||||
} else {
|
|
||||||
langText[lang] = text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SIevent::setText(unsigned int lang, const std::string &text)
|
||||||
|
{
|
||||||
|
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode())
|
||||||
|
lang = 0;
|
||||||
|
|
||||||
|
for (std::list<SILangData>::iterator it = langData.begin(); it != langData.end(); ++it)
|
||||||
|
if (it->lang == lang) {
|
||||||
|
it->text[SILangData::langText] = text;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SILangData ld;
|
||||||
|
ld.lang = lang;
|
||||||
|
ld.text[SILangData::langText] = text;
|
||||||
|
langData.push_back(ld);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SIevent::getExtendedText() const
|
std::string SIevent::getExtendedText() const
|
||||||
{
|
{
|
||||||
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
||||||
std::map<std::string, std::string>::const_iterator it = langExtendedText.begin() ;
|
if (langData.size())
|
||||||
if (it != langExtendedText.end()) return it->second;
|
return langData.begin()->text[SILangData::langExtendedText];
|
||||||
else return("");
|
return "";
|
||||||
} else {
|
}
|
||||||
std::string retval;
|
std::string retval;
|
||||||
SIlanguage::filter(langExtendedText, 0, retval);
|
SIlanguage::filter(langData, SILangData::langExtendedText, 0, retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SIevent::appendExtendedText(const std::string &lang, const std::string &text, bool append)
|
||||||
|
{
|
||||||
|
appendExtendedText(getLangIndex(lang), text, append);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIevent::appendExtendedText(const std::string &lang, const std::string &text)
|
void SIevent::appendExtendedText(unsigned int lang, const std::string &text, bool append)
|
||||||
{
|
{
|
||||||
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode())
|
||||||
langExtendedText[languangeOFF] += text;
|
lang = 0;
|
||||||
} else {
|
|
||||||
langExtendedText[lang] += text;
|
for (std::list<SILangData>::iterator it = langData.begin(); it != langData.end(); ++it)
|
||||||
}
|
if (it->lang == lang) {
|
||||||
|
if (append)
|
||||||
|
it->text[SILangData::langExtendedText] += text;
|
||||||
|
else
|
||||||
|
it->text[SILangData::langExtendedText] = text;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIevent::setExtendedText(const std::string &lang, const std::string &text)
|
SILangData ld;
|
||||||
{
|
ld.lang = lang;
|
||||||
//printf("setExtendedText: lang %s text %s\n", lang.c_str(), text.c_str());
|
ld.text[SILangData::langExtendedText] = text;
|
||||||
if (CSectionsdClient::LANGUAGE_MODE_OFF == SIlanguage::getMode()) {
|
langData.push_back(ld);
|
||||||
langExtendedText[languangeOFF] = text;
|
|
||||||
} else {
|
|
||||||
langExtendedText[lang] = text;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SIevent::saveXML(FILE *file, const char *serviceName) const
|
int SIevent::saveXML(FILE *file, const char *serviceName) const
|
||||||
@@ -488,23 +595,17 @@ int SIevent::saveXML0(FILE *file) const
|
|||||||
|
|
||||||
int SIevent::saveXML2(FILE *file) const
|
int SIevent::saveXML2(FILE *file) const
|
||||||
{
|
{
|
||||||
for (std::map<std::string, std::string>::const_iterator
|
for (std::list<SILangData>::const_iterator i = langData.begin(); i != langData.end(); ++i) {
|
||||||
i = langName.begin() ;
|
if (i->text[SILangData::langName].length()) {
|
||||||
i != langName.end() ;
|
fprintf(file, "\t\t\t<name lang=\"%s\" string=\"", langIndex[i->lang].c_str());
|
||||||
++i) {
|
saveStringToXMLfile(file, i->text[SILangData::langName].c_str());
|
||||||
if (i->second.length()) {
|
|
||||||
fprintf(file, "\t\t\t<name lang=\"%s\" string=\"", i->first.c_str());
|
|
||||||
saveStringToXMLfile(file, i->second.c_str());
|
|
||||||
fprintf(file, "\"/>\n");
|
fprintf(file, "\"/>\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (std::map<std::string, std::string>::const_iterator
|
for (std::list<SILangData>::const_iterator i = langData.begin(); i != langData.end(); ++i) {
|
||||||
i = langText.begin() ;
|
if (i->text[SILangData::langText].length()) {
|
||||||
i != langText.end() ;
|
fprintf(file, "\t\t\t<text lang=\"%s\" string=\"", langIndex[i->lang].c_str());
|
||||||
++i) {
|
saveStringToXMLfile(file, i->text[SILangData::langText].c_str());
|
||||||
if (i->second.length()) {
|
|
||||||
fprintf(file, "\t\t\t<text lang=\"%s\" string=\"", i->first.c_str());
|
|
||||||
saveStringToXMLfile(file, i->second.c_str());
|
|
||||||
fprintf(file, "\"/>\n");
|
fprintf(file, "\"/>\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -520,17 +621,16 @@ int SIevent::saveXML2(FILE *file) const
|
|||||||
fprintf(file, "\"/>\n");
|
fprintf(file, "\"/>\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (std::map<std::string, std::string>::const_iterator
|
for (std::list<SILangData>::const_iterator i = langData.begin(); i != langData.end(); ++i) {
|
||||||
i = langExtendedText.begin() ;
|
if (i->text[SILangData::langExtendedText].length()) {
|
||||||
i != langExtendedText.end() ;
|
fprintf(file, "\t\t\t<extended_text lang=\"%s\" string=\"", langIndex[i->lang].c_str());
|
||||||
++i) {
|
saveStringToXMLfile(file, i->text[SILangData::langExtendedText].c_str());
|
||||||
if (i->second.length()) {
|
|
||||||
fprintf(file, "\t\t\t<extended_text lang=\"%s\" string=\"", i->first.c_str());
|
|
||||||
saveStringToXMLfile(file, i->second.c_str());
|
|
||||||
fprintf(file, "\"/>\n");
|
fprintf(file, "\"/>\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for_each(times.begin(), times.end(), saveSItimeXML(file));
|
for_each(times.begin(), times.end(), saveSItimeXML(file));
|
||||||
|
std::string contentClassification, userClassification;
|
||||||
|
classifications.get(contentClassification, userClassification);
|
||||||
for(unsigned i=0; i<contentClassification.length(); i++) {
|
for(unsigned i=0; i<contentClassification.length(); i++) {
|
||||||
/* focus: i think no sense to save 'unknown' */
|
/* focus: i think no sense to save 'unknown' */
|
||||||
if(contentClassification[i] || userClassification[i])
|
if(contentClassification[i] || userClassification[i])
|
||||||
@@ -557,16 +657,14 @@ void SIevent::dump(void) const
|
|||||||
if(itemDescription.length())
|
if(itemDescription.length())
|
||||||
printf("Item-Description: %s\n", itemDescription.c_str());
|
printf("Item-Description: %s\n", itemDescription.c_str());
|
||||||
#endif
|
#endif
|
||||||
for (std::map<std::string, std::string>::const_iterator it = langName.begin() ;
|
for (std::list<SILangData>::const_iterator it = langData.begin(); it != langData.end(); ++it) {
|
||||||
it != langName.end() ; ++it)
|
printf("Name (%s): %s\n", langIndex[it->lang].c_str(), it->text[SILangData::langName].c_str());
|
||||||
printf("Name (%s): %s\n", it->first.c_str(), it->second.c_str());
|
printf("Text (%s): %s\n", langIndex[it->lang].c_str(), it->text[SILangData::langText].c_str());
|
||||||
for (std::map<std::string, std::string>::const_iterator it = langText.begin() ;
|
printf("Extended-Text (%s): %s\n", langIndex[it->lang].c_str(), it->text[SILangData::langExtendedText].c_str());
|
||||||
it != langText.end() ; ++it)
|
}
|
||||||
printf("Text (%s): %s\n", it->first.c_str(), it->second.c_str());
|
|
||||||
for (std::map<std::string, std::string>::const_iterator it = langExtendedText.begin() ;
|
|
||||||
it != langExtendedText.end() ; ++it)
|
|
||||||
printf("Extended-Text (%s): %s\n", it->first.c_str(), it->second.c_str());
|
|
||||||
|
|
||||||
|
std::string contentClassification, userClassification;
|
||||||
|
classifications.get(contentClassification, userClassification);
|
||||||
if(contentClassification.length()) {
|
if(contentClassification.length()) {
|
||||||
printf("Content classification:");
|
printf("Content classification:");
|
||||||
for(unsigned i=0; i<contentClassification.length(); i++)
|
for(unsigned i=0; i<contentClassification.length(); i++)
|
||||||
@@ -589,13 +687,13 @@ void SIevent::dump(void) const
|
|||||||
//never used
|
//never used
|
||||||
void SIevent::dumpSmall(void) const
|
void SIevent::dumpSmall(void) const
|
||||||
{
|
{
|
||||||
for (std::map<std::string, std::string>::const_iterator it = langName.begin() ;
|
for (std::list<std::pair<unsigned int, std::string> >::const_iterator it = langName.begin() ;
|
||||||
it != langName.end() ; ++it)
|
it != langName.end() ; ++it)
|
||||||
printf("Name (%s): %s\n", it->first.c_str(), it->second.c_str());
|
printf("Name (%s): %s\n", it->first.c_str(), it->second.c_str());
|
||||||
for (std::map<std::string, std::string>::const_iterator it = langText.begin() ;
|
for (std::list<std::pair<unsigned int, std::string> >::const_iterator it = langText.begin() ;
|
||||||
it != langText.end() ; ++it)
|
it != langText.end() ; ++it)
|
||||||
printf("Text (%s): %s\n", it->first.c_str(), it->second.c_str());
|
printf("Text (%s): %s\n", it->first.c_str(), it->second.c_str());
|
||||||
for (std::map<std::string, std::string>::const_iterator it = langExtendedText.begin() ;
|
for (std::list<std::pair<unsigned int, std::string> >::const_iterator it = langExtendedText.begin() ;
|
||||||
it != langExtendedText.end() ; ++it)
|
it != langExtendedText.end() ; ++it)
|
||||||
printf("Extended-Text (%s): %s\n", it->first.c_str(), it->second.c_str());
|
printf("Extended-Text (%s): %s\n", it->first.c_str(), it->second.c_str());
|
||||||
|
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
#define SIEVENTS_HPP
|
#define SIEVENTS_HPP
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <sectionsdclient/sectionsdtypes.h>
|
#include <sectionsdclient/sectionsdtypes.h>
|
||||||
#include <dvbsi++/event_information_section.h>
|
#include <dvbsi++/event_information_section.h>
|
||||||
#include "edvbstring.h"
|
#include "edvbstring.h"
|
||||||
|
#include "SIlanguage.hpp"
|
||||||
|
|
||||||
//#define USE_ITEM_DESCRIPTION
|
//#define USE_ITEM_DESCRIPTION
|
||||||
|
|
||||||
@@ -123,7 +124,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dump(void) const {
|
void dump(void) const {
|
||||||
printf("Linakge Type: 0x%02hhx\n", linkageType);
|
printf("Linkage Type: 0x%02hhx\n", linkageType);
|
||||||
if (name.length())
|
if (name.length())
|
||||||
printf("Name: %s\n", name.c_str());
|
printf("Name: %s\n", name.c_str());
|
||||||
printf("Transport Stream Id: 0x%04hhx\n", transportStreamId);
|
printf("Transport Stream Id: 0x%04hhx\n", transportStreamId);
|
||||||
@@ -177,35 +178,41 @@ struct saveSIlinkageXML : public std::unary_function<class SIlinkage, void>
|
|||||||
class SIcomponent
|
class SIcomponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string component;
|
unsigned int component;
|
||||||
unsigned char componentType;
|
unsigned char componentType;
|
||||||
unsigned char componentTag;
|
unsigned char componentTag;
|
||||||
unsigned char streamContent;
|
unsigned char streamContent;
|
||||||
|
|
||||||
SIcomponent(void) {
|
SIcomponent(void) {
|
||||||
|
component = 0;
|
||||||
streamContent=0;
|
streamContent=0;
|
||||||
componentType=0;
|
componentType=0;
|
||||||
componentTag=0;
|
componentTag=0;
|
||||||
}
|
}
|
||||||
SIcomponent(const struct descr_component_header *comp) {
|
SIcomponent(const struct descr_component_header *comp) {
|
||||||
|
component = 0;
|
||||||
streamContent=comp->stream_content;
|
streamContent=comp->stream_content;
|
||||||
componentType=comp->component_type;
|
componentType=comp->component_type;
|
||||||
componentTag=comp->component_tag;
|
componentTag=comp->component_tag;
|
||||||
if(comp->descriptor_length>sizeof(struct descr_component_header)-2)
|
if(comp->descriptor_length>sizeof(struct descr_component_header)-2)
|
||||||
component=convertDVBUTF8(((const char *)comp)+sizeof(struct descr_component_header),
|
setComponent(convertDVBUTF8(((const char *)comp) + sizeof(struct descr_component_header),
|
||||||
comp->descriptor_length-(sizeof(struct descr_component_header)-2), 0, 0);
|
comp->descriptor_length-(sizeof(struct descr_component_header)-2), 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setComponent(const std::string &component_description);
|
||||||
|
const char *getComponentName() const;
|
||||||
|
|
||||||
void dump(void) const {
|
void dump(void) const {
|
||||||
if(component.length())
|
const char *comp = getComponentName();
|
||||||
printf("Component: %s\n", component.c_str());
|
if(*comp)
|
||||||
|
printf("Component: %s\n", comp);
|
||||||
printf("Stream Content: 0x%02hhx\n", streamContent);
|
printf("Stream Content: 0x%02hhx\n", streamContent);
|
||||||
printf("Component type: 0x%02hhx\n", componentType);
|
printf("Component type: 0x%02hhx\n", componentType);
|
||||||
printf("Component tag: 0x%02hhx\n", componentTag);
|
printf("Component tag: 0x%02hhx\n", componentTag);
|
||||||
}
|
}
|
||||||
int saveXML(FILE *file) const {
|
int saveXML(FILE *file) const {
|
||||||
fprintf(file, "\t\t\t<component tag=\"%02x\" type=\"%02x\" stream_content=\"%02x\" text=\"", componentTag, componentType, streamContent);
|
fprintf(file, "\t\t\t<component tag=\"%02x\" type=\"%02x\" stream_content=\"%02x\" text=\"", componentTag, componentType, streamContent);
|
||||||
saveStringToXMLfile(file,component.c_str());
|
saveStringToXMLfile(file, getComponentName());
|
||||||
fprintf(file, "\"/>\n");
|
fprintf(file, "\"/>\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -247,26 +254,15 @@ struct saveSIcomponentXML : public std::unary_function<class SIcomponent, void>
|
|||||||
class SIparentalRating
|
class SIparentalRating
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string countryCode;
|
unsigned int countryCode;
|
||||||
unsigned char rating; // Bei 1-16 -> Minumim Alter = rating +3
|
unsigned char rating; // Bei 1-16 -> Minimales Alter = rating +3
|
||||||
|
|
||||||
SIparentalRating(const std::string &cc, unsigned char rate) {
|
SIparentalRating(const std::string &cc, unsigned char rate);
|
||||||
rating=rate;
|
|
||||||
countryCode=cc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Der Operator zum sortieren
|
// Der Operator zum sortieren
|
||||||
bool operator < (const SIparentalRating& c) const {
|
bool operator < (const SIparentalRating& c) const {
|
||||||
return countryCode < c.countryCode;
|
return countryCode < c.countryCode;
|
||||||
}
|
}
|
||||||
void dump(void) const {
|
|
||||||
printf("Rating: %s %hhu (+3)\n", countryCode.c_str(), rating);
|
|
||||||
}
|
|
||||||
int saveXML(FILE *file) const {
|
|
||||||
if(fprintf(file, "\t\t\t<parental_rating country=\"%s\" rating=\"%hhu\"/>\n", countryCode.c_str(), rating)<0)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
bool operator==(const SIparentalRating& p) const {
|
bool operator==(const SIparentalRating& p) const {
|
||||||
return (rating == p.rating) &&
|
return (rating == p.rating) &&
|
||||||
(countryCode == p.countryCode);
|
(countryCode == p.countryCode);
|
||||||
@@ -275,6 +271,8 @@ class SIparentalRating
|
|||||||
return (rating != p.rating) ||
|
return (rating != p.rating) ||
|
||||||
(countryCode != p.countryCode);
|
(countryCode != p.countryCode);
|
||||||
}
|
}
|
||||||
|
void dump(void) const;
|
||||||
|
int saveXML(FILE *file) const;
|
||||||
};
|
};
|
||||||
//typedef std::set <SIparentalRating, std::less<SIparentalRating> > SIparentalRatings;
|
//typedef std::set <SIparentalRating, std::less<SIparentalRating> > SIparentalRatings;
|
||||||
typedef std::vector <SIparentalRating> SIparentalRatings;
|
typedef std::vector <SIparentalRating> SIparentalRatings;
|
||||||
@@ -344,9 +342,7 @@ struct saveSItimeXML : public std::unary_function<SItime, void>
|
|||||||
class SIevent
|
class SIevent
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::string> langName;
|
std::list<SILangData> langData;
|
||||||
std::map<std::string, std::string> langText;
|
|
||||||
std::map<std::string, std::string> langExtendedText;
|
|
||||||
int running;
|
int running;
|
||||||
|
|
||||||
void parseShortEventDescriptor(const uint8_t *buf, unsigned maxlen);
|
void parseShortEventDescriptor(const uint8_t *buf, unsigned maxlen);
|
||||||
@@ -378,8 +374,112 @@ class SIevent
|
|||||||
std::string itemDescription; // Aus dem Extended Descriptor
|
std::string itemDescription; // Aus dem Extended Descriptor
|
||||||
std::string item; // Aus dem Extended Descriptor
|
std::string item; // Aus dem Extended Descriptor
|
||||||
#endif
|
#endif
|
||||||
std::string contentClassification; // Aus dem Content Descriptor, als String, da mehrere vorkommen koennen
|
struct SIeventClassifications
|
||||||
std::string userClassification; // Aus dem Content Descriptor, als String, da mehrere vorkommen koennen
|
{
|
||||||
|
uint8_t *data;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
SIeventClassifications& operator = (const SIeventClassifications& c)
|
||||||
|
{
|
||||||
|
if (this != &c) {
|
||||||
|
if (data)
|
||||||
|
free(data);
|
||||||
|
if (c.data) {
|
||||||
|
data = (uint8_t *) malloc(c.size);
|
||||||
|
memcpy(data, c.data, c.size);
|
||||||
|
} else
|
||||||
|
data = NULL;
|
||||||
|
size = c.size;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SIeventClassifications(const SIeventClassifications& c)
|
||||||
|
{
|
||||||
|
if (this != &c) {
|
||||||
|
if (c.data) {
|
||||||
|
data = (uint8_t *) malloc(c.size);
|
||||||
|
memcpy(data, c.data, c.size);
|
||||||
|
} else
|
||||||
|
data = NULL;
|
||||||
|
size = c.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const SIeventClassifications& c) const
|
||||||
|
{
|
||||||
|
if (!data && !c.data)
|
||||||
|
return true;
|
||||||
|
if (!(data && c.data))
|
||||||
|
return false;
|
||||||
|
if (size != c.size)
|
||||||
|
return false;
|
||||||
|
return !memcmp(data, c.data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const SIeventClassifications& c) const
|
||||||
|
{
|
||||||
|
return *this == c;
|
||||||
|
}
|
||||||
|
|
||||||
|
SIeventClassifications()
|
||||||
|
{
|
||||||
|
data = NULL;
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~SIeventClassifications()
|
||||||
|
{
|
||||||
|
if (data) free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get(std::string &contentClassifications, std::string &userClassifications) const
|
||||||
|
{
|
||||||
|
contentClassifications.clear();
|
||||||
|
userClassifications.clear();
|
||||||
|
uint8_t *d = data;
|
||||||
|
unsigned int z = size & ~1;
|
||||||
|
for (unsigned int i = 0; i < z; i += 2) {
|
||||||
|
contentClassifications.append(1, (char)(*d++));
|
||||||
|
userClassifications.append(1, (char)(*d++));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t reserve(unsigned int r)
|
||||||
|
{
|
||||||
|
size_t off = size;
|
||||||
|
|
||||||
|
if (off) {
|
||||||
|
uint8_t * _data = (uint8_t *) realloc(data, size + r);
|
||||||
|
if (!_data)
|
||||||
|
return -1;
|
||||||
|
data = _data;
|
||||||
|
} else
|
||||||
|
data = (uint8_t *) malloc(r);
|
||||||
|
size += r;
|
||||||
|
return off;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t set(ssize_t off, uint8_t content, uint8_t user)
|
||||||
|
{
|
||||||
|
if (off < -1 || off + 2 >= (ssize_t) size)
|
||||||
|
return -1;
|
||||||
|
data[off++] = content;
|
||||||
|
data[off++] = user;
|
||||||
|
return off;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t set(ssize_t off, const uint8_t *_data, size_t _size)
|
||||||
|
{
|
||||||
|
if (off < -1 || off + _size >= size)
|
||||||
|
return -1;
|
||||||
|
memcpy (data + off, _data, _size);
|
||||||
|
size += _size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SIeventClassifications classifications;
|
||||||
|
|
||||||
SIevent(const t_original_network_id, const t_transport_stream_id, const t_service_id, const unsigned short);
|
SIevent(const t_original_network_id, const t_transport_stream_id, const t_service_id, const unsigned short);
|
||||||
SIevent(void) {
|
SIevent(void) {
|
||||||
@@ -400,15 +500,23 @@ class SIevent
|
|||||||
// Name aus dem Short-Event-Descriptor
|
// Name aus dem Short-Event-Descriptor
|
||||||
std::string getName() const;
|
std::string getName() const;
|
||||||
void setName(const std::string &lang, const std::string &name);
|
void setName(const std::string &lang, const std::string &name);
|
||||||
|
void setName(unsigned int lang, const std::string &name);
|
||||||
|
|
||||||
// Text aus dem Short-Event-Descriptor
|
// Text aus dem Short-Event-Descriptor
|
||||||
std::string getText() const;
|
std::string getText() const;
|
||||||
void setText(const std::string &lang, const std::string &text);
|
void setText(const std::string &lang, const std::string &text);
|
||||||
|
void setText(unsigned int lang, const std::string &text);
|
||||||
|
|
||||||
// Aus dem Extended Descriptor
|
// Aus dem Extended Descriptor
|
||||||
std::string getExtendedText() const;
|
std::string getExtendedText() const;
|
||||||
void appendExtendedText(const std::string &lang, const std::string &text);
|
void appendExtendedText(const std::string &lang, const std::string &text, bool append = true);
|
||||||
void setExtendedText(const std::string &lang, const std::string &text);
|
void appendExtendedText(unsigned int lang, const std::string &text, bool append = true);
|
||||||
|
void setExtendedText(const std::string &lang, const std::string &text) {
|
||||||
|
appendExtendedText(lang, text, false);
|
||||||
|
}
|
||||||
|
void setExtendedText(unsigned int lang, const std::string &text) {
|
||||||
|
appendExtendedText(lang, text, false);
|
||||||
|
}
|
||||||
|
|
||||||
t_channel_id get_channel_id(void) const {
|
t_channel_id get_channel_id(void) const {
|
||||||
return CREATE_CHANNEL_ID(service_id, original_network_id, transport_stream_id);
|
return CREATE_CHANNEL_ID(service_id, original_network_id, transport_stream_id);
|
||||||
|
@@ -32,12 +32,35 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <OpenThreads/Thread>
|
||||||
|
#include <OpenThreads/Condition>
|
||||||
|
#include <OpenThreads/ScopedLock>
|
||||||
|
|
||||||
#include <sectionsdclient/sectionsdclient.h>
|
#include <sectionsdclient/sectionsdclient.h>
|
||||||
|
|
||||||
#include "SIlanguage.hpp"
|
#include "SIlanguage.hpp"
|
||||||
|
|
||||||
std::vector<std::string> SIlanguage::languages;
|
static OpenThreads::Mutex languages_lock;
|
||||||
pthread_mutex_t SIlanguage::languages_lock = PTHREAD_MUTEX_INITIALIZER;
|
static std::vector<std::string> languages;
|
||||||
|
|
||||||
|
static OpenThreads::Mutex langIndexMutex;
|
||||||
|
std::vector<std::string> langIndex;
|
||||||
|
|
||||||
|
static const std::string languageOFF = "OFF";
|
||||||
|
|
||||||
|
unsigned int getLangIndex(const std::string &lang)
|
||||||
|
{
|
||||||
|
unsigned int ix = 0;
|
||||||
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(langIndexMutex);
|
||||||
|
if (!langIndex.size())
|
||||||
|
langIndex.push_back(languageOFF);
|
||||||
|
for (std::vector<std::string>::iterator it = langIndex.begin(); it != langIndex.end(); ++it, ++ix)
|
||||||
|
if (*it == lang)
|
||||||
|
return ix;
|
||||||
|
langIndex.push_back(lang);
|
||||||
|
return ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ALL = Show all available languages
|
ALL = Show all available languages
|
||||||
@@ -49,22 +72,26 @@ ALL_ALL = Show all wanted languages if possible. If not found show all available
|
|||||||
//CSectionsdClient::SIlanguageMode_t SIlanguage::mode = CSectionsdClient::ALL;
|
//CSectionsdClient::SIlanguageMode_t SIlanguage::mode = CSectionsdClient::ALL;
|
||||||
CSectionsdClient::SIlanguageMode_t SIlanguage::mode = CSectionsdClient::FIRST_ALL;
|
CSectionsdClient::SIlanguageMode_t SIlanguage::mode = CSectionsdClient::FIRST_ALL;
|
||||||
|
|
||||||
void SIlanguage::filter(const std::map<std::string, std::string>& s, int max, std::string& retval)
|
void SIlanguage::filter(const std::list<SILangData>& s, SILangData::SILangDataIndex textIndex, int max, std::string& retval)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&languages_lock);
|
|
||||||
// languages cannot get iterated through
|
// languages cannot get iterated through
|
||||||
// if another thread is updating it simultaneously
|
// if another thread is updating it simultaneously
|
||||||
int count = max;
|
int count = max;
|
||||||
|
|
||||||
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(languages_lock);
|
||||||
if (mode != CSectionsdClient::ALL) {
|
if (mode != CSectionsdClient::ALL) {
|
||||||
for (std::vector<std::string>::const_iterator it = languages.begin() ;
|
for (std::vector<std::string>::const_iterator it = languages.begin() ;
|
||||||
it != languages.end() ; ++it) {
|
it != languages.end() ; ++it) {
|
||||||
std::map<std::string,std::string>::const_iterator text;
|
std::list<SILangData>::const_iterator text;
|
||||||
if ((text = s.find(*it)) != s.end()) {
|
unsigned int lang = getLangIndex(*it);
|
||||||
|
for (text = s.begin(); text != s.end() && text->lang != lang; ++text);
|
||||||
|
if (text != s.end()) {
|
||||||
|
if (text->text[textIndex].empty())
|
||||||
|
continue;
|
||||||
if (count != max) {
|
if (count != max) {
|
||||||
retval.append(" \n");
|
retval.append(" \n");
|
||||||
}
|
}
|
||||||
retval.append(text->second);
|
retval.append(text->text[textIndex]);
|
||||||
if (--count == 0) break;
|
if (--count == 0) break;
|
||||||
if (mode == CSectionsdClient::FIRST_FIRST ||
|
if (mode == CSectionsdClient::FIRST_FIRST ||
|
||||||
mode == CSectionsdClient::FIRST_ALL) {
|
mode == CSectionsdClient::FIRST_ALL) {
|
||||||
@@ -77,12 +104,14 @@ void SIlanguage::filter(const std::map<std::string, std::string>& s, int max, st
|
|||||||
if (retval.length() == 0) {
|
if (retval.length() == 0) {
|
||||||
// return all available languages
|
// return all available languages
|
||||||
if (s.begin() != s.end()) {
|
if (s.begin() != s.end()) {
|
||||||
for (std::map<std::string, std::string>::const_iterator it = s.begin() ;
|
for (std::list<SILangData>::const_iterator it = s.begin() ;
|
||||||
it != s.end() ; ++it) {
|
it != s.end() ; ++it) {
|
||||||
|
if (it->text[textIndex].empty())
|
||||||
|
continue;
|
||||||
if (it != s.begin()) {
|
if (it != s.begin()) {
|
||||||
retval.append(" \n");
|
retval.append(" \n");
|
||||||
}
|
}
|
||||||
retval.append(it->second);
|
retval.append(it->text[textIndex]);
|
||||||
if (--max == 0) break;
|
if (--max == 0) break;
|
||||||
if (mode == CSectionsdClient::FIRST_FIRST ||
|
if (mode == CSectionsdClient::FIRST_FIRST ||
|
||||||
mode == CSectionsdClient::ALL_FIRST) {
|
mode == CSectionsdClient::ALL_FIRST) {
|
||||||
@@ -91,13 +120,12 @@ void SIlanguage::filter(const std::map<std::string, std::string>& s, int max, st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&languages_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SIlanguage::loadLanguages()
|
bool SIlanguage::loadLanguages()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&languages_lock);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(languages_lock);
|
||||||
std::ifstream file(LANGUAGEFILE);
|
std::ifstream file(LANGUAGEFILE);
|
||||||
std::string word;
|
std::string word;
|
||||||
CSectionsdClient::SIlanguageMode_t tmpMode = CSectionsdClient::FIRST_ALL;
|
CSectionsdClient::SIlanguageMode_t tmpMode = CSectionsdClient::FIRST_ALL;
|
||||||
@@ -125,20 +153,18 @@ bool SIlanguage::loadLanguages()
|
|||||||
if (tmpLang.empty()) tmpLang.push_back("OFF");
|
if (tmpLang.empty()) tmpLang.push_back("OFF");
|
||||||
languages = tmpLang;
|
languages = tmpLang;
|
||||||
mode = tmpMode;
|
mode = tmpMode;
|
||||||
pthread_mutex_unlock(&languages_lock);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
tmpLang.push_back("OFF");
|
tmpLang.push_back("OFF");
|
||||||
languages = tmpLang;
|
languages = tmpLang;
|
||||||
mode = tmpMode;
|
mode = tmpMode;
|
||||||
pthread_mutex_unlock(&languages_lock);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SIlanguage::saveLanguages()
|
bool SIlanguage::saveLanguages()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&languages_lock);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(languages_lock);
|
||||||
std::ofstream file(LANGUAGEFILE);
|
std::ofstream file(LANGUAGEFILE);
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case CSectionsdClient::ALL:
|
case CSectionsdClient::ALL:
|
||||||
@@ -171,26 +197,22 @@ bool SIlanguage::saveLanguages()
|
|||||||
file.close();
|
file.close();
|
||||||
if (file.fail()) goto error;
|
if (file.fail()) goto error;
|
||||||
|
|
||||||
pthread_mutex_unlock(&languages_lock);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
pthread_mutex_unlock(&languages_lock);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIlanguage::setLanguages(const std::vector<std::string>& newLanguages)
|
void SIlanguage::setLanguages(const std::vector<std::string>& newLanguages)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&languages_lock);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(languages_lock);
|
||||||
languages = newLanguages;
|
languages = newLanguages;
|
||||||
pthread_mutex_unlock(&languages_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> SIlanguage::getLanguages()
|
std::vector<std::string> SIlanguage::getLanguages()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&languages_lock);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(languages_lock);
|
||||||
std::vector<std::string> retval(languages); // Store it before unlock
|
std::vector<std::string> retval(languages); // Store it before unlock
|
||||||
pthread_mutex_unlock(&languages_lock);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,15 +25,22 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <list>
|
||||||
|
|
||||||
#include <sectionsdclient/sectionsdclient.h>
|
#include <sectionsdclient/sectionsdclient.h>
|
||||||
|
|
||||||
#define LANGUAGEFILE CONFIGDIR "/epglanguages.conf"
|
#define LANGUAGEFILE CONFIGDIR "/epglanguages.conf"
|
||||||
|
|
||||||
|
class SILangData {
|
||||||
|
public:
|
||||||
|
enum SILangDataIndex { langName = 0, langText, langExtendedText, langMax };
|
||||||
|
unsigned int lang;
|
||||||
|
std::string text[langMax];
|
||||||
|
};
|
||||||
|
|
||||||
class SIlanguage {
|
class SIlanguage {
|
||||||
public:
|
public:
|
||||||
static void filter(const std::map<std::string, std::string>& s, int max, std::string& retval);
|
static void filter(const std::list<SILangData>& s, SILangData::SILangDataIndex textIndex, int max, std::string& retval);
|
||||||
static bool loadLanguages();
|
static bool loadLanguages();
|
||||||
static bool saveLanguages();
|
static bool saveLanguages();
|
||||||
static void setLanguages(const std::vector<std::string>& newLanguages);
|
static void setLanguages(const std::vector<std::string>& newLanguages);
|
||||||
@@ -44,9 +51,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
SIlanguage();
|
SIlanguage();
|
||||||
~SIlanguage();
|
~SIlanguage();
|
||||||
static std::vector<std::string> languages;
|
|
||||||
static pthread_mutex_t languages_lock;
|
|
||||||
static CSectionsdClient::SIlanguageMode_t mode;
|
static CSectionsdClient::SIlanguageMode_t mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern std::vector<std::string> langIndex;
|
||||||
|
unsigned int getLangIndex(const std::string &lang);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -344,8 +344,7 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann
|
|||||||
already_exists = false;
|
already_exists = false;
|
||||||
|
|
||||||
if ((already_exists) && (SIlanguage::getMode() == CSectionsdClient::LANGUAGE_MODE_OFF)) {
|
if ((already_exists) && (SIlanguage::getMode() == CSectionsdClient::LANGUAGE_MODE_OFF)) {
|
||||||
si->second->contentClassification = evt.contentClassification;
|
si->second->classifications = evt.classifications;
|
||||||
si->second->userClassification = evt.userClassification;
|
|
||||||
#ifdef USE_ITEM_DESCRIPTION
|
#ifdef USE_ITEM_DESCRIPTION
|
||||||
si->second->itemDescription = evt.itemDescription;
|
si->second->itemDescription = evt.itemDescription;
|
||||||
si->second->item = evt.item;
|
si->second->item = evt.item;
|
||||||
@@ -353,11 +352,11 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann
|
|||||||
//si->second->vps = evt.vps;
|
//si->second->vps = evt.vps;
|
||||||
if ((evt.getExtendedText().length() > 0) && !evt.times.empty() &&
|
if ((evt.getExtendedText().length() > 0) && !evt.times.empty() &&
|
||||||
(evt.times.begin()->startzeit < zeit + secondsExtendedTextCache))
|
(evt.times.begin()->startzeit < zeit + secondsExtendedTextCache))
|
||||||
si->second->setExtendedText("OFF",evt.getExtendedText().c_str());
|
si->second->setExtendedText(0 /*"OFF"*/,evt.getExtendedText());
|
||||||
if (evt.getText().length() > 0)
|
if (evt.getText().length() > 0)
|
||||||
si->second->setText("OFF",evt.getText().c_str());
|
si->second->setText(0 /*"OFF"*/,evt.getText());
|
||||||
if (evt.getName().length() > 0)
|
if (evt.getName().length() > 0)
|
||||||
si->second->setName("OFF",evt.getName().c_str());
|
si->second->setName(0 /*"OFF"*/,evt.getName());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
@@ -375,7 +374,7 @@ xprintf("addEvent: ch %012" PRIx64 " running %d (%s) got_CN %d\n", evt.get_chann
|
|||||||
//Strip ExtendedDescription if too far in the future
|
//Strip ExtendedDescription if too far in the future
|
||||||
if ((e->times.begin()->startzeit > zeit + secondsExtendedTextCache) &&
|
if ((e->times.begin()->startzeit > zeit + secondsExtendedTextCache) &&
|
||||||
(SIlanguage::getMode() == CSectionsdClient::LANGUAGE_MODE_OFF) && (zeit != 0))
|
(SIlanguage::getMode() == CSectionsdClient::LANGUAGE_MODE_OFF) && (zeit != 0))
|
||||||
e->setExtendedText("OFF","");
|
e->setExtendedText(0 /*"OFF"*/,"");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this is test code, so indentation is deliberately wrong :-)
|
* this is test code, so indentation is deliberately wrong :-)
|
||||||
@@ -2601,8 +2600,7 @@ bool CEitManager::getEPGid(const event_id_t epgID, const time_t startzeit, CEPGD
|
|||||||
epgdata->info1 = evt.getText();
|
epgdata->info1 = evt.getText();
|
||||||
epgdata->info2 = evt.getExtendedText();
|
epgdata->info2 = evt.getExtendedText();
|
||||||
/* FIXME printf("itemDescription: %s\n", evt.itemDescription.c_str()); */
|
/* FIXME printf("itemDescription: %s\n", evt.itemDescription.c_str()); */
|
||||||
epgdata->contentClassification = std::string(evt.contentClassification.data(), evt.contentClassification.length());
|
evt.classifications.get(epgdata->contentClassification, epgdata->userClassification);
|
||||||
epgdata->userClassification = std::string(evt.userClassification.data(), evt.userClassification.length());
|
|
||||||
epgdata->fsk = evt.getFSK();
|
epgdata->fsk = evt.getFSK();
|
||||||
epgdata->table_id = evt.table_id;
|
epgdata->table_id = evt.table_id;
|
||||||
|
|
||||||
@@ -2663,8 +2661,7 @@ bool CEitManager::getActualEPGServiceKey(const t_channel_id channel_id, CEPGData
|
|||||||
epgdata->info1 = evt.getText();
|
epgdata->info1 = evt.getText();
|
||||||
epgdata->info2 = evt.getExtendedText();
|
epgdata->info2 = evt.getExtendedText();
|
||||||
/* FIXME printf("itemDescription: %s\n", evt.itemDescription.c_str());*/
|
/* FIXME printf("itemDescription: %s\n", evt.itemDescription.c_str());*/
|
||||||
epgdata->contentClassification = std::string(evt.contentClassification.data(), evt.contentClassification.length());
|
evt.classifications.get(epgdata->contentClassification, epgdata->userClassification);
|
||||||
epgdata->userClassification = std::string(evt.userClassification.data(), evt.userClassification.length());
|
|
||||||
epgdata->fsk = evt.getFSK();
|
epgdata->fsk = evt.getFSK();
|
||||||
epgdata->table_id = evt.table_id;
|
epgdata->table_id = evt.table_id;
|
||||||
|
|
||||||
@@ -2765,7 +2762,7 @@ bool CEitManager::getComponentTagsUniqueKey(const event_id_t uniqueKey, CSection
|
|||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
for (SIcomponents::iterator cmp = eFirst->second->components.begin(); cmp != eFirst->second->components.end(); ++cmp) {
|
for (SIcomponents::iterator cmp = eFirst->second->components.begin(); cmp != eFirst->second->components.end(); ++cmp) {
|
||||||
response.component = cmp->component;
|
response.component = cmp->getComponentName();
|
||||||
response.componentType = cmp->componentType;
|
response.componentType = cmp->componentType;
|
||||||
response.componentTag = cmp->componentTag;
|
response.componentTag = cmp->componentTag;
|
||||||
response.streamContent = cmp->streamContent;
|
response.streamContent = cmp->streamContent;
|
||||||
|
@@ -40,6 +40,7 @@
|
|||||||
#include "xmlutil.h"
|
#include "xmlutil.h"
|
||||||
#include "eitd.h"
|
#include "eitd.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include <system/set_threadname.h>
|
||||||
|
|
||||||
void addEvent(const SIevent &evt, const time_t zeit, bool cn = false);
|
void addEvent(const SIevent &evt, const time_t zeit, bool cn = false);
|
||||||
extern MySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey;
|
extern MySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey;
|
||||||
@@ -270,12 +271,12 @@ void deleteOldfileEvents(char *epgdir)
|
|||||||
|
|
||||||
void *insertEventsfromFile(void * data)
|
void *insertEventsfromFile(void * data)
|
||||||
{
|
{
|
||||||
|
set_threadname(__func__);
|
||||||
reader_ready=false;
|
reader_ready=false;
|
||||||
xmlDocPtr event_parser = NULL;
|
xmlDocPtr event_parser = NULL;
|
||||||
xmlNodePtr eventfile = NULL;
|
xmlNodePtr eventfile = NULL;
|
||||||
xmlNodePtr service = NULL;
|
xmlNodePtr service = NULL;
|
||||||
xmlNodePtr event = NULL;
|
xmlNodePtr event = NULL;
|
||||||
xmlNodePtr node = NULL;
|
|
||||||
t_original_network_id onid = 0;
|
t_original_network_id onid = 0;
|
||||||
t_transport_stream_id tsid = 0;
|
t_transport_stream_id tsid = 0;
|
||||||
t_service_id sid = 0;
|
t_service_id sid = 0;
|
||||||
@@ -316,86 +317,121 @@ void *insertEventsfromFile(void * data)
|
|||||||
event = service->xmlChildrenNode;
|
event = service->xmlChildrenNode;
|
||||||
|
|
||||||
while (event) {
|
while (event) {
|
||||||
|
|
||||||
SIevent e(onid,tsid,sid,xmlGetNumericAttribute(event, "id", 16));
|
SIevent e(onid,tsid,sid,xmlGetNumericAttribute(event, "id", 16));
|
||||||
uint8_t tid = xmlGetNumericAttribute(event, "tid", 16);
|
uint8_t tid = xmlGetNumericAttribute(event, "tid", 16);
|
||||||
|
std::string contentClassification, userClassification;
|
||||||
if(tid)
|
if(tid)
|
||||||
e.table_id = tid;
|
e.table_id = tid;
|
||||||
e.table_id |= 0x80; /* make sure on-air data has a lower table_id */
|
e.table_id |= 0x80; /* make sure on-air data has a lower table_id */
|
||||||
|
|
||||||
node = event->xmlChildrenNode;
|
xmlNodePtr node;
|
||||||
|
|
||||||
while (xmlGetNextOccurence(node, "name") != NULL) {
|
node = event->xmlChildrenNode;
|
||||||
e.setName( std::string(ZapitTools::UTF8_to_Latin1(xmlGetAttribute(node, "lang"))),
|
while ((node = xmlGetNextOccurence(node, "name"))) {
|
||||||
std::string(xmlGetAttribute(node, "string")));
|
char *s = xmlGetAttribute(node, "string");
|
||||||
|
if (s)
|
||||||
|
e.setName(ZapitTools::UTF8_to_Latin1(xmlGetAttribute(node, "lang")), s);
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
while (xmlGetNextOccurence(node, "text") != NULL) {
|
|
||||||
e.setText( std::string(ZapitTools::UTF8_to_Latin1(xmlGetAttribute(node, "lang"))),
|
node = event->xmlChildrenNode;
|
||||||
std::string(xmlGetAttribute(node, "string")));
|
while ((node = xmlGetNextOccurence(node, "text"))) {
|
||||||
|
char *s = xmlGetAttribute(node, "string");
|
||||||
|
if (s)
|
||||||
|
e.setText(ZapitTools::UTF8_to_Latin1(xmlGetAttribute(node, "lang")), s);
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
while (xmlGetNextOccurence(node, "item") != NULL) {
|
node = event->xmlChildrenNode;
|
||||||
|
while ((node = xmlGetNextOccurence(node, "item"))) {
|
||||||
#ifdef USE_ITEM_DESCRIPTION
|
#ifdef USE_ITEM_DESCRIPTION
|
||||||
e.item = std::string(xmlGetAttribute(node, "string"));
|
char *s = xmlGetAttribute(node, "string");
|
||||||
|
if (s)
|
||||||
|
e.item = s;
|
||||||
#endif
|
#endif
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
while (xmlGetNextOccurence(node, "item_description") != NULL) {
|
|
||||||
|
node = event->xmlChildrenNode;
|
||||||
|
while ((node = xmlGetNextOccurence(node, "item_description"))) {
|
||||||
#ifdef USE_ITEM_DESCRIPTION
|
#ifdef USE_ITEM_DESCRIPTION
|
||||||
e.itemDescription = std::string(xmlGetAttribute(node, "string"));
|
char *s = xmlGetAttribute(node, "string");
|
||||||
|
if (s)
|
||||||
|
e.itemDescription = s;
|
||||||
#endif
|
#endif
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
while (xmlGetNextOccurence(node, "extended_text") != NULL) {
|
node = event->xmlChildrenNode;
|
||||||
e.appendExtendedText( std::string(ZapitTools::UTF8_to_Latin1(xmlGetAttribute(node, "lang"))),
|
while ((node = xmlGetNextOccurence(node, "extended_text"))) {
|
||||||
std::string(xmlGetAttribute(node, "string")));
|
char *l = xmlGetAttribute(node, "lang");
|
||||||
|
char *s = xmlGetAttribute(node, "string");
|
||||||
|
if (l && s)
|
||||||
|
e.appendExtendedText(ZapitTools::UTF8_to_Latin1(l), s);
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
while (xmlGetNextOccurence(node, "time") != NULL) {
|
|
||||||
|
node = event->xmlChildrenNode;
|
||||||
|
while ((node = xmlGetNextOccurence(node, "time"))) {
|
||||||
e.times.insert(SItime(xmlGetNumericAttribute(node, "start_time", 10),
|
e.times.insert(SItime(xmlGetNumericAttribute(node, "start_time", 10),
|
||||||
xmlGetNumericAttribute(node, "duration", 10)));
|
xmlGetNumericAttribute(node, "duration", 10)));
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (xmlGetNextOccurence(node, "content") != NULL) {
|
node = event->xmlChildrenNode;
|
||||||
|
while ((node = xmlGetNextOccurence(node, "content"))) {
|
||||||
char cl = xmlGetNumericAttribute(node, "class", 16);
|
char cl = xmlGetNumericAttribute(node, "class", 16);
|
||||||
e.contentClassification += cl;
|
contentClassification += cl;
|
||||||
cl = xmlGetNumericAttribute(node, "user", 16);
|
cl = xmlGetNumericAttribute(node, "user", 16);
|
||||||
e.userClassification += cl;
|
userClassification += cl;
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (xmlGetNextOccurence(node, "component") != NULL) {
|
node = event->xmlChildrenNode;
|
||||||
|
while ((node = xmlGetNextOccurence(node, "component"))) {
|
||||||
SIcomponent c;
|
SIcomponent c;
|
||||||
c.streamContent = xmlGetNumericAttribute(node, "stream_content", 16);
|
c.streamContent = xmlGetNumericAttribute(node, "stream_content", 16);
|
||||||
c.componentType = xmlGetNumericAttribute(node, "type", 16);
|
c.componentType = xmlGetNumericAttribute(node, "type", 16);
|
||||||
c.componentTag = xmlGetNumericAttribute(node, "tag", 16);
|
c.componentTag = xmlGetNumericAttribute(node, "tag", 16);
|
||||||
c.component = std::string(xmlGetAttribute(node, "text"));
|
char *s = xmlGetAttribute(node, "text");
|
||||||
|
if (s)
|
||||||
|
c.setComponent(s);
|
||||||
//e.components.insert(c);
|
//e.components.insert(c);
|
||||||
e.components.push_back(c);
|
e.components.push_back(c);
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
while (xmlGetNextOccurence(node, "parental_rating") != NULL) {
|
|
||||||
|
node = event->xmlChildrenNode;
|
||||||
|
while ((node = xmlGetNextOccurence(node, "parental_rating"))) {
|
||||||
|
char *s = xmlGetAttribute(node, "country");
|
||||||
|
if (s)
|
||||||
#if 0
|
#if 0
|
||||||
e.ratings.insert(SIparentalRating(std::string(ZapitTools::UTF8_to_Latin1(xmlGetAttribute(node, "country"))),
|
e.ratings.insert(SIparentalRating(ZapitTools::UTF8_to_Latin1(s),
|
||||||
(unsigned char) xmlGetNumericAttribute(node, "rating", 10)));
|
(unsigned char) xmlGetNumericAttribute(node, "rating", 10)));
|
||||||
#endif
|
#endif
|
||||||
e.ratings.push_back(SIparentalRating(std::string(ZapitTools::UTF8_to_Latin1(xmlGetAttribute(node, "country"))),
|
e.ratings.push_back(SIparentalRating(ZapitTools::UTF8_to_Latin1(s),
|
||||||
(unsigned char) xmlGetNumericAttribute(node, "rating", 10)));
|
(unsigned char) xmlGetNumericAttribute(node, "rating", 10)));
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
while (xmlGetNextOccurence(node, "linkage") != NULL) {
|
|
||||||
|
node = event->xmlChildrenNode;
|
||||||
|
while ((node = xmlGetNextOccurence(node, "linkage"))) {
|
||||||
SIlinkage l;
|
SIlinkage l;
|
||||||
l.linkageType = xmlGetNumericAttribute(node, "type", 16);
|
l.linkageType = xmlGetNumericAttribute(node, "type", 16);
|
||||||
l.transportStreamId = xmlGetNumericAttribute(node, "transport_stream_id", 16);
|
l.transportStreamId = xmlGetNumericAttribute(node, "transport_stream_id", 16);
|
||||||
l.originalNetworkId = xmlGetNumericAttribute(node, "original_network_id", 16);
|
l.originalNetworkId = xmlGetNumericAttribute(node, "original_network_id", 16);
|
||||||
l.serviceId = xmlGetNumericAttribute(node, "service_id", 16);
|
l.serviceId = xmlGetNumericAttribute(node, "service_id", 16);
|
||||||
l.name = std::string(xmlGetAttribute(node, "linkage_descriptor"));
|
char *s = xmlGetAttribute(node, "linkage_descriptor");
|
||||||
|
if (s)
|
||||||
|
l.name = s;
|
||||||
e.linkage_descs.insert(e.linkage_descs.end(), l);
|
e.linkage_descs.insert(e.linkage_descs.end(), l);
|
||||||
|
|
||||||
node = node->xmlNextNode;
|
node = node->xmlNextNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (contentClassification.size()) {
|
||||||
|
ssize_t off = e.classifications.reserve(2 * contentClassification.size());
|
||||||
|
if (off > -1)
|
||||||
|
for (unsigned i = 0; i < contentClassification.size(); i++)
|
||||||
|
off = e.classifications.set(off, contentClassification.at(i), userClassification.at(i));
|
||||||
|
}
|
||||||
addEvent(e, 0);
|
addEvent(e, 0);
|
||||||
ev_count++;
|
ev_count++;
|
||||||
|
|
||||||
@@ -411,7 +447,7 @@ void *insertEventsfromFile(void * data)
|
|||||||
|
|
||||||
xmlFreeDoc(index_parser);
|
xmlFreeDoc(index_parser);
|
||||||
printdate_ms(stdout);
|
printdate_ms(stdout);
|
||||||
printf("[sectionsd] Reading Information finished after %ld miliseconds (%d events)\n",
|
printf("[sectionsd] Reading Information finished after %ld milliseconds (%d events)\n",
|
||||||
time_monotonic_ms()-now, ev_count);
|
time_monotonic_ms()-now, ev_count);
|
||||||
|
|
||||||
reader_ready = true;
|
reader_ready = true;
|
||||||
|
Reference in New Issue
Block a user