Only open iconv handlers once (during system startup) instead of every

time we parse a DVB string. Should be much faster. Also, it seems the 
dynamic loading of converters causes memory leakage.
This commit is contained in:
Andreas Öman 2008-10-14 19:15:04 +00:00
parent 448d945fdd
commit 54d29d7aaf
5 changed files with 53 additions and 28 deletions

View file

@ -19,9 +19,12 @@
#include "tvhead.h"
#include "dvb.h"
#include "dvb_support.h"
void
dvb_init(void)
{
dvb_adapter_init();
dvb_conversion_init();
}

View file

@ -35,18 +35,48 @@
#include "dvb_support.h"
#include "dvb.h"
/**
*
*/
static iconv_t convert_iso_8859[16];
static iconv_t convert_utf8;
static iconv_t convert_latin1;
static iconv_t
dvb_iconv_open(const char *srcencoding)
{
iconv_t ic;
ic = iconv_open("UTF8", srcencoding);
return ic;
}
void
dvb_conversion_init(void)
{
char buf[50];
int i;
for(i = 1; i <= 15; i++) {
snprintf(buf, sizeof(buf), "ISO_8859-%d", i);
convert_iso_8859[i] = dvb_iconv_open(buf);
}
convert_utf8 = dvb_iconv_open("UTF8");
convert_latin1 = dvb_iconv_open("LATIN1");
}
/*
* DVB String conversion according to EN 300 468, Annex A
* Not all character sets are supported, but it should cover most of them
*/
int
dvb_get_string(char *dst, size_t dstlen, const uint8_t *src,
size_t srclen, const char *target_encoding)
dvb_get_string(char *dst, size_t dstlen, const uint8_t *src, size_t srclen)
{
iconv_t ic;
const char *encoding;
char encbuf[20];
int len;
char *in, *out;
size_t inlen, outlen;
@ -65,8 +95,7 @@ dvb_get_string(char *dst, size_t dstlen, const uint8_t *src,
return -1;
case 0x01 ... 0x0b:
snprintf(encbuf, sizeof(encbuf), "ISO_8859-%d", src[0] + 4);
encoding = encbuf;
ic = convert_iso_8859[src[0]];
src++; srclen--;
break;
@ -77,8 +106,7 @@ dvb_get_string(char *dst, size_t dstlen, const uint8_t *src,
if(srclen < 3 || src[1] != 0 || src[2] == 0 || src[2] > 0x0f)
return -1;
snprintf(encbuf, sizeof(encbuf), "ISO_8859-%d", src[2]);
encoding = encbuf;
ic = convert_iso_8859[src[2]];
src+=3; srclen-=3;
break;
@ -86,14 +114,14 @@ dvb_get_string(char *dst, size_t dstlen, const uint8_t *src,
return -1;
case 0x15:
encoding = "UTF8";
ic = convert_utf8;
utf8 = 1;
break;
case 0x16 ... 0x1f:
return -1;
default:
encoding = "LATIN1"; /* Default to latin-1 */
ic = convert_latin1;
break;
}
@ -116,10 +144,8 @@ dvb_get_string(char *dst, size_t dstlen, const uint8_t *src,
}
}
ic = iconv_open(target_encoding, encoding);
if(ic == (iconv_t) -1) {
if(ic == (iconv_t) -1)
return -1;
}
inlen = srclen;
outlen = dstlen - 1;
@ -141,7 +167,6 @@ dvb_get_string(char *dst, size_t dstlen, const uint8_t *src,
}
}
iconv_close(ic);
len = dstlen - outlen - 1;
dst[len] = 0;
return 0;
@ -150,15 +175,14 @@ dvb_get_string(char *dst, size_t dstlen, const uint8_t *src,
int
dvb_get_string_with_len(char *dst, size_t dstlen,
const uint8_t *buf, size_t buflen,
const char *target_encoding)
const uint8_t *buf, size_t buflen)
{
int l = buf[0];
if(l + 1 > buflen)
return -1;
if(dvb_get_string(dst, dstlen, buf + 1, l, target_encoding))
if(dvb_get_string(dst, dstlen, buf + 1, l))
return -1;
return l + 1;

View file

@ -44,11 +44,10 @@
#define DVB_DESC_AC3 0x6a
int dvb_get_string(char *dst, size_t dstlen, const uint8_t *src,
const size_t srclen, const char *target_encoding);
const size_t srclen);
int dvb_get_string_with_len(char *dst, size_t dstlen,
const uint8_t *buf, size_t buflen,
const char *target_encoding);
const uint8_t *buf, size_t buflen);
#define bcdtoint(i) ((((i & 0xf0) >> 4) * 10) + (i & 0x0f))
@ -62,5 +61,6 @@ th_dvb_mux_instance_t *dvb_mux_find_by_identifier(const char *identifier);
void dvb_mux_nicename(char *buf, size_t size, th_dvb_mux_instance_t *tdmi);
int dvb_mux_badness(th_dvb_mux_instance_t *tdmi);
const char *dvb_mux_status(th_dvb_mux_instance_t *tdmi);
void dvb_conversion_init(void);
#endif /* DVB_SUPPORT_H */

View file

@ -232,11 +232,11 @@ dvb_desc_short_event(uint8_t *ptr, int len,
return -1;
ptr += 3; len -= 3;
if((r = dvb_get_string_with_len(title, titlelen, ptr, len, "UTF8")) < 0)
if((r = dvb_get_string_with_len(title, titlelen, ptr, len)) < 0)
return -1;
ptr += r; len -= r;
if((r = dvb_get_string_with_len(desc, desclen, ptr, len, "UTF8")) < 0)
if((r = dvb_get_string_with_len(desc, desclen, ptr, len)) < 0)
return -1;
return 0;
@ -261,13 +261,11 @@ dvb_desc_service(uint8_t *ptr, int len, uint8_t *typep,
ptr++;
len--;
if((r = dvb_get_string_with_len(provider, providerlen, ptr, len,
"UTF8")) < 0)
if((r = dvb_get_string_with_len(provider, providerlen, ptr, len)) < 0)
return -1;
ptr += r; len -= r;
if((r = dvb_get_string_with_len(name, namelen, ptr, len,
"UTF8")) < 0)
if((r = dvb_get_string_with_len(name, namelen, ptr, len)) < 0)
return -1;
ptr += r; len -= r;
return 0;
@ -736,7 +734,7 @@ dvb_nit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
switch(tag) {
case DVB_DESC_NETWORK_NAME:
if(dvb_get_string(networkname, sizeof(networkname), ptr, tlen, "UTF8"))
if(dvb_get_string(networkname, sizeof(networkname), ptr, tlen))
return;
if(strcmp(tdmi->tdmi_network ?: "", networkname))

View file

@ -93,7 +93,7 @@ autorec_cmp(dvr_autorec_entry_t *dae, event_t *e)
return 0;
}
if(dae->dae_title != NULL &&
if(dae->dae_title != NULL && e->e_title != NULL &&
regexec(&dae->dae_title_preg, e->e_title, 0, NULL, 0))
return 0;