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:
parent
5f3ad4fc9b
commit
ab308bea31
@ -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
|
||||||
|
4
HISTORY
4
HISTORY
@ -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).
|
||||||
|
@ -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;
|
||||||
|
112
libsi/si.c
112
libsi/si.c
@ -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) {
|
||||||
|
13
libsi/si.h
13
libsi/si.h
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user