124 const unsigned char *end=p+len-it.
i;
143 const unsigned char *end=p+len-it.
i;
145 for (
int u=0; u<arrayLength;u++)
194 for (
int i=0;i<
length;i++)
205 for (
int i=0;i<
length;i++)
209 if (length <= d->getDescriptorNumber())
216 for (
int i=0;i<
length;i++)
224 if (len < 0 || len > 4095)
225 return strdup(
"text error");
226 char *
data=
new char(len+1);
235 if (len < 0 || len >= size) {
236 strncpy(buffer,
"text error", size);
244 char *
String::getText(
char *buffer,
char *shortVersion,
int sizeBuffer,
int sizeShortVersion) {
246 if (len < 0 || len >= sizeBuffer) {
247 strncpy(buffer,
"text error", sizeBuffer);
248 buffer[sizeBuffer-1] = 0;
252 decodeText(buffer, shortVersion, sizeBuffer, sizeShortVersion);
291 #define SingleByteLimit 0x0B
312 #define NumEntries(Table) (sizeof(Table) / sizeof(char *))
331 if (cd != (iconv_t)-1) {
345 char a[] =
"ä ;
char *pa = a;
char b[10];
char *pb = b;
size_t la = strlen(a);
size_t lb = sizeof(b);
iconv_t cd = iconv_open(SystemCharacterTable, "ISO-8859-1");
if (cd != (iconv_t)-1) {
if (iconv(cd, &pa, &la, &pb, &lb) != size_t(-1)) {
*pb = 0;
SystemCharacterTableIsSingleByte = strlen(b) == 1;
}
iconv_close(cd);
return true;
}
}
return false;
}
const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte) {
const char *cs = "ISO6937";
// Workaround for broadcaster stupidity: according to
// "ETSI EN 300 468" the default character set is ISO6937. But unfortunately some
// broadcasters actually use ISO-8859-9, but fail to correctly announce that.
if (OverrideCharacterTable)
cs = OverrideCharacterTable;
if (isSingleByte)
*isSingleByte = false;
if (length <= 0)
return cs;
unsigned int tag = buffer[0];
if (tag >= 0x20)
return cs;
if (tag == 0x10) {
if (length >= 3) {
tag = (buffer[1] << 8) | buffer[2];
if (tag < NumEntries(CharacterTables2) && CharacterTables2[tag]) {
buffer += 3;
length -= 3;
if (isSingleByte)
*isSingleByte = true;
return CharacterTables2[tag];
}
}
} else if (tag < NumEntries(CharacterTables1) && CharacterTables1[tag]) {
buffer += 1;
length -= 1;
if (isSingleByte)
*isSingleByte = tag <= SingleByteLimit;
return CharacterTables1[tag];
}
return cs;
}
// A similar version is used in VDR/tools.c:
static int Utf8CharLen(const char *s)
{
if (SystemCharacterTableIsSingleByte)
return 1;
#define MT(s, m, v) ((*(s) & (m)) == (v)) // Mask Test
if (MT(s, 0xE0, 0xC0) && MT(s + 1, 0xC0, 0x80))
return 2;
if (MT(s, 0xF0, 0xE0) && MT(s + 1, 0xC0, 0x80) && MT(s + 2, 0xC0, 0x80))
return 3;
if (MT(s, 0xF8, 0xF0) && MT(s + 1, 0xC0, 0x80) && MT(s + 2, 0xC0, 0x80) && MT(s + 3, 0xC0, 0x80))
return 4;
return 1;
}
size_t convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode)
{
bool converted = false;
char *result = to;
if (SystemCharacterTable && fromCode) {
iconv_t cd = iconv_open(SystemCharacterTable, fromCode);
if (cd != (iconv_t)-1) {
char *fromPtr = (char *)from;
while (fromLength > 0 && toLength > 1) {
if (iconv(cd, &fromPtr, &fromLength, &to, &toLength) == size_t(-1)) {
if (errno == EILSEQ) {
// A character can't be converted, so mark it with '?' and proceed:
fromPtr++;
fromLength--;
*to++ = '?';
toLength--;
}
else
break;
}
}
*to = 0;
iconv_close(cd);
converted = true;
}
}
if (!converted) {
size_t len = fromLength;
if (len >= toLength)
len = toLength - 1;
strncpy(to, from, len);
to[len] = 0;
}
// Handle control codes:
to = result;
size_t len = strlen(to);
while (len > 0) {
int l = Utf8CharLen(to);
if (l <= 2) {
unsigned char *p = (unsigned char *)to;
if (l == 2 && *p == 0xC2) // UTF-8 sequence
p++;
bool Move = true;
switch (*p) {
case 0x8A: *to = '\n'; break;
case 0xA0: *to = ' '; break;
default: Move = false;
}
if (l == 2 && Move) {
memmove(p, p + 1, len - 1); // we also copy the terminating 0!
len -= 1;
l = 1;
}
}
to += l;
len -= l;
}
return strlen(result);
}
// originally from libdtv, Copyright Rolf Hakenes <hakenes@hippomi.de>
void String::decodeText(char *buffer, int size, const char **fromCode) {
const unsigned char *from=data.getData(0);
char *to=buffer;
int len=getLength();
if (len <= 0) {
*to = '\0';
return;
}
const char *cs = getCharacterTable(from, len);
if (fromCode) {
if (len >= size)
len = size - 1;
strncpy(buffer, (const char *)from, len);
buffer[len] = 0;
if (!*fromCode)
*fromCode = cs;
}
else
convertCharacterTable((const char *)from, len, to, size, cs);
}
void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) {
decodeText(buffer, sizeBuffer);
if (!*buffer) {
*shortVersion = '\0';
return;
}
// Handle control codes:
char *to=buffer;
int len=strlen(to);
int IsShortName=0;
while (len > 0) {
int l = Utf8CharLen(to);
unsigned char *p = (unsigned char *)to;
if (l == 2 && *p == 0xC2) // UTF-8 sequence
p++;
if (*p == 0x86 || *p == 0x87) {
IsShortName += (*p == 0x86) ? 1 : -1;
memmove(to, to + l, len - l + 1); // we also copy the terminating 0!
len -= l;
l = 0;
}
if (l && IsShortName) {
if (l < sizeShortVersion) {
for (int i = 0; i < l; i++)
*shortVersion++ = to[i];
sizeShortVersion -= l;
}
}
to += l;
len -= l;
}
*shortVersion = '\0';
}
Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor) {
Descriptor *d=0;
switch (domain) {
case SI:
switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) {
case CaDescriptorTag:
d=new CaDescriptor();
break;
case CarouselIdentifierDescriptorTag:
d=new CarouselIdentifierDescriptor();
break;
case AVCDescriptorTag:
d=new AVCDescriptor();
break;
case NetworkNameDescriptorTag:
d=new NetworkNameDescriptor();
break;
case ServiceListDescriptorTag:
d=new ServiceListDescriptor();
break;
case SatelliteDeliverySystemDescriptorTag:
d=new SatelliteDeliverySystemDescriptor();
break;
case CableDeliverySystemDescriptorTag:
d=new CableDeliverySystemDescriptor();
break;
case TerrestrialDeliverySystemDescriptorTag:
d=new TerrestrialDeliverySystemDescriptor();
break;
case BouquetNameDescriptorTag:
d=new BouquetNameDescriptor();
break;
case ServiceDescriptorTag:
d=new ServiceDescriptor();
break;
case NVODReferenceDescriptorTag:
d=new NVODReferenceDescriptor();
break;
case TimeShiftedServiceDescriptorTag:
d=new TimeShiftedServiceDescriptor();
break;
case ComponentDescriptorTag:
d=new ComponentDescriptor();
break;
case StreamIdentifierDescriptorTag:
d=new StreamIdentifierDescriptor();
break;
case SubtitlingDescriptorTag:
d=new SubtitlingDescriptor();
break;
case MultilingualNetworkNameDescriptorTag:
d=new MultilingualNetworkNameDescriptor();
break;
case MultilingualBouquetNameDescriptorTag:
d=new MultilingualBouquetNameDescriptor();
break;
case MultilingualServiceNameDescriptorTag:
d=new MultilingualServiceNameDescriptor();
break;
case MultilingualComponentDescriptorTag:
d=new MultilingualComponentDescriptor();
break;
case PrivateDataSpecifierDescriptorTag:
d=new PrivateDataSpecifierDescriptor();
break;
case ServiceMoveDescriptorTag:
d=new ServiceMoveDescriptor();
break;
case FrequencyListDescriptorTag:
d=new FrequencyListDescriptor();
break;
case ServiceIdentifierDescriptorTag:
d=new ServiceIdentifierDescriptor();
break;
case CaIdentifierDescriptorTag:
d=new CaIdentifierDescriptor();
break;
case ShortEventDescriptorTag:
d=new ShortEventDescriptor();
break;
case ExtendedEventDescriptorTag:
d=new ExtendedEventDescriptor();
break;
case TimeShiftedEventDescriptorTag:
d=new TimeShiftedEventDescriptor();
break;
case ContentDescriptorTag:
d=new ContentDescriptor();
break;
case ParentalRatingDescriptorTag:
d=new ParentalRatingDescriptor();
break;
case TeletextDescriptorTag:
case VBITeletextDescriptorTag:
d=new TeletextDescriptor();
break;
case ApplicationSignallingDescriptorTag:
d=new ApplicationSignallingDescriptor();
break;
case LocalTimeOffsetDescriptorTag:
d=new LocalTimeOffsetDescriptor();
break;
case LinkageDescriptorTag:
d=new LinkageDescriptor();
break;
case ISO639LanguageDescriptorTag:
d=new ISO639LanguageDescriptor();
break;
case PDCDescriptorTag:
d=new PDCDescriptor();
break;
case AncillaryDataDescriptorTag:
d=new AncillaryDataDescriptor();
break;
case S2SatelliteDeliverySystemDescriptorTag:
d=new S2SatelliteDeliverySystemDescriptor();
break;
case ExtensionDescriptorTag:
d=new ExtensionDescriptor();
break;
case LogicalChannelDescriptorTag:
d=new LogicalChannelDescriptor();
break;
case HdSimulcastLogicalChannelDescriptorTag:
d=new HdSimulcastLogicalChannelDescriptor();
break;
case RegistrationDescriptorTag:
d=new RegistrationDescriptor();
break;
case ContentIdentifierDescriptorTag:
d=new ContentIdentifierDescriptor();
break;
case DefaultAuthorityDescriptorTag:
d=new DefaultAuthorityDescriptor();
break;
//note that it is no problem to implement one
//of the unimplemented descriptors.
//defined in ISO-13818-1
case VideoStreamDescriptorTag:
case AudioStreamDescriptorTag:
case HierarchyDescriptorTag:
case DataStreamAlignmentDescriptorTag:
case TargetBackgroundGridDescriptorTag:
case VideoWindowDescriptorTag:
case SystemClockDescriptorTag:
case MultiplexBufferUtilizationDescriptorTag:
case CopyrightDescriptorTag:
case MaximumBitrateDescriptorTag:
case PrivateDataIndicatorDescriptorTag:
case SmoothingBufferDescriptorTag:
case STDDescriptorTag:
case IBPDescriptorTag:
//defined in ETSI EN 300 468
case StuffingDescriptorTag:
case VBIDataDescriptorTag:
case CountryAvailabilityDescriptorTag:
case MocaicDescriptorTag:
case TelephoneDescriptorTag:
case CellListDescriptorTag:
case CellFrequencyLinkDescriptorTag:
case ServiceAvailabilityDescriptorTag:
case ShortSmoothingBufferDescriptorTag:
case PartialTransportStreamDescriptorTag:
case DataBroadcastDescriptorTag:
case DataBroadcastIdDescriptorTag:
case ScramblingDescriptorTag:
case AC3DescriptorTag:
case DSNGDescriptorTag:
case AnnouncementSupportDescriptorTag:
case AdaptationFieldDataDescriptorTag:
case TransportStreamDescriptorTag:
//defined in ETSI EN 300 468 v 1.7.1
case RelatedContentDescriptorTag:
case TVAIdDescriptorTag:
case TimeSliceFecIdentifierDescriptorTag:
case ECMRepetitionRateDescriptorTag:
case EnhancedAC3DescriptorTag:
case DTSDescriptorTag:
case AACDescriptorTag:
default:
if (!returnUnimplemetedDescriptor)
return 0;
d=new UnimplementedDescriptor();
break;
}
break;
case MHP:
switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) {
// They once again start with 0x00 (see page 234, MHP specification)
case MHP_ApplicationDescriptorTag:
d=new MHP_ApplicationDescriptor();
break;
case MHP_ApplicationNameDescriptorTag:
d=new MHP_ApplicationNameDescriptor();
break;
case MHP_TransportProtocolDescriptorTag:
d=new MHP_TransportProtocolDescriptor();
break;
case MHP_DVBJApplicationDescriptorTag:
d=new MHP_DVBJApplicationDescriptor();
break;
case MHP_DVBJApplicationLocationDescriptorTag:
d=new MHP_DVBJApplicationLocationDescriptor();
break;
case MHP_SimpleApplicationLocationDescriptorTag:
d=new MHP_SimpleApplicationLocationDescriptor();
break;
// 0x05 - 0x0A is unimplemented this library
case MHP_ExternalApplicationAuthorisationDescriptorTag:
case MHP_IPv4RoutingDescriptorTag:
case MHP_IPv6RoutingDescriptorTag:
case MHP_DVBHTMLApplicationDescriptorTag:
case MHP_DVBHTMLApplicationLocationDescriptorTag:
case MHP_DVBHTMLApplicationBoundaryDescriptorTag:
case MHP_ApplicationIconsDescriptorTag:
case MHP_PrefetchDescriptorTag:
case MHP_DelegatedApplicationDescriptorTag:
case MHP_ApplicationStorageDescriptorTag:
default:
if (!returnUnimplemetedDescriptor)
return 0;
d=new UnimplementedDescriptor();
break;
}
break;
case PCIT:
switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) {
case ContentDescriptorTag:
d=new ContentDescriptor();
break;
case ShortEventDescriptorTag:
d=new ShortEventDescriptor();
break;
case ExtendedEventDescriptorTag:
d=new ExtendedEventDescriptor();
break;
case PremiereContentTransmissionDescriptorTag:
d=new PremiereContentTransmissionDescriptor();
break;
default:
if (!returnUnimplemetedDescriptor)
return 0;
d=new UnimplementedDescriptor();
break;
}
break;
default: ; // unknown domain, nothing to do
}
d->setData(da);
return d;
}
} //end of namespace
";
349 size_t la = strlen(a);
350 size_t lb =
sizeof(b);
352 if (cd != (iconv_t)-1) {
353 if (iconv(cd, &pa, &la, &pb, &lb) !=
size_t(-1)) {
365 const char *cs =
"ISO6937";
372 *isSingleByte =
false;
375 unsigned int tag = buffer[0];
380 tag = (buffer[1] << 8) | buffer[2];
385 *isSingleByte =
true;
404 #define MT(s, m, v) ((*(s) & (m)) == (v))
405 if (
MT(s, 0xE0, 0xC0) &&
MT(s + 1, 0xC0, 0x80))
407 if (
MT(s, 0xF0, 0xE0) &&
MT(s + 1, 0xC0, 0x80) &&
MT(s + 2, 0xC0, 0x80))
409 if (
MT(s, 0xF8, 0xF0) &&
MT(s + 1, 0xC0, 0x80) &&
MT(s + 2, 0xC0, 0x80) &&
MT(s + 3, 0xC0, 0x80))
416 bool converted =
false;
420 if (cd != (iconv_t)-1) {
421 char *fromPtr = (
char *)from;
422 while (fromLength > 0 && toLength > 1) {
423 if (iconv(cd, &fromPtr, &fromLength, &to, &toLength) == size_t(-1)) {
424 if (errno == EILSEQ) {
441 size_t len = fromLength;
444 strncpy(to, from, len);
449 size_t len = strlen(to);
453 unsigned char *p = (
unsigned char *)to;
454 if (l == 2 && *p == 0xC2)
458 case 0x8A: *to =
'\n';
break;
459 case 0xA0: *to =
' ';
break;
460 default: Move =
false;
462 if (l == 2 && Move) {
463 memmove(p, p + 1, len - 1);
471 return strlen(result);
487 strncpy(buffer, (
const char *)from, len);
499 *shortVersion =
'\0';
508 unsigned char *p = (
unsigned char *)to;
509 if (l == 2 && *p == 0xC2)
511 if (*p == 0x86 || *p == 0x87) {
512 IsShortName += (*p == 0x86) ? 1 : -1;
513 memmove(to, to + l, len - l + 1);
517 if (l && IsShortName) {
518 if (l < sizeShortVersion) {
519 for (
int i = 0; i < l; i++)
520 *shortVersion++ = to[i];
521 sizeShortVersion -= l;
527 *shortVersion =
'\0';
714 if (!returnUnimplemetedDescriptor)
753 if (!returnUnimplemetedDescriptor)
774 if (!returnUnimplemetedDescriptor)
void assign(const unsigned char *data, int size, bool doCopy=true)
const unsigned char * getData() const
bool checkSize(int offset)
bool Add(GroupDescriptor *d)
bool deleteOnDesctruction
DescriptorGroup(bool deleteOnDesctruction=true)
int getNumberOfDescriptors()
DescriptorTagDomain domain
Descriptor * getNext(Iterator &it)
Descriptor * createDescriptor(int &i, bool returnUnimplemetedDescriptor)
DescriptorTag getDescriptorTag() const
static Descriptor * getDescriptor(CharArray d, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor)
virtual int getLastDescriptorNumber()=0
virtual int getDescriptorNumber()=0
int getTableIdExtension() const
bool getCurrentNextIndicator() const
int getSectionNumber() const
int getLastSectionNumber() const
int getVersionNumber() const
void setData(const unsigned char *data, int size, bool doCopy=true)
bool checkSize(int offset)
TableId getTableId() const
void decodeText(char *buffer, int size, const char **fromCode=NULL)
static const char * CharacterTables2[]
static int Utf8CharLen(const char *s)
const char * getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte)
bool SetSystemCharacterTable(const char *CharacterTable)
size_t convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode)
bool SystemCharacterTableIsSingleByte
bool systemCharacterTableIsSingleByte(void)
@ AudioStreamDescriptorTag
@ ECMRepetitionRateDescriptorTag
@ MHP_PrefetchDescriptorTag
@ MHP_SimpleApplicationLocationDescriptorTag
@ StreamIdentifierDescriptorTag
@ VideoWindowDescriptorTag
@ MultiplexBufferUtilizationDescriptorTag
@ RelatedContentDescriptorTag
@ MultilingualComponentDescriptorTag
@ NVODReferenceDescriptorTag
@ EnhancedAC3DescriptorTag
@ ServiceMoveDescriptorTag
@ PrivateDataSpecifierDescriptorTag
@ ScramblingDescriptorTag
@ PartialTransportStreamDescriptorTag
@ CountryAvailabilityDescriptorTag
@ CarouselIdentifierDescriptorTag
@ DataBroadcastDescriptorTag
@ ExtendedEventDescriptorTag
@ VBITeletextDescriptorTag
@ S2SatelliteDeliverySystemDescriptorTag
@ MHP_DVBHTMLApplicationDescriptorTag
@ CableDeliverySystemDescriptorTag
@ ShortEventDescriptorTag
@ PrivateDataIndicatorDescriptorTag
@ ServiceAvailabilityDescriptorTag
@ MaximumBitrateDescriptorTag
@ CaIdentifierDescriptorTag
@ TransportStreamDescriptorTag
@ HdSimulcastLogicalChannelDescriptorTag
@ MHP_DelegatedApplicationDescriptorTag
@ TimeShiftedServiceDescriptorTag
@ ServiceIdentifierDescriptorTag
@ MultilingualNetworkNameDescriptorTag
@ MHP_ApplicationIconsDescriptorTag
@ ShortSmoothingBufferDescriptorTag
@ PremiereContentTransmissionDescriptorTag
@ DataStreamAlignmentDescriptorTag
@ LocalTimeOffsetDescriptorTag
@ TargetBackgroundGridDescriptorTag
@ MultilingualServiceNameDescriptorTag
@ MHP_ExternalApplicationAuthorisationDescriptorTag
@ MHP_TransportProtocolDescriptorTag
@ MHP_DVBHTMLApplicationBoundaryDescriptorTag
@ VideoStreamDescriptorTag
@ SubtitlingDescriptorTag
@ ISO639LanguageDescriptorTag
@ DefaultAuthorityDescriptorTag
@ MHP_ApplicationStorageDescriptorTag
@ AncillaryDataDescriptorTag
@ MHP_DVBJApplicationLocationDescriptorTag
@ TimeSliceFecIdentifierDescriptorTag
@ MultilingualBouquetNameDescriptorTag
@ SystemClockDescriptorTag
@ ServiceListDescriptorTag
@ MHP_IPv4RoutingDescriptorTag
@ MHP_IPv6RoutingDescriptorTag
@ ParentalRatingDescriptorTag
@ DataBroadcastIdDescriptorTag
@ NetworkNameDescriptorTag
@ RegistrationDescriptorTag
@ SatelliteDeliverySystemDescriptorTag
@ CellFrequencyLinkDescriptorTag
@ SmoothingBufferDescriptorTag
@ MHP_DVBJApplicationDescriptorTag
@ AdaptationFieldDataDescriptorTag
@ MHP_DVBHTMLApplicationLocationDescriptorTag
@ MHP_ApplicationDescriptorTag
@ BouquetNameDescriptorTag
@ FrequencyListDescriptorTag
@ ApplicationSignallingDescriptorTag
@ TerrestrialDeliverySystemDescriptorTag
@ TimeShiftedEventDescriptorTag
@ LogicalChannelDescriptorTag
@ AnnouncementSupportDescriptorTag
@ MHP_ApplicationNameDescriptorTag
@ ContentIdentifierDescriptorTag
static char * SystemCharacterTable
static char * OverrideCharacterTable
bool SetOverrideCharacterTable(const char *CharacterTable)
static const char * CharacterTables1[]
#define NumEntries(Table)