+int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
+{
+ int i;
+
+ if (buflen <= 0)
+ return AVERROR(EINVAL);
+ // reserve 1 byte for terminating 0
+ buflen = FFMIN(buflen - 1, maxlen);
+ for (i = 0; i < buflen; i++)
+ if (!(buf[i] = avio_r8(s)))
+ return i + 1;
+ buf[i] = 0;
+ for (; i < maxlen; i++)
+ if (!avio_r8(s))
+ return i + 1;
+ return maxlen;
+}
+
+#define GET_STR16(type, read) \
+ int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\
+{\
+ char* q = buf;\
+ int ret = 0;\
+ if (buflen <= 0) \
+ return AVERROR(EINVAL); \
+ 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, avio_rl16)
+GET_STR16(be, avio_rb16)
+
+#undef GET_STR16
+
+uint64_t avio_rb64(AVIOContext *s)