From a5921252942f73601b159f20b560477ec45b4ece Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 22 Apr 2007 18:00:00 +0200 Subject: =?UTF-8?q?Version=201.5.2=20-=20Updated=20the=20Finnish=20OSD=20t?= =?UTF-8?q?exts=20(thanks=20to=20Rolf=20Ahrenberg).=20-=20Fixed=20handling?= =?UTF-8?q?=20user=20activity=20for=20shutdown,=20which=20I=20had=20messed?= =?UTF-8?q?=20when=20adopting=20Udo's=20=20=20original=20patch=20(thanks?= =?UTF-8?q?=20to=20Udo=20Richter).=20-=20Added=20Turkish=20language=20text?= =?UTF-8?q?s=20(thanks=20to=20Oktay=20Yolge=C3=A7en).=20-=20Added=20missin?= =?UTF-8?q?g=20rules=20for=20generating=20iso8859-13=20font=20to=20Makefil?= =?UTF-8?q?e.=20-=20'libsi'=20now=20converts=20the=20incoming=20strings=20?= =?UTF-8?q?into=20the=20system's=20character=20set=20=20=20according=20to?= =?UTF-8?q?=20the=20DVB=20standard.=20The=20system's=20character=20set=20i?= =?UTF-8?q?s=20determined=20from=20=20=20the=20LANG=20environment=20variab?= =?UTF-8?q?le.=20If=20no=20recognizable=20setting=20can=20be=20found,=20no?= =?UTF-8?q?=20=20=20conversion=20will=20take=20place.=20Note=20that=20curr?= =?UTF-8?q?ently=20only=20the=20strings=20received=20from=20the=20=20=20SI?= =?UTF-8?q?=20data=20stream=20are=20converted,=20there=20have=20not=20been?= =?UTF-8?q?=20any=20changes=20regarding=20displaying=20=20=20UTF-8=20chara?= =?UTF-8?q?cters=20on=20the=20OSD,=20yet=20-=20this=20will=20follow=20in?= =?UTF-8?q?=20one=20of=20the=20next=20steps.=20=20=20With=20this=20convers?= =?UTF-8?q?ion,=20it=20should=20now=20be=20safe=20to=20run=20VDR=20on=20a?= =?UTF-8?q?=20UTF-8=20file=20system,=20=20=20because=20all=20incoming=20ch?= =?UTF-8?q?aracters=20are=20converted=20to=20UTF-8.=20This=20will=20most?= =?UTF-8?q?=20likely=20=20=20result=20in=20wrong=20characters=20being=20di?= =?UTF-8?q?splayed=20on=20the=20OSD=20(because=20there=20UTF-8=20is=20=20?= =?UTF-8?q?=20not=20known,=20yet),=20but=20the=20file=20names=20should=20b?= =?UTF-8?q?e=20ok=20(haven't=20tested=20this=20myself,=20=20=20though,=20b?= =?UTF-8?q?ecause=20I=20don't=20do=20UTF-8=20-=20so=20please=20be=20very?= =?UTF-8?q?=20careful=20when=20testing!).=20=20=20There's=20one=20piece=20?= =?UTF-8?q?of=20bad=20news=20here:=20the=20German=20pay-tv=20broadcaster?= =?UTF-8?q?=20Premiere=20=20=20apparently=20encodes=20all=20EPG=20strings?= =?UTF-8?q?=20as=20ISO8859-1,=20but=20fails=20to=20correctly=20mark=20=20?= =?UTF-8?q?=20these=20strings=20as=20such.=20Therefore=20'libsi'=20(follow?= =?UTF-8?q?ing=20the=20DVB=20standard)=20considers=20=20=20the=20strings?= =?UTF-8?q?=20to=20be=20encoded=20in=20the=20default=20ISO6937=20and=20con?= =?UTF-8?q?verts=20them=20to=20whatever=20=20=20the=20system's=20character?= =?UTF-8?q?=20set=20is.=20This,=20of=20course,=20results=20in=20wrong=20um?= =?UTF-8?q?lauts.=20=20=20On=20its=20old=20transponder,=20the=20ProSieben/?= =?UTF-8?q?SAT.1=20channels=20also=20had=20their=20EPG=20data=20=20=20wron?= =?UTF-8?q?gly=20encoded,=20but=20apparently=20on=20the=20new=20transponde?= =?UTF-8?q?r=20they=20started=20broadcasting=20=20=20on=20this=20month,=20?= =?UTF-8?q?they=20got=20it=20right.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libsi/si.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ libsi/si.h | 7 ++- 2 files changed, 184 insertions(+), 19 deletions(-) (limited to 'libsi') diff --git a/libsi/si.c b/libsi/si.c index a16000d..a1d2f34 100644 --- a/libsi/si.c +++ b/libsi/si.c @@ -6,12 +6,15 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.c 1.17 2007/02/03 11:45:58 kls Exp $ + * $Id: si.c 1.18 2007/04/22 13:56:39 kls Exp $ * * ***************************************************************************/ -#include #include "si.h" +#include +#include +#include +#include #include "descriptor.h" namespace SI { @@ -232,7 +235,6 @@ char *String::getText(char *buffer, int size) { return buffer; } -//taken from VDR, Copyright Klaus Schmidinger char *String::getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) { int len=getLength(); if (len < 0 || len >= sizeBuffer) { @@ -245,21 +247,163 @@ char *String::getText(char *buffer, char *shortVersion, int sizeBuffer, int size return buffer; } -//taken from libdtv, Copyright Rolf Hakenes +static const char *CharacterTables1[] = { + NULL, // 0x00 + "ISO8859-5", // 0x01 + "ISO8859-6", // 0x02 + "ISO8859-7", // 0x03 + "ISO8859-8", // 0x04 + "ISO8859-9", // 0x05 + "ISO8859-10", // 0x06 + "ISO8859-11", // 0x07 + "ISO8859-12", // 0x08 + "ISO8859-13", // 0x09 + "ISO8859-14", // 0x0A + "ISO8859-15", // 0x0B + NULL, // 0x0C + NULL, // 0x0D + NULL, // 0x0E + NULL, // 0x0F + NULL, // 0x10 + "UTF16", // 0x11 + "EUC-KR", // 0x12 + "GB2312", // 0x13 + "GBK", // 0x14 + "UTF8", // 0x15 + NULL, // 0x16 + NULL, // 0x17 + NULL, // 0x18 + NULL, // 0x19 + NULL, // 0x1A + NULL, // 0x1B + NULL, // 0x1C + NULL, // 0x1D + NULL, // 0x1E + NULL, // 0x1F +}; + +#define SingleByteLimit 0x0B + +static const char *CharacterTables2[] = { + NULL, // 0x00 + "ISO8859-1", // 0x01 + "ISO8859-2", // 0x02 + "ISO8859-3", // 0x03 + "ISO8859-4", // 0x04 + "ISO8859-5", // 0x05 + "ISO8859-6", // 0x06 + "ISO8859-7", // 0x07 + "ISO8859-8", // 0x08 + "ISO8859-9", // 0x09 + "ISO8859-10", // 0x0A + "ISO8859-11", // 0x0B + NULL, // 0x0C + "ISO8859-13", // 0x0D + "ISO8859-14", // 0x0E + "ISO8859-15", // 0x0F +}; + +#define NumEntries(Table) (sizeof(Table) / sizeof(char *)) + +static const char *SystemCharacterTable = NULL; +bool SystemCharacterTableIsSingleByte = true; + +bool SetSystemCharacterTable(const char *CharacterTable) { + if (CharacterTable) { + for (unsigned int i = 0; i < NumEntries(CharacterTables1); i++) { + if (CharacterTables1[i] && strcasecmp(CharacterTable, CharacterTables1[i]) == 0) { + SystemCharacterTable = CharacterTables1[i]; + SystemCharacterTableIsSingleByte = i <= SingleByteLimit; + return true; + } + } + for (unsigned int i = 0; i < NumEntries(CharacterTables2); i++) { + if (CharacterTables2[i] && strcasecmp(CharacterTable, CharacterTables2[i]) == 0) { + SystemCharacterTable = CharacterTables2[i]; + SystemCharacterTableIsSingleByte = true; + return true; + } + } + } else { + SystemCharacterTable = NULL; + SystemCharacterTableIsSingleByte = true; + return true; + } + return false; +} + +// Determines the character table used in the given buffer and returns +// a string indicating that table. If no table can be determined, the +// default ISO6937 is returned. If a table can be determined, the buffer +// and length are adjusted accordingly. +static const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte = NULL) { + const char *cs = "ISO6937"; + 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; +} + +static bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode) +{ + if (SystemCharacterTable) { + iconv_t cd = iconv_open(SystemCharacterTable, fromCode); + if (cd >= 0) { + 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); + return true; + } + } + return false; +} + +// originally from libdtv, Copyright Rolf Hakenes void String::decodeText(char *buffer, int size) { const unsigned char *from=data.getData(0); char *to=buffer; - - /* Disable detection of coding tables - libdtv doesn't do it either - if ( (0x01 <= *from) && (*from <= 0x1f) ) { - codeTable=*from - } - */ - - if (*from == 0x10) - from += 3; // skips code table info - int len=getLength(); + if (len <= 0) { + *to = '\0'; + return; + } + bool singleByte; + const char *cs = getCharacterTable(from, len, &singleByte); for (int i = 0; i < len; i++) { if (*from == 0) break; @@ -276,6 +420,11 @@ void String::decodeText(char *buffer, int size) { break; } *to = '\0'; + if (!singleByte || !SystemCharacterTableIsSingleByte) { + char convBuffer[size]; + if (convertCharacterTable(buffer, strlen(buffer), convBuffer, sizeof(convBuffer), cs)) + strncpy(buffer, convBuffer, strlen(convBuffer) + 1); + } } void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) { @@ -283,11 +432,14 @@ void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int si char *to=buffer; char *toShort=shortVersion; int IsShortName=0; - - if (*from == 0x10) - from += 3; // skips code table info - int len=getLength(); + if (len <= 0) { + *to = '\0'; + *toShort = '\0'; + return; + } + bool singleByte; + const char *cs = getCharacterTable(from, len, &singleByte); for (int i = 0; i < len; i++) { if ( ((' ' <= *from) && (*from <= '~')) || (*from == '\n') @@ -312,6 +464,14 @@ void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int si } *to = '\0'; *toShort = '\0'; + if (!singleByte || !SystemCharacterTableIsSingleByte) { + char convBuffer[sizeBuffer]; + if (convertCharacterTable(buffer, strlen(buffer), convBuffer, sizeof(convBuffer), cs)) + strncpy(buffer, convBuffer, strlen(convBuffer) + 1); + char convShortVersion[sizeShortVersion]; + if (convertCharacterTable(shortVersion, strlen(shortVersion), convShortVersion, sizeof(convShortVersion), cs)) + strncpy(shortVersion, convShortVersion, strlen(convShortVersion) + 1); + } } Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor) { diff --git a/libsi/si.h b/libsi/si.h index eb01609..a156d76 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 1.16 2007/02/03 11:47:25 kls Exp $ + * $Id: si.h 1.17 2007/04/22 13:32:09 kls Exp $ * * ***************************************************************************/ @@ -486,6 +486,11 @@ protected: void decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion); }; +// Call this function to set the system character table. CharacterTable is a string +// like "iso8859-15" or "utf-8" (case insensitive). +// Returns true if the character table was recognized. +bool SetSystemCharacterTable(const char *CharacterTable); + } //end of namespace #endif //LIBSI_SI_H -- cgit v1.2.3