summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS2
-rw-r--r--HISTORY4
-rw-r--r--libsi/descriptor.c14
-rw-r--r--libsi/si.c112
-rw-r--r--libsi/si.h13
5 files changed, 84 insertions, 61 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 6bd3af04..f085eeba 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -3589,6 +3589,8 @@ Helmut Binder <cco@aon.at>
for helping with the implementation of retuning if the received transponder's SDT
doesn't contain the expected values for NID and TID
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>
for reporting a problem with shutdown after user inactivity in case a plugin is
diff --git a/HISTORY b/HISTORY
index b136e7c2..fafad735 100644
--- a/HISTORY
+++ b/HISTORY
@@ -9420,7 +9420,7 @@ Video Disk Recorder Revision History
- Fixed handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting
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
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).
- Fixed dropping capabilities in case cap_sys_time is not available.
- 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).
diff --git a/libsi/descriptor.c b/libsi/descriptor.c
index 6b00fc77..a94c0035 100644
--- a/libsi/descriptor.c
+++ b/libsi/descriptor.c
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (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) {
+ int tmpsize = size;
+ char tmpbuf[tmpsize];
+ const char *fromCode = NULL;
int index=0, len;
for (int i=0;i<length;i++) {
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
if (!d)
continue;
- d->text.getText(buffer+index, size);
- len = strlen(buffer+index);
+ d->text.getText(tmpbuf+index, tmpsize, &fromCode);
+ len = strlen(tmpbuf+index);
index += len;
- size -= len;
+ tmpsize -= len;
}
-
+ index = convertCharacterTable(tmpbuf, strlen(tmpbuf), buffer, size, fromCode);
+ size -= index;
int sepLen1 = strlen(separation1);
int sepLen2 = strlen(separation2);
bool separated = false;
diff --git a/libsi/si.c b/libsi/si.c
index e51770ab..c294c2fc 100644
--- a/libsi/si.c
+++ b/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 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;
}
-char *String::getText(char *buffer, int size) {
+char *String::getText(char *buffer, int size, const char **fromCode) {
int len=getLength();
if (len < 0 || len >= size) {
strncpy(buffer, "text error", size);
buffer[size-1] = 0;
return buffer;
}
- decodeText(buffer, size);
+ decodeText(buffer, size, fromCode);
return buffer;
}
@@ -386,9 +386,25 @@ const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *i
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 (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)
{
- if (SystemCharacterTable) {
+ char *result = to;
+ if (SystemCharacterTable && fromCode) {
iconv_t cd = iconv_open(SystemCharacterTable, fromCode);
if (cd != (iconv_t)-1) {
char *fromPtr = (char *)from;
@@ -407,29 +423,44 @@ bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t
}
*to = 0;
iconv_close(cd);
- return true;
}
}
- return false;
-}
-
-// 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;
+ else {
+ 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) {
+void String::decodeText(char *buffer, int size, const char **fromCode) {
const unsigned char *from=data.getData(0);
char *to=buffer;
int len=getLength();
@@ -437,38 +468,17 @@ void String::decodeText(char *buffer, int size) {
*to = '\0';
return;
}
- bool singleByte;
- const char *cs = getCharacterTable(from, len, &singleByte);
- if (singleByte && SystemCharacterTableIsSingleByte || !convertCharacterTable((const char *)from, len, to, size, cs)) {
+ const char *cs = getCharacterTable(from, len);
+ if (fromCode) {
if (len >= size)
len = size - 1;
- strncpy(to, (const char *)from, len);
- to[len] = 0;
+ strncpy(buffer, (const char *)from, len);
+ buffer[len] = 0;
+ if (!*fromCode)
+ *fromCode = cs;
}
else
- len = strlen(to); // might have changed
- // 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;
- }
+ convertCharacterTable((const char *)from, len, to, size, cs);
}
void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) {
diff --git a/libsi/si.h b/libsi/si.h
index e70de685..c5f426ef 100644
--- a/libsi/si.h
+++ b/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 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.
//returns the given buffer for convenience.
//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 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
@@ -518,7 +521,7 @@ public:
char *getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion);
protected:
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);
};
@@ -534,7 +537,9 @@ bool SetSystemCharacterTable(const char *CharacterTable);
// default ISO6937 is returned. If a table can be determined, the buffer
// and length are adjusted accordingly.
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);
} //end of namespace