read and allocate a DVB string preceded by its length */
| 708 | |
| 709 | /* read and allocate a DVB string preceded by its length */ |
| 710 | static char *getstr8(const uint8_t **pp, const uint8_t *p_end) |
| 711 | { |
| 712 | int len; |
| 713 | const uint8_t *p; |
| 714 | char *str; |
| 715 | |
| 716 | p = *pp; |
| 717 | len = get8(&p, p_end); |
| 718 | if (len < 0) |
| 719 | return NULL; |
| 720 | if (len > p_end - p) |
| 721 | return NULL; |
| 722 | #if CONFIG_ICONV |
| 723 | if (len) { |
| 724 | const char *encodings[] = { |
| 725 | "ISO6937", "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", |
| 726 | "ISO-8859-8", "ISO-8859-9", "ISO-8859-10", "ISO-8859-11", |
| 727 | "", "ISO-8859-13", "ISO-8859-14", "ISO-8859-15", "", "", "", "", |
| 728 | "", "UCS-2BE", "KSC_5601", "GB2312", "UCS-2BE", "UTF-8", "", "", |
| 729 | "", "", "", "", "", "", "", "" |
| 730 | }; |
| 731 | iconv_t cd; |
| 732 | char *in, *out; |
| 733 | size_t inlen = len, outlen = inlen * 6 + 1; |
| 734 | if (len >= 3 && p[0] == 0x10 && !p[1] && p[2] && p[2] <= 0xf && p[2] != 0xc) { |
| 735 | char iso8859[12]; |
| 736 | snprintf(iso8859, sizeof(iso8859), "ISO-8859-%d", p[2]); |
| 737 | inlen -= 3; |
| 738 | in = (char *)p + 3; |
| 739 | cd = iconv_open("UTF-8", iso8859); |
| 740 | } else if (p[0] < 0x20) { |
| 741 | inlen -= 1; |
| 742 | in = (char *)p + 1; |
| 743 | cd = iconv_open("UTF-8", encodings[*p]); |
| 744 | } else { |
| 745 | in = (char *)p; |
| 746 | cd = iconv_open("UTF-8", encodings[0]); |
| 747 | } |
| 748 | if (cd == (iconv_t)-1) |
| 749 | goto no_iconv; |
| 750 | str = out = av_malloc(outlen); |
| 751 | if (!str) { |
| 752 | iconv_close(cd); |
| 753 | return NULL; |
| 754 | } |
| 755 | if (iconv(cd, &in, &inlen, &out, &outlen) == -1) { |
| 756 | iconv_close(cd); |
| 757 | av_freep(&str); |
| 758 | goto no_iconv; |
| 759 | } |
| 760 | iconv_close(cd); |
| 761 | *out = 0; |
| 762 | *pp = p + len; |
| 763 | return str; |
| 764 | } |
| 765 | no_iconv: |
| 766 | #endif |
| 767 | str = av_malloc(len + 1); |