1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed handling multi part ExtendedEventDescriptors where only the first part contains information about the character table

This commit is contained in:
Klaus Schmidinger 2020-05-14 21:21:03 +02:00
parent 5f3ad4fc9b
commit ab308bea31
5 changed files with 84 additions and 61 deletions

View File

@ -3589,6 +3589,8 @@ Helmut Binder <cco@aon.at>
for helping with the implementation of retuning if the received transponder's SDT for helping with the implementation of retuning if the received transponder's SDT
doesn't contain the expected values for NID and TID doesn't contain the expected values for NID and TID
for adding the language code for Bulgarian for adding the language code for Bulgarian
for a patch that was used as a base for fixing handling multi part ExtendedEventDescriptors
where only the first part contains information about the character table
Ulrich Eckhardt <uli@uli-eckhardt.de> Ulrich Eckhardt <uli@uli-eckhardt.de>
for reporting a problem with shutdown after user inactivity in case a plugin is for reporting a problem with shutdown after user inactivity in case a plugin is

View File

@ -9420,7 +9420,7 @@ Video Disk Recorder Revision History
- Fixed handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting - Fixed handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting
in "backwards compatibility mode" according to ETSI EN 300 468 (thanks to Onur Sentürk). in "backwards compatibility mode" according to ETSI EN 300 468 (thanks to Onur Sentürk).
2020-05-11: 2020-05-14:
- Fixed moving channels between number groups in SVDRP's MOVC command and the Channels - Fixed moving channels between number groups in SVDRP's MOVC command and the Channels
menu, in case a channel is moved to a higher number and into a numbered group menu, in case a channel is moved to a higher number and into a numbered group
@ -9432,3 +9432,5 @@ Video Disk Recorder Revision History
- The SVDRP command DELC now also accepts a channel id (suggested by Manuel Reimer). - The SVDRP command DELC now also accepts a channel id (suggested by Manuel Reimer).
- Fixed dropping capabilities in case cap_sys_time is not available. - Fixed dropping capabilities in case cap_sys_time is not available.
- Added the language code for Bulgarian (thanks to Helmut Binder). - Added the language code for Bulgarian (thanks to Helmut Binder).
- Fixed handling multi part ExtendedEventDescriptors where only the first part
contains information about the character table (based on a patch from Helmut Binder).

View File

@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* $Id: descriptor.c 4.1 2019/03/15 16:12:43 kls Exp $ * $Id: descriptor.c 4.2 2020/05/14 21:21:03 kls Exp $
* * * *
***************************************************************************/ ***************************************************************************/
@ -90,17 +90,21 @@ char *ExtendedEventDescriptors::getText(const char *separation1, const char *sep
} }
char *ExtendedEventDescriptors::getText(char *buffer, int size, const char *separation1, const char *separation2) { char *ExtendedEventDescriptors::getText(char *buffer, int size, const char *separation1, const char *separation2) {
int tmpsize = size;
char tmpbuf[tmpsize];
const char *fromCode = NULL;
int index=0, len; int index=0, len;
for (int i=0;i<length;i++) { for (int i=0;i<length;i++) {
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i]; ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
if (!d) if (!d)
continue; continue;
d->text.getText(buffer+index, size); d->text.getText(tmpbuf+index, tmpsize, &fromCode);
len = strlen(buffer+index); len = strlen(tmpbuf+index);
index += len; index += len;
size -= len; tmpsize -= len;
} }
index = convertCharacterTable(tmpbuf, strlen(tmpbuf), buffer, size, fromCode);
size -= index;
int sepLen1 = strlen(separation1); int sepLen1 = strlen(separation1);
int sepLen2 = strlen(separation2); int sepLen2 = strlen(separation2);
bool separated = false; bool separated = false;

View File

@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* $Id: si.c 3.3 2015/02/10 13:42:41 kls Exp $ * $Id: si.c 4.1 2020/05/14 21:21:03 kls Exp $
* * * *
***************************************************************************/ ***************************************************************************/
@ -230,14 +230,14 @@ char *String::getText() {
return data; return data;
} }
char *String::getText(char *buffer, int size) { char *String::getText(char *buffer, int size, const char **fromCode) {
int len=getLength(); int len=getLength();
if (len < 0 || len >= size) { if (len < 0 || len >= size) {
strncpy(buffer, "text error", size); strncpy(buffer, "text error", size);
buffer[size-1] = 0; buffer[size-1] = 0;
return buffer; return buffer;
} }
decodeText(buffer, size); decodeText(buffer, size, fromCode);
return buffer; return buffer;
} }
@ -386,9 +386,25 @@ const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *i
return cs; return cs;
} }
bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode) // A similar version is used in VDR/tools.c:
static int Utf8CharLen(const char *s)
{ {
if (SystemCharacterTable) { 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)
{
char *result = to;
if (SystemCharacterTable && fromCode) {
iconv_t cd = iconv_open(SystemCharacterTable, fromCode); iconv_t cd = iconv_open(SystemCharacterTable, fromCode);
if (cd != (iconv_t)-1) { if (cd != (iconv_t)-1) {
char *fromPtr = (char *)from; char *fromPtr = (char *)from;
@ -407,29 +423,44 @@ bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t
} }
*to = 0; *to = 0;
iconv_close(cd); iconv_close(cd);
return true;
} }
} }
return false; else {
} size_t len = fromLength;
if (len >= toLength)
// A similar version is used in VDR/tools.c: len = toLength - 1;
static int Utf8CharLen(const char *s) strncpy(to, from, len);
{ to[len] = 0;
if (SystemCharacterTableIsSingleByte) }
return 1; // Handle control codes:
#define MT(s, m, v) ((*(s) & (m)) == (v)) // Mask Test to = result;
if (MT(s, 0xE0, 0xC0) && MT(s + 1, 0xC0, 0x80)) size_t len = strlen(to);
return 2; while (len > 0) {
if (MT(s, 0xF0, 0xE0) && MT(s + 1, 0xC0, 0x80) && MT(s + 2, 0xC0, 0x80)) int l = Utf8CharLen(to);
return 3; if (l <= 2) {
if (MT(s, 0xF8, 0xF0) && MT(s + 1, 0xC0, 0x80) && MT(s + 2, 0xC0, 0x80) && MT(s + 3, 0xC0, 0x80)) unsigned char *p = (unsigned char *)to;
return 4; if (l == 2 && *p == 0xC2) // UTF-8 sequence
return 1; 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> // originally from libdtv, Copyright Rolf Hakenes <hakenes@hippomi.de>
void String::decodeText(char *buffer, int size) { void String::decodeText(char *buffer, int size, const char **fromCode) {
const unsigned char *from=data.getData(0); const unsigned char *from=data.getData(0);
char *to=buffer; char *to=buffer;
int len=getLength(); int len=getLength();
@ -437,38 +468,17 @@ void String::decodeText(char *buffer, int size) {
*to = '\0'; *to = '\0';
return; return;
} }
bool singleByte; const char *cs = getCharacterTable(from, len);
const char *cs = getCharacterTable(from, len, &singleByte); if (fromCode) {
if (singleByte && SystemCharacterTableIsSingleByte || !convertCharacterTable((const char *)from, len, to, size, cs)) {
if (len >= size) if (len >= size)
len = size - 1; len = size - 1;
strncpy(to, (const char *)from, len); strncpy(buffer, (const char *)from, len);
to[len] = 0; buffer[len] = 0;
if (!*fromCode)
*fromCode = cs;
} }
else else
len = strlen(to); // might have changed convertCharacterTable((const char *)from, len, to, size, cs);
// Handle control codes:
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;
}
} }
void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) { void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) {

View File

@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* $Id: si.h 3.4 2015/02/10 13:54:28 kls Exp $ * $Id: si.h 4.1 2020/05/14 21:21:03 kls Exp $
* * * *
***************************************************************************/ ***************************************************************************/
@ -508,7 +508,10 @@ public:
//so the maximum there is 256. //so the maximum there is 256.
//returns the given buffer for convenience. //returns the given buffer for convenience.
//The emphasis marks 0x86 and 0x87 are still available. //The emphasis marks 0x86 and 0x87 are still available.
char *getText(char *buffer, int size); //If fromCode is given, the string will be copied into buffer in its raw form,
//without conversion, and he code table of the string is returned in this variable
//if it is NULL.
char *getText(char *buffer, int size, const char **fromCode = NULL);
//The same semantics as for getText(char*) apply. //The same semantics as for getText(char*) apply.
//The short version of the text according to ETSI TR 101 211 (chapter 4.6) //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 //will be written into the shortVersion buffer (which should, therefore, have the same
@ -518,7 +521,7 @@ public:
char *getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion); char *getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion);
protected: protected:
virtual void Parse() {} virtual void Parse() {}
void decodeText(char *buffer, int size); void decodeText(char *buffer, int size, const char **fromCode = NULL);
void decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion); void decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion);
}; };
@ -534,7 +537,9 @@ bool SetSystemCharacterTable(const char *CharacterTable);
// default ISO6937 is returned. If a table can be determined, the buffer // default ISO6937 is returned. If a table can be determined, the buffer
// and length are adjusted accordingly. // and length are adjusted accordingly.
const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte = NULL); const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte = NULL);
bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode); // Copies 'from' to 'to' and converts characters according to 'fromCode', if given.
// Returns the length of the resulting string.
size_t convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode);
bool systemCharacterTableIsSingleByte(void); bool systemCharacterTableIsSingleByte(void);
} //end of namespace } //end of namespace