diff --git a/src/dvb/dvb_support.c b/src/dvb/dvb_support.c index 3526e115..b102fcd4 100644 --- a/src/dvb/dvb_support.c +++ b/src/dvb/dvb_support.c @@ -29,8 +29,6 @@ #include #include -#include - #include #include "tvhead.h" @@ -197,16 +195,18 @@ dvb_get_string_with_len(char *dst, size_t dstlen, void atsc_utf16_to_utf8(uint8_t *src, int len, char *buf, int buflen) { - int i, c; - char *q = buf; + int i, c, r; for(i = 0; i < len; i++) { - uint8_t tmp; c = (src[i * 2 + 0] << 8) | src[i * 2 + 1]; - PUT_UTF8(c, tmp, if (q - buf < buflen - 1) *q++ = tmp;) + if(buflen >= 7) { + r = put_utf8(buf, c); + buf += r; + buflen -= r; + } } - *q = 0; + *buf = 0; } diff --git a/src/htsmsg_xml.c b/src/htsmsg_xml.c index fd44a9af..9324d723 100644 --- a/src/htsmsg_xml.c +++ b/src/htsmsg_xml.c @@ -50,7 +50,7 @@ #include #include -#include +#include "tvhead.h" #include "htsmsg_xml.h" #include "htsbuf.h" @@ -106,18 +106,19 @@ static void add_unicode(struct cdata_content_queue *ccq, int c) { cdata_content_t *cc; - char *q; - uint8_t tmp; + int r; cc = malloc(sizeof(cdata_content_t) + 6); - cc->cc_encoding = XML_ENCODING_UTF8; - q = cc->cc_buf; + r = put_utf8(cc->cc_buf, c); + if(r == 0) { + free(cc); + return; + } + cc->cc_encoding = XML_ENCODING_UTF8; TAILQ_INSERT_TAIL(ccq, cc, cc_link); cc->cc_start = cc->cc_buf; - - PUT_UTF8(c, tmp, *q++ = tmp;) - cc->cc_end = q; + cc->cc_end = cc->cc_buf + r; } /** @@ -665,10 +666,8 @@ htsmsg_xml_parse_cd(xmlparser_t *xp, htsmsg_t *parent, char *src) htsmsg_field_t *f; cdata_content_t *cc; int c = 0, l, y = 0; - char *body; - char *x; + char *x, *body; htsmsg_t *tags = htsmsg_create_map(); - uint8_t tmp; TAILQ_INIT(&ccq); src = htsmsg_xml_parse_cd0(xp, &ccq, tags, NULL, src, 0); @@ -722,9 +721,8 @@ htsmsg_xml_parse_cd(xmlparser_t *xp, htsmsg_t *parent, char *src) break; case XML_ENCODING_8859_1: - for(x = cc->cc_start; x < cc->cc_end; x++) { - PUT_UTF8(*x, tmp, body[c++] = tmp;) - } + for(x = cc->cc_start; x < cc->cc_end; x++) + body += put_utf8(body, *x); break; } diff --git a/src/tvhead.h b/src/tvhead.h index 8a39173c..10d9925e 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -840,4 +840,6 @@ uint32_t crc32(uint8_t *data, size_t datalen, uint32_t crc); int base64_decode(uint8_t *out, const char *in, int out_size); +int put_utf8(char *out, int c); + #endif /* TV_HEAD_H */ diff --git a/src/utils.c b/src/utils.c index 9a92c54c..0b117eac 100644 --- a/src/utils.c +++ b/src/utils.c @@ -136,3 +136,57 @@ base64_decode(uint8_t *out, const char *in, int out_size) return dst - out; } + + +/** + * + */ +int +put_utf8(char *out, int c) +{ + if(c == 0xfffe || c == 0xffff || (c >= 0xD800 && c < 0xE000)) + return 0; + + if (c < 0x80) { + *out = c; + return 1; + } + + if(c < 0x800) { + *out++ = 0xc0 | (0x1f & (c >> 6)); + *out = 0x80 | (0x3f & c); + return 2; + } + + if(c < 0x10000) { + *out++ = 0xe0 | (0x0f & (c >> 12)); + *out++ = 0x80 | (0x3f & (c >> 6)); + *out = 0x80 | (0x3f & c); + return 3; + } + + if(c < 0x200000) { + *out++ = 0xf0 | (0x07 & (c >> 18)); + *out++ = 0x80 | (0x3f & (c >> 12)); + *out++ = 0x80 | (0x3f & (c >> 6)); + *out = 0x80 | (0x3f & c); + return 4; + } + + if(c < 0x4000000) { + *out++ = 0xf8 | (0x03 & (c >> 24)); + *out++ = 0x80 | (0x3f & (c >> 18)); + *out++ = 0x80 | (0x3f & (c >> 12)); + *out++ = 0x80 | (0x3f & (c >> 6)); + *out++ = 0x80 | (0x3f & c); + return 5; + } + + *out++ = 0xfc | (0x01 & (c >> 30)); + *out++ = 0x80 | (0x3f & (c >> 24)); + *out++ = 0x80 | (0x3f & (c >> 18)); + *out++ = 0x80 | (0x3f & (c >> 12)); + *out++ = 0x80 | (0x3f & (c >> 6)); + *out++ = 0x80 | (0x3f & c); + return 6; +}