From f9d6b13a234022ee752a973102c6e4207f74f94c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 23 Jan 2011 12:38:27 +0100 Subject: [PATCH] lavf: make a variant of ff_get_str16_nolen public It will be useful in mp3 demuxer and hopeful some other places. Signed-off-by: Janne Grunau (cherry picked from commit 93b78d12106112d7c5d9cfdcf96fc3dce9dc5f82) --- libavformat/asfdec.c | 30 ++++++++++-------------------- libavformat/avio.h | 9 +++++++++ libavformat/aviobuf.c | 22 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 6ae4e99326..3ce37dc59e 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -121,21 +121,6 @@ static void get_str16(ByteIOContext *pb, char *buf, int buf_size) } #endif -static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size) -{ - char* q = buf; - while (len > 1) { - uint8_t tmp; - uint32_t ch; - - GET_UTF16(ch, (len -= 2) >= 0 ? get_le16(pb) : 0, break;) - PUT_UTF8(ch, tmp, if (q - buf < buf_size - 1) *q++ = tmp;) - } - if (len > 0) - url_fskip(pb, len); - *q = '\0'; -} - static int asf_probe(AVProbeData *pd) { /* check file header */ @@ -167,7 +152,7 @@ static void get_tag(AVFormatContext *s, const char *key, int type, int len) return; if (type == 0) { // UTF16-LE - get_str16_nolen(s->pb, len, value, 2*len + 1); + avio_get_str16le(s->pb, len, value, 2*len + 1); } else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD uint64_t num = get_value(s->pb, type); snprintf(value, len, "%"PRIu64, num); @@ -206,6 +191,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid)); for(;;) { uint64_t gpos= url_ftell(pb); + int ret; ff_get_guid(pb, &g); gsize = get_le64(pb); dprintf(s, "%08"PRIx64": ", gpos); @@ -447,7 +433,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) for(j = 0; j < stream_count; j++) { char lang[6]; unsigned int lang_len = get_byte(pb); - get_str16_nolen(pb, lang_len, lang, sizeof(lang)); + if ((ret = avio_get_str16le(pb, lang_len, lang, sizeof(lang))) < lang_len) + url_fskip(pb, lang_len - ret); if (j < 128) av_strlcpy(asf->stream_languages[j], lang, sizeof(*asf->stream_languages)); } @@ -462,7 +449,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) name_len = get_le16(pb); if (name_len%2) // must be even, broken lavf versions wrote len-1 name_len += 1; - get_str16_nolen(pb, name_len, name, sizeof(name)); + if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len) + url_fskip(pb, name_len - ret); value_type = get_le16(pb); value_len = get_le16(pb); if (!value_type && value_len%2) @@ -491,7 +479,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) value_type= get_le16(pb); value_len= get_le32(pb); - get_str16_nolen(pb, name_len, name, sizeof(name)); + if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len) + url_fskip(pb, name_len - ret); //av_log(s, AV_LOG_ERROR, "%d %d %d %d %d <%s>\n", i, stream_num, name_len, value_type, value_len, name); value_num= get_le16(pb);//we should use get_value() here but it does not work 2 is le16 here but le32 elsewhere url_fskip(pb, value_len - 2); @@ -574,7 +563,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) get_le32(pb); // send time get_le32(pb); // flags name_len = get_le32(pb); // name length - get_str16_nolen(pb, name_len * 2, name, sizeof(name)); + if ((ret = avio_get_str16le(pb, name_len * 2, name, sizeof(name))) < name_len) + url_fskip(pb, name_len - ret); ff_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name ); } #if 0 diff --git a/libavformat/avio.h b/libavformat/avio.h index b35d4c716c..a606f7cb97 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -460,6 +460,15 @@ unsigned int get_le32(ByteIOContext *s); uint64_t get_le64(ByteIOContext *s); unsigned int get_le16(ByteIOContext *s); +/** + * Read a UTF-16 string from pb and convert it to UTF-8. + * The reading will terminate when either a null or invalid character was + * encountered or maxlen bytes have been read. + * @return number of bytes read (is always <= maxlen) + */ +int avio_get_str16le(ByteIOContext *pb, int maxlen, char *buf, int buflen); +int avio_get_str16be(ByteIOContext *pb, int maxlen, char *buf, int buflen); + char *get_strz(ByteIOContext *s, char *buf, int maxlen); unsigned int get_be16(ByteIOContext *s); unsigned int get_be24(ByteIOContext *s); diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 5aeced1b9f..acea8111d9 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -602,6 +602,28 @@ int ff_get_line(ByteIOContext *s, char *buf, int maxlen) return i; } +#define GET_STR16(type, read) \ + int avio_get_str16 ##type(ByteIOContext *pb, int maxlen, char *buf, int buflen)\ +{\ + char* q = buf;\ + int ret = 0;\ + while (ret + 1 < maxlen) {\ + uint8_t tmp;\ + uint32_t ch;\ + GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\ + if (!ch)\ + break;\ + PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\ + }\ + *q = 0;\ + return ret;\ +}\ + +GET_STR16(le, get_le16) +GET_STR16(be, get_be16) + +#undef GET_STR16 + uint64_t get_be64(ByteIOContext *s) { uint64_t val;