From 54d29d7aaf9b19d198574874b13b8a1d2bc8914e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Tue, 14 Oct 2008 19:15:04 +0000 Subject: [PATCH] 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. --- dvb/dvb.c | 3 +++ dvb/dvb_support.c | 58 +++++++++++++++++++++++++++++++++-------------- dvb/dvb_support.h | 6 ++--- dvb/dvb_tables.c | 12 ++++------ dvr/dvr_autorec.c | 2 +- 5 files changed, 53 insertions(+), 28 deletions(-) diff --git a/dvb/dvb.c b/dvb/dvb.c index 824672a6..8ef90076 100644 --- a/dvb/dvb.c +++ b/dvb/dvb.c @@ -19,9 +19,12 @@ #include "tvhead.h" #include "dvb.h" +#include "dvb_support.h" void dvb_init(void) { dvb_adapter_init(); + dvb_conversion_init(); + } diff --git a/dvb/dvb_support.c b/dvb/dvb_support.c index 571fbf42..a1a505c2 100644 --- a/dvb/dvb_support.c +++ b/dvb/dvb_support.c @@ -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; diff --git a/dvb/dvb_support.h b/dvb/dvb_support.h index 1fc11367..984344b3 100644 --- a/dvb/dvb_support.h +++ b/dvb/dvb_support.h @@ -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 */ diff --git a/dvb/dvb_tables.c b/dvb/dvb_tables.c index c75b5fa3..d5a632a0 100644 --- a/dvb/dvb_tables.c +++ b/dvb/dvb_tables.c @@ -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)) diff --git a/dvr/dvr_autorec.c b/dvr/dvr_autorec.c index fefa228d..24f99934 100644 --- a/dvr/dvr_autorec.c +++ b/dvr/dvr_autorec.c @@ -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;