mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Fixed handling itemized texts in EPG data
This commit is contained in:
parent
e070d5462c
commit
823081b59e
@ -944,6 +944,7 @@ Thomas Bergwinkl <Thomas.Bergwinkl@t-online.de>
|
||||
Stéphane Esté-Gracias <sestegra@free.fr>
|
||||
for fixing a typo in libsi/si.h
|
||||
for fixing some descriptor handling in 'libsi'
|
||||
for pointing out a problem with "itemized" texts in EPG data
|
||||
|
||||
Marc Hoppe <MarcHoppe@gmx.de>
|
||||
for fixing handling the current menu item
|
||||
|
2
HISTORY
2
HISTORY
@ -2725,3 +2725,5 @@ Video Disk Recorder Revision History
|
||||
- Fixed handling timers in VPS margin if the EPG scan is turned on (the EPG scan
|
||||
switched the device away from the channel, so it wouldn't see the change of
|
||||
the running status).
|
||||
- Fixed handling "itemized" texts in EPG data (thanks to Stéphane Esté-Gracias
|
||||
for pointing out this problem, and Marcel Wiesweg for improving 'libsi').
|
||||
|
4
eit.c
4
eit.c
@ -8,7 +8,7 @@
|
||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
|
||||
*
|
||||
* $Id: eit.c 1.90 2004/03/06 14:24:22 kls Exp $
|
||||
* $Id: eit.c 1.91 2004/03/07 10:36:57 kls Exp $
|
||||
*/
|
||||
|
||||
#include "eit.h"
|
||||
@ -191,7 +191,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
|
||||
}
|
||||
if (ExtendedEventDescriptors) {
|
||||
char buffer[ExtendedEventDescriptors->getMaximumTextLength()];
|
||||
pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer));
|
||||
pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, ": "));
|
||||
}
|
||||
}
|
||||
delete ExtendedEventDescriptors;
|
||||
|
@ -6,7 +6,7 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: descriptor.c 1.7 2004/03/05 15:17:33 kls Exp $
|
||||
* $Id: descriptor.c 1.8 2004/03/07 11:07:57 kls Exp $
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
@ -60,13 +60,13 @@ void ExtendedEventDescriptor::Item::Parse() {
|
||||
item.setData(data+offset, mid->item_length);
|
||||
}
|
||||
|
||||
int ExtendedEventDescriptors::getTextLength() {
|
||||
/*int ExtendedEventDescriptors::getTextLength() {
|
||||
int ret=0;
|
||||
for (int i=0;i<length;i++) {
|
||||
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
|
||||
if (!d)
|
||||
continue;
|
||||
ret+=d->text.getLength()+1; //plus a blank
|
||||
ret+=d->text.getLength();
|
||||
ExtendedEventDescriptor::Item item;
|
||||
for (Loop::Iterator it; d->itemLoop.hasNext(it); ) {
|
||||
item=d->itemLoop.getNext(it);
|
||||
@ -76,28 +76,18 @@ int ExtendedEventDescriptors::getTextLength() {
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}*/
|
||||
|
||||
//is there a case where this function does not return the same as getTextLength?
|
||||
int ExtendedEventDescriptors::getMaximumTextLength() {
|
||||
int ret=0;
|
||||
for (int i=0;i<length;i++) {
|
||||
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
|
||||
if (!d)
|
||||
continue;
|
||||
ret+=d->text.getLength()+1; //plus a blank
|
||||
ret+=d->itemLoop.getLength();
|
||||
}
|
||||
return ret;
|
||||
return getMaximumTextPlainLength()+getMaximumTextItemizedLength();
|
||||
}
|
||||
|
||||
char *ExtendedEventDescriptors::getText() {
|
||||
char *ExtendedEventDescriptors::getText(const char *separation1, const char *separation2) {
|
||||
char *text=new char[getMaximumTextLength()];
|
||||
return getText(text);
|
||||
return getText(text, separation1, separation2);
|
||||
}
|
||||
|
||||
//appends the Strings of every Descriptor in the group
|
||||
char *ExtendedEventDescriptors::getText(char *buffer) {
|
||||
char *ExtendedEventDescriptors::getText(char *buffer, const char *separation1, const char *separation2) {
|
||||
int index=0, len;
|
||||
char tempbuf[256];
|
||||
for (int i=0;i<length;i++) {
|
||||
@ -110,30 +100,161 @@ char *ExtendedEventDescriptors::getText(char *buffer) {
|
||||
memcpy(buffer+index, tempbuf, len);
|
||||
index+=len;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0;i<length;i++) {
|
||||
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
|
||||
if (!d)
|
||||
continue;
|
||||
|
||||
ExtendedEventDescriptor::Item item;
|
||||
for (Loop::Iterator it; d->itemLoop.hasNext(it); ) {
|
||||
item=d->itemLoop.getNext(it);
|
||||
|
||||
item.item.getText(tempbuf);
|
||||
len=strlen(tempbuf);
|
||||
if (len) {
|
||||
memcpy(buffer+index, tempbuf, len);
|
||||
index+=len;
|
||||
}
|
||||
|
||||
item.itemDescription.getText(tempbuf);
|
||||
len=strlen(tempbuf);
|
||||
if (len) {
|
||||
memcpy(buffer+index, tempbuf, len);
|
||||
index+=len;
|
||||
}
|
||||
strcpy(buffer+index, separation1);
|
||||
index += strlen(separation1);
|
||||
|
||||
item.item.getText(tempbuf);
|
||||
len=strlen(tempbuf);
|
||||
if (len) {
|
||||
memcpy(buffer+index, tempbuf, len);
|
||||
index+=len;
|
||||
}
|
||||
strcpy(buffer+index, separation2);
|
||||
index += strlen(separation2);
|
||||
}
|
||||
}
|
||||
|
||||
buffer[index]='\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int ExtendedEventDescriptors::getMaximumTextPlainLength() {
|
||||
int ret=0;
|
||||
for (int i=0;i<length;i++) {
|
||||
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
|
||||
if (!d)
|
||||
continue;
|
||||
ret+=d->text.getLength();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *ExtendedEventDescriptors::getTextPlain() {
|
||||
char *text=new char[getMaximumTextPlainLength()];
|
||||
return getText(text);
|
||||
}
|
||||
|
||||
char *ExtendedEventDescriptors::getTextPlain(char *buffer) {
|
||||
int index=0, len;
|
||||
char tempbuf[256];
|
||||
for (int i=0;i<length;i++) {
|
||||
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
|
||||
if (!d)
|
||||
continue;
|
||||
d->text.getText(tempbuf);
|
||||
len=strlen(tempbuf);
|
||||
if (len) {
|
||||
memcpy(buffer+index, tempbuf, len);
|
||||
index+=len;
|
||||
}
|
||||
}
|
||||
buffer[index]='\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int ExtendedEventDescriptors::getMaximumTextItemizedLength() {
|
||||
int ret=0;
|
||||
for (int i=0;i<length;i++) {
|
||||
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
|
||||
if (!d)
|
||||
continue;
|
||||
//the size for the two separating characters is included ;-)
|
||||
ret+=d->itemLoop.getLength();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *ExtendedEventDescriptors::getTextItemized(const char *separation1, const char *separation2) {
|
||||
char *text=new char[getMaximumTextItemizedLength()];
|
||||
return getText(text, separation1, separation2);
|
||||
}
|
||||
|
||||
char *ExtendedEventDescriptors::getTextItemized(char *buffer, const char *separation1, const char *separation2) {
|
||||
int index=0, len;
|
||||
char tempbuf[256];
|
||||
for (int i=0;i<length;i++) {
|
||||
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
|
||||
if (!d)
|
||||
continue;
|
||||
|
||||
ExtendedEventDescriptor::Item item;
|
||||
for (Loop::Iterator it; d->itemLoop.hasNext(it); ) {
|
||||
item=d->itemLoop.getNext(it);
|
||||
|
||||
item.itemDescription.getText(tempbuf);
|
||||
len=strlen(tempbuf);
|
||||
if (len) {
|
||||
memcpy(buffer+index, tempbuf, len);
|
||||
index+=len;
|
||||
}
|
||||
strcpy(buffer+index, separation1);
|
||||
index += strlen(separation1);
|
||||
|
||||
item.item.getText(tempbuf);
|
||||
len=strlen(tempbuf);
|
||||
if (len) {
|
||||
memcpy(buffer+index, tempbuf, len);
|
||||
index+=len;
|
||||
}
|
||||
strcpy(buffer+index, separation2);
|
||||
index += strlen(separation2);
|
||||
}
|
||||
}
|
||||
buffer[index]='\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//returns the itemized text pair by pair. Maximum length for buffers is 256.
|
||||
//Return value is false if and only if the end of the list is reached.
|
||||
bool ExtendedEventDescriptors::getTextItemized(Loop::Iterator &it, bool &valid, char *itemDescription, char *itemText) {
|
||||
//The iterator has to store two values: The descriptor index (4bit)
|
||||
//and the item loop index (max overall length 256, min item length 16 => max number 128 => 7bit)
|
||||
valid=false;
|
||||
|
||||
int index=(it.i & 0x780) >> 7; // 0x780 == 1111 000 0000
|
||||
it.i &= 0x7F; //0x7F == 111 1111
|
||||
|
||||
for (;index<length;index++) {
|
||||
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[index];
|
||||
if (!d)
|
||||
continue;
|
||||
|
||||
ExtendedEventDescriptor::Item item;
|
||||
if (d->itemLoop.hasNext(it)) {
|
||||
item=d->itemLoop.getNext(it);
|
||||
|
||||
item.item.getText(itemDescription);
|
||||
item.itemDescription.getText(itemText);
|
||||
valid=true;
|
||||
} else {
|
||||
it.reset();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
it.i &= 0x7F;
|
||||
it.i |= (index & 0xF) << 7; //0xF == 1111
|
||||
|
||||
return index<length;
|
||||
}
|
||||
|
||||
int TimeShiftedEventDescriptor::getReferenceServiceId() const {
|
||||
return HILO(s->reference_service_id);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: descriptor.h 1.6 2004/02/22 10:16:47 kls Exp $
|
||||
* $Id: descriptor.h 1.7 2004/03/07 11:13:54 kls Exp $
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
@ -50,14 +50,29 @@ private:
|
||||
|
||||
class ExtendedEventDescriptors : public DescriptorGroup {
|
||||
public:
|
||||
//don't use
|
||||
int getTextLength();
|
||||
//really fast
|
||||
int getMaximumTextLength();
|
||||
//Returns a concatenated version of first the non-itemized and then the itemized text
|
||||
//same semantics as with SI::String
|
||||
char *getText();
|
||||
char *getText(const char *separation1="\t", const char *separation2="\n");
|
||||
//buffer must at least be getTextLength(), getMaximumTextLength() is a good choice
|
||||
char *getText(char *buffer);
|
||||
char *getText(char *buffer, const char *separation1="\t", const char *separation2="\n");
|
||||
|
||||
//these only return the non-itemized text fields in concatenated form
|
||||
int getMaximumTextPlainLength();
|
||||
char *getTextPlain();
|
||||
char *getTextPlain(char *buffer);
|
||||
|
||||
//these only return the itemized text fields in concatenated form.
|
||||
//Between the description and the text the separation1 character is used,
|
||||
//separation2 used between two pairs. Example:
|
||||
//Director\tSteven Spielberg\nActor\tMichael Mendl\n
|
||||
int getMaximumTextItemizedLength();
|
||||
char *getTextItemized(const char *separation1="\t", const char *separation2="\n");
|
||||
char *getTextItemized(char *buffer, const char *separation1="\t", const char *separation2="\n");
|
||||
//returns the itemized text pair by pair. Maximum length for buffers is 256.
|
||||
//Return value is false if and only if the end of the list is reached.
|
||||
//The argument valid indicates whether the buffers contain valid content.
|
||||
bool getTextItemized(Loop::Iterator &it, bool &valid, char *itemDescription, char *itemText);
|
||||
};
|
||||
|
||||
class TimeShiftedEventDescriptor : public Descriptor {
|
||||
|
85
libsi/si.c
85
libsi/si.c
@ -6,7 +6,7 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: si.c 1.8 2004/02/22 10:14:12 kls Exp $
|
||||
* $Id: si.c 1.9 2004/03/07 10:50:09 kls Exp $
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
@ -103,7 +103,7 @@ DescriptorTag Descriptor::getDescriptorTag(const unsigned char *d) {
|
||||
|
||||
Descriptor *DescriptorLoop::getNext(Iterator &it) {
|
||||
if (it.i<getLength()) {
|
||||
return createDescriptor(it.i);
|
||||
return createDescriptor(it.i, true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -115,19 +115,18 @@ Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag tag, bool return
|
||||
const unsigned char *end=p+getLength();
|
||||
while (p < end) {
|
||||
if (Descriptor::getDescriptorTag(p) == tag) {
|
||||
d=createDescriptor(it.i);
|
||||
break;
|
||||
d=createDescriptor(it.i, returnUnimplemetedDescriptor);
|
||||
if (d)
|
||||
break;
|
||||
}
|
||||
it.i+=Descriptor::getLength(p);
|
||||
p+=Descriptor::getLength(p);
|
||||
}
|
||||
}
|
||||
if (d && d->getDescriptorTag()==UnimplementedDescriptorTag)
|
||||
return returnUnimplemetedDescriptor ? d : 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplemetedDescriptor) {
|
||||
Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplementedDescriptor) {
|
||||
Descriptor *d=0;
|
||||
if (it.i<getLength()) {
|
||||
const unsigned char *p=data.getData(it.i);
|
||||
@ -135,27 +134,38 @@ Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int array
|
||||
while (p < end) {
|
||||
for (int u=0; u<arrayLength;u++)
|
||||
if (Descriptor::getDescriptorTag(p) == tags[u]) {
|
||||
d=createDescriptor(it.i);
|
||||
d=createDescriptor(it.i, returnUnimplementedDescriptor);
|
||||
break;
|
||||
}
|
||||
if (d)
|
||||
break;
|
||||
break; //length is added to it.i by createDescriptor, break here
|
||||
it.i+=Descriptor::getLength(p);
|
||||
p+=Descriptor::getLength(p);
|
||||
}
|
||||
}
|
||||
if (d && d->getDescriptorTag()==UnimplementedDescriptorTag)
|
||||
return returnUnimplemetedDescriptor ? d : 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
Descriptor *DescriptorLoop::createDescriptor(int &i) {
|
||||
Descriptor *d=Descriptor::getDescriptor(data+i, domain);
|
||||
Descriptor *DescriptorLoop::createDescriptor(int &i, bool returnUnimplemetedDescriptor) {
|
||||
Descriptor *d=Descriptor::getDescriptor(data+i, domain, returnUnimplemetedDescriptor);
|
||||
if (!d)
|
||||
return 0;
|
||||
i+=d->getLength();
|
||||
d->CheckParse();
|
||||
return d;
|
||||
}
|
||||
|
||||
int DescriptorLoop::getNumberOfDescriptors() {
|
||||
const unsigned char *p=data.getData();
|
||||
const unsigned char *end=p+getLength();
|
||||
int count=0;
|
||||
while (p < end) {
|
||||
count++;
|
||||
p+=Descriptor::getLength(p);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
DescriptorGroup::DescriptorGroup(bool del) {
|
||||
array=0;
|
||||
length=0;
|
||||
@ -211,6 +221,16 @@ char *String::getText(char *buffer) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//taken from VDR, Copyright Klaus Schmidinger <kls@cadsoft.de>
|
||||
char *String::getText(char *buffer, char *shortVersion) {
|
||||
if (getLength() < 0 || getLength() >4095) {
|
||||
strncpy(buffer, "text error", getLength()+1);
|
||||
return buffer;
|
||||
}
|
||||
decodeText(buffer, shortVersion);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//taken from libdtv, Copyright Rolf Hakenes <hakenes@hippomi.de>
|
||||
void String::decodeText(char *buffer) {
|
||||
const unsigned char *from=data.getData(0);
|
||||
@ -228,18 +248,47 @@ void String::decodeText(char *buffer) {
|
||||
if ( ((' ' <= *from) && (*from <= '~'))
|
||||
|| (*from == '\n')
|
||||
|| (0xA0 <= *from)
|
||||
|| (*from == 0x86 || *from == 0x87)
|
||||
)
|
||||
*to++ = *from;
|
||||
else if (*from == 0x8A)
|
||||
*to++ = '\n';
|
||||
else if (*from == 0x86 || *from == 0x87) //&& !(GDT_NAME_DESCRIPTOR & type))
|
||||
*to++ = *from;
|
||||
from++;
|
||||
}
|
||||
*to = '\0';
|
||||
}
|
||||
|
||||
Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain) {
|
||||
void String::decodeText(char *buffer, char *shortVersion) {
|
||||
const unsigned char *from=data.getData(0);
|
||||
char *to=buffer;
|
||||
char *toShort=shortVersion;
|
||||
int IsShortName=0;
|
||||
|
||||
for (int i = 0; i < getLength(); i++) {
|
||||
if (*from == 0)
|
||||
break;
|
||||
if ( ((' ' <= *from) && (*from <= '~'))
|
||||
|| (*from == '\n')
|
||||
|| (0xA0 <= *from)
|
||||
)
|
||||
{
|
||||
*to++ = *from;
|
||||
if (IsShortName)
|
||||
*toShort++ = *from;
|
||||
}
|
||||
else if (*from == 0x8A)
|
||||
*to++ = '\n';
|
||||
else if (*from == 0x86)
|
||||
IsShortName++;
|
||||
else if (*from == 0x87)
|
||||
IsShortName--;
|
||||
from++;
|
||||
}
|
||||
*to = '\0';
|
||||
*toShort = '\0';
|
||||
}
|
||||
|
||||
Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor) {
|
||||
Descriptor *d=0;
|
||||
switch (domain) {
|
||||
case SI:
|
||||
@ -383,6 +432,8 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain)
|
||||
case AdaptationFieldDataDescriptorTag:
|
||||
case TransportStreamDescriptorTag:
|
||||
default:
|
||||
if (!returnUnimplemetedDescriptor)
|
||||
return 0;
|
||||
d=new UnimplementedDescriptor();
|
||||
break;
|
||||
}
|
||||
@ -417,6 +468,8 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain)
|
||||
case MHP_DelegatedApplicationDescriptorTag:
|
||||
case MHP_ApplicationStorageDescriptorTag:
|
||||
default:
|
||||
if (!returnUnimplemetedDescriptor)
|
||||
return 0;
|
||||
d=new UnimplementedDescriptor();
|
||||
break;
|
||||
}
|
||||
|
63
libsi/si.h
63
libsi/si.h
@ -6,7 +6,7 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: si.h 1.8 2004/02/23 17:02:33 kls Exp $
|
||||
* $Id: si.h 1.9 2004/03/07 10:09:49 kls Exp $
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
@ -252,8 +252,11 @@ protected:
|
||||
//returns a subclass of descriptor according to the data given.
|
||||
//The object is allocated with new and must be delete'd.
|
||||
//setData() will have been called, CheckParse() not.
|
||||
//Never returns null - maybe the UnimplementedDescriptor.
|
||||
static Descriptor *getDescriptor(CharArray d, DescriptorTagDomain domain);
|
||||
//if returnUnimplemetedDescriptor==true:
|
||||
// Never returns null - maybe the UnimplementedDescriptor.
|
||||
//if returnUnimplemetedDescriptor==false:
|
||||
// Never returns the UnimplementedDescriptor - maybe null
|
||||
static Descriptor *getDescriptor(CharArray d, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor);
|
||||
};
|
||||
|
||||
class Loop : public VariableLengthPart {
|
||||
@ -266,6 +269,7 @@ public:
|
||||
template <class T> friend class StructureLoop;
|
||||
friend class DescriptorLoop;
|
||||
template <class T> friend class TypeLoop;
|
||||
friend class ExtendedEventDescriptors;
|
||||
int i;
|
||||
};
|
||||
protected:
|
||||
@ -311,14 +315,46 @@ public:
|
||||
//returns null if no more descriptors available
|
||||
Descriptor *getNext(Iterator &it);
|
||||
//return the next descriptor with given tag, or 0 if not available.
|
||||
//if the descriptor found is not implemented,
|
||||
// an UnimplementedDescriptor will be returned if returnUnimplemetedDescriptor==true,
|
||||
// 0 will be returned if returnUnimplemetedDescriptor==false
|
||||
//if returnUnimplemetedDescriptor==true:
|
||||
// an UnimplementedDescriptor may be returned if the next matching descriptor is unimplemented,
|
||||
// 0 will be returned if and only if no matching descriptor is found.
|
||||
//if returnUnimplemetedDescriptor==false:
|
||||
// if 0 is returned, either no descriptor with the given tag was found,
|
||||
// or descriptors were found, but the descriptor type is not implemented
|
||||
//In either case, a return value of 0 indicates that no further calls to this method
|
||||
//with the iterator shall be made.
|
||||
Descriptor *getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor=false);
|
||||
//return the next descriptor with one of the given tags, or 0 if not available.
|
||||
//if returnUnimplemetedDescriptor==true:
|
||||
// returns 0 if and only if no descriptor with one of the given tags was found.
|
||||
// The UnimplementedDescriptor may be returned.
|
||||
//if returnUnimplemetedDescriptor==false:
|
||||
// if 0 is returned, either no descriptor with one of the given tags was found,
|
||||
// or descriptors were found, but none of them are implemented.
|
||||
// The UnimplementedDescriptor will never be returned.
|
||||
//In either case, a return value of 0 indicates that no further calls to this method
|
||||
//with the iterator shall be made.
|
||||
Descriptor *getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplemetedDescriptor=false);
|
||||
//returns the number of descriptors in this loop
|
||||
int getNumberOfDescriptors();
|
||||
//writes the tags of the descriptors in this loop in the array,
|
||||
// which must at least have the size getNumberOfDescriptors().
|
||||
//The number of descriptors, i.e. getNumberOfDescriptors(), is returned.
|
||||
// You can specify the array type (Descriptor tags are 8 Bit,
|
||||
// you might e.g. choose a char, short, int or DescriptorTag array)
|
||||
template <typename T> int getDescriptorTags(T *tags)
|
||||
{
|
||||
const unsigned char *p=data.getData();
|
||||
const unsigned char *end=p+getLength();
|
||||
int count=0;
|
||||
while (p < end) {
|
||||
tags[count++]=(T)Descriptor::getDescriptorTag(p);
|
||||
p+=Descriptor::getLength(p);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
protected:
|
||||
Descriptor *createDescriptor(int &i);
|
||||
Descriptor *createDescriptor(int &i, bool returnUnimplemetedDescriptor);
|
||||
DescriptorTagDomain domain;
|
||||
};
|
||||
|
||||
@ -385,7 +421,7 @@ class String : public VariableLengthPart {
|
||||
public:
|
||||
//A note to the length: getLength() returns the length of the raw data.
|
||||
//The text may be shorter. Its length can be obtained with one of the
|
||||
//above functions and strlen.
|
||||
//getText functions and strlen.
|
||||
|
||||
//returns text. Data is allocated with new and must be delete'd by the user.
|
||||
char *getText();
|
||||
@ -394,10 +430,19 @@ public:
|
||||
//In most descriptors the string length is an 8-bit field,
|
||||
//so the maximum there is 256.
|
||||
//returns the given buffer for convenience.
|
||||
char * getText(char *buffer);
|
||||
//The emphasis marks 0x86 and 0x87 are still available.
|
||||
char *getText(char *buffer);
|
||||
//The same semantics as for getText(char*) apply.
|
||||
//The short version of the text according to ETSI TR 101 211 (chapter 4.6)
|
||||
//will be written into the shortVersion buffer (which should, therefore, have the same
|
||||
//length as buffer). If no shortVersion is available, shortVersion will contain
|
||||
//an empty string.
|
||||
//The emphasis marks 0x86 and 0x87 are still available in buffer, but not in shortVersion.
|
||||
char *getText(char *buffer, char *shortVersion);
|
||||
protected:
|
||||
virtual void Parse() {}
|
||||
void decodeText(char *buffer);
|
||||
void decodeText(char *buffer, char *shortVersion);
|
||||
};
|
||||
|
||||
} //end of namespace
|
||||
|
27
sdt.c
27
sdt.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: sdt.c 1.7 2004/01/17 17:27:49 kls Exp $
|
||||
* $Id: sdt.c 1.8 2004/03/07 10:46:08 kls Exp $
|
||||
*/
|
||||
|
||||
#include "sdt.h"
|
||||
@ -57,34 +57,17 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
|
||||
//XXX TODO case 0x04: // NVOD reference service
|
||||
//XXX TODO case 0x05: // NVOD time-shifted service
|
||||
{
|
||||
char buffer[1024];
|
||||
char *p = sd->serviceName.getText(buffer);
|
||||
char NameBuf[1024];
|
||||
char ShortNameBuf[1024];
|
||||
char *pn = NameBuf;
|
||||
char *ps = ShortNameBuf;
|
||||
int IsShortName = 0;
|
||||
while (*p) {
|
||||
if ((uchar)*p == 0x86)
|
||||
IsShortName++;
|
||||
else if ((uchar)*p == 0x87)
|
||||
IsShortName--;
|
||||
else {
|
||||
*pn++ = *p;
|
||||
if (IsShortName)
|
||||
*ps++ = *p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
*pn = *ps = 0;
|
||||
pn = NameBuf;
|
||||
sd->serviceName.getText(NameBuf, ShortNameBuf);
|
||||
char *pn = compactspace(NameBuf);
|
||||
char *ps = compactspace(ShortNameBuf);
|
||||
if (*NameBuf && *ShortNameBuf && strcmp(NameBuf, ShortNameBuf) != 0) {
|
||||
ps = ShortNameBuf + strlen(ShortNameBuf);
|
||||
*ps++ = ',';
|
||||
strcpy(ps, NameBuf);
|
||||
pn = ShortNameBuf;
|
||||
}
|
||||
pn = compactspace(pn);
|
||||
ps = compactspace(ps);
|
||||
if (channel) {
|
||||
channel->SetId(sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
|
||||
if (Setup.UpdateChannels >= 1)
|
||||
|
Loading…
Reference in New Issue
Block a user