1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
3cabdff1aSopenharmony_ci * Copyright (c) 2007 Mans Rullgard
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#include <limits.h>
23cabdff1aSopenharmony_ci#include <stdarg.h>
24cabdff1aSopenharmony_ci#include <stdint.h>
25cabdff1aSopenharmony_ci#include <stdio.h>
26cabdff1aSopenharmony_ci#include <string.h>
27cabdff1aSopenharmony_ci
28cabdff1aSopenharmony_ci#include "config.h"
29cabdff1aSopenharmony_ci#include "mem.h"
30cabdff1aSopenharmony_ci#include "avassert.h"
31cabdff1aSopenharmony_ci#include "avstring.h"
32cabdff1aSopenharmony_ci#include "bprint.h"
33cabdff1aSopenharmony_ci#include "error.h"
34cabdff1aSopenharmony_ci#include "macros.h"
35cabdff1aSopenharmony_ci#include "version.h"
36cabdff1aSopenharmony_ci
37cabdff1aSopenharmony_ciint av_strstart(const char *str, const char *pfx, const char **ptr)
38cabdff1aSopenharmony_ci{
39cabdff1aSopenharmony_ci    while (*pfx && *pfx == *str) {
40cabdff1aSopenharmony_ci        pfx++;
41cabdff1aSopenharmony_ci        str++;
42cabdff1aSopenharmony_ci    }
43cabdff1aSopenharmony_ci    if (!*pfx && ptr)
44cabdff1aSopenharmony_ci        *ptr = str;
45cabdff1aSopenharmony_ci    return !*pfx;
46cabdff1aSopenharmony_ci}
47cabdff1aSopenharmony_ci
48cabdff1aSopenharmony_ciint av_stristart(const char *str, const char *pfx, const char **ptr)
49cabdff1aSopenharmony_ci{
50cabdff1aSopenharmony_ci    while (*pfx && av_toupper((unsigned)*pfx) == av_toupper((unsigned)*str)) {
51cabdff1aSopenharmony_ci        pfx++;
52cabdff1aSopenharmony_ci        str++;
53cabdff1aSopenharmony_ci    }
54cabdff1aSopenharmony_ci    if (!*pfx && ptr)
55cabdff1aSopenharmony_ci        *ptr = str;
56cabdff1aSopenharmony_ci    return !*pfx;
57cabdff1aSopenharmony_ci}
58cabdff1aSopenharmony_ci
59cabdff1aSopenharmony_cichar *av_stristr(const char *s1, const char *s2)
60cabdff1aSopenharmony_ci{
61cabdff1aSopenharmony_ci    if (!*s2)
62cabdff1aSopenharmony_ci        return (char*)(intptr_t)s1;
63cabdff1aSopenharmony_ci
64cabdff1aSopenharmony_ci    do
65cabdff1aSopenharmony_ci        if (av_stristart(s1, s2, NULL))
66cabdff1aSopenharmony_ci            return (char*)(intptr_t)s1;
67cabdff1aSopenharmony_ci    while (*s1++);
68cabdff1aSopenharmony_ci
69cabdff1aSopenharmony_ci    return NULL;
70cabdff1aSopenharmony_ci}
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_cichar *av_strnstr(const char *haystack, const char *needle, size_t hay_length)
73cabdff1aSopenharmony_ci{
74cabdff1aSopenharmony_ci    size_t needle_len = strlen(needle);
75cabdff1aSopenharmony_ci    if (!needle_len)
76cabdff1aSopenharmony_ci        return (char*)haystack;
77cabdff1aSopenharmony_ci    while (hay_length >= needle_len) {
78cabdff1aSopenharmony_ci        hay_length--;
79cabdff1aSopenharmony_ci        if (!memcmp(haystack, needle, needle_len))
80cabdff1aSopenharmony_ci            return (char*)haystack;
81cabdff1aSopenharmony_ci        haystack++;
82cabdff1aSopenharmony_ci    }
83cabdff1aSopenharmony_ci    return NULL;
84cabdff1aSopenharmony_ci}
85cabdff1aSopenharmony_ci
86cabdff1aSopenharmony_cisize_t av_strlcpy(char *dst, const char *src, size_t size)
87cabdff1aSopenharmony_ci{
88cabdff1aSopenharmony_ci    size_t len = 0;
89cabdff1aSopenharmony_ci    while (++len < size && *src)
90cabdff1aSopenharmony_ci        *dst++ = *src++;
91cabdff1aSopenharmony_ci    if (len <= size)
92cabdff1aSopenharmony_ci        *dst = 0;
93cabdff1aSopenharmony_ci    return len + strlen(src) - 1;
94cabdff1aSopenharmony_ci}
95cabdff1aSopenharmony_ci
96cabdff1aSopenharmony_cisize_t av_strlcat(char *dst, const char *src, size_t size)
97cabdff1aSopenharmony_ci{
98cabdff1aSopenharmony_ci    size_t len = strlen(dst);
99cabdff1aSopenharmony_ci    if (size <= len + 1)
100cabdff1aSopenharmony_ci        return len + strlen(src);
101cabdff1aSopenharmony_ci    return len + av_strlcpy(dst + len, src, size - len);
102cabdff1aSopenharmony_ci}
103cabdff1aSopenharmony_ci
104cabdff1aSopenharmony_cisize_t av_strlcatf(char *dst, size_t size, const char *fmt, ...)
105cabdff1aSopenharmony_ci{
106cabdff1aSopenharmony_ci    size_t len = strlen(dst);
107cabdff1aSopenharmony_ci    va_list vl;
108cabdff1aSopenharmony_ci
109cabdff1aSopenharmony_ci    va_start(vl, fmt);
110cabdff1aSopenharmony_ci    len += vsnprintf(dst + len, size > len ? size - len : 0, fmt, vl);
111cabdff1aSopenharmony_ci    va_end(vl);
112cabdff1aSopenharmony_ci
113cabdff1aSopenharmony_ci    return len;
114cabdff1aSopenharmony_ci}
115cabdff1aSopenharmony_ci
116cabdff1aSopenharmony_cichar *av_asprintf(const char *fmt, ...)
117cabdff1aSopenharmony_ci{
118cabdff1aSopenharmony_ci    char *p = NULL;
119cabdff1aSopenharmony_ci    va_list va;
120cabdff1aSopenharmony_ci    int len;
121cabdff1aSopenharmony_ci
122cabdff1aSopenharmony_ci    va_start(va, fmt);
123cabdff1aSopenharmony_ci    len = vsnprintf(NULL, 0, fmt, va);
124cabdff1aSopenharmony_ci    va_end(va);
125cabdff1aSopenharmony_ci    if (len < 0)
126cabdff1aSopenharmony_ci        goto end;
127cabdff1aSopenharmony_ci
128cabdff1aSopenharmony_ci    p = av_malloc(len + 1);
129cabdff1aSopenharmony_ci    if (!p)
130cabdff1aSopenharmony_ci        goto end;
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci    va_start(va, fmt);
133cabdff1aSopenharmony_ci    len = vsnprintf(p, len + 1, fmt, va);
134cabdff1aSopenharmony_ci    va_end(va);
135cabdff1aSopenharmony_ci    if (len < 0)
136cabdff1aSopenharmony_ci        av_freep(&p);
137cabdff1aSopenharmony_ci
138cabdff1aSopenharmony_ciend:
139cabdff1aSopenharmony_ci    return p;
140cabdff1aSopenharmony_ci}
141cabdff1aSopenharmony_ci
142cabdff1aSopenharmony_ci#if FF_API_D2STR
143cabdff1aSopenharmony_cichar *av_d2str(double d)
144cabdff1aSopenharmony_ci{
145cabdff1aSopenharmony_ci    char *str = av_malloc(16);
146cabdff1aSopenharmony_ci    if (str)
147cabdff1aSopenharmony_ci        snprintf(str, 16, "%f", d);
148cabdff1aSopenharmony_ci    return str;
149cabdff1aSopenharmony_ci}
150cabdff1aSopenharmony_ci#endif
151cabdff1aSopenharmony_ci
152cabdff1aSopenharmony_ci#define WHITESPACES " \n\t\r"
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_cichar *av_get_token(const char **buf, const char *term)
155cabdff1aSopenharmony_ci{
156cabdff1aSopenharmony_ci    char *out     = av_malloc(strlen(*buf) + 1);
157cabdff1aSopenharmony_ci    char *ret     = out, *end = out;
158cabdff1aSopenharmony_ci    const char *p = *buf;
159cabdff1aSopenharmony_ci    if (!out)
160cabdff1aSopenharmony_ci        return NULL;
161cabdff1aSopenharmony_ci    p += strspn(p, WHITESPACES);
162cabdff1aSopenharmony_ci
163cabdff1aSopenharmony_ci    while (*p && !strspn(p, term)) {
164cabdff1aSopenharmony_ci        char c = *p++;
165cabdff1aSopenharmony_ci        if (c == '\\' && *p) {
166cabdff1aSopenharmony_ci            *out++ = *p++;
167cabdff1aSopenharmony_ci            end    = out;
168cabdff1aSopenharmony_ci        } else if (c == '\'') {
169cabdff1aSopenharmony_ci            while (*p && *p != '\'')
170cabdff1aSopenharmony_ci                *out++ = *p++;
171cabdff1aSopenharmony_ci            if (*p) {
172cabdff1aSopenharmony_ci                p++;
173cabdff1aSopenharmony_ci                end = out;
174cabdff1aSopenharmony_ci            }
175cabdff1aSopenharmony_ci        } else {
176cabdff1aSopenharmony_ci            *out++ = c;
177cabdff1aSopenharmony_ci        }
178cabdff1aSopenharmony_ci    }
179cabdff1aSopenharmony_ci
180cabdff1aSopenharmony_ci    do
181cabdff1aSopenharmony_ci        *out-- = 0;
182cabdff1aSopenharmony_ci    while (out >= end && strspn(out, WHITESPACES));
183cabdff1aSopenharmony_ci
184cabdff1aSopenharmony_ci    *buf = p;
185cabdff1aSopenharmony_ci
186cabdff1aSopenharmony_ci    return ret;
187cabdff1aSopenharmony_ci}
188cabdff1aSopenharmony_ci
189cabdff1aSopenharmony_cichar *av_strtok(char *s, const char *delim, char **saveptr)
190cabdff1aSopenharmony_ci{
191cabdff1aSopenharmony_ci    char *tok;
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_ci    if (!s && !(s = *saveptr))
194cabdff1aSopenharmony_ci        return NULL;
195cabdff1aSopenharmony_ci
196cabdff1aSopenharmony_ci    /* skip leading delimiters */
197cabdff1aSopenharmony_ci    s += strspn(s, delim);
198cabdff1aSopenharmony_ci
199cabdff1aSopenharmony_ci    /* s now points to the first non delimiter char, or to the end of the string */
200cabdff1aSopenharmony_ci    if (!*s) {
201cabdff1aSopenharmony_ci        *saveptr = NULL;
202cabdff1aSopenharmony_ci        return NULL;
203cabdff1aSopenharmony_ci    }
204cabdff1aSopenharmony_ci    tok = s++;
205cabdff1aSopenharmony_ci
206cabdff1aSopenharmony_ci    /* skip non delimiters */
207cabdff1aSopenharmony_ci    s += strcspn(s, delim);
208cabdff1aSopenharmony_ci    if (*s) {
209cabdff1aSopenharmony_ci        *s = 0;
210cabdff1aSopenharmony_ci        *saveptr = s+1;
211cabdff1aSopenharmony_ci    } else {
212cabdff1aSopenharmony_ci        *saveptr = NULL;
213cabdff1aSopenharmony_ci    }
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_ci    return tok;
216cabdff1aSopenharmony_ci}
217cabdff1aSopenharmony_ci
218cabdff1aSopenharmony_ciint av_strcasecmp(const char *a, const char *b)
219cabdff1aSopenharmony_ci{
220cabdff1aSopenharmony_ci    uint8_t c1, c2;
221cabdff1aSopenharmony_ci    do {
222cabdff1aSopenharmony_ci        c1 = av_tolower(*a++);
223cabdff1aSopenharmony_ci        c2 = av_tolower(*b++);
224cabdff1aSopenharmony_ci    } while (c1 && c1 == c2);
225cabdff1aSopenharmony_ci    return c1 - c2;
226cabdff1aSopenharmony_ci}
227cabdff1aSopenharmony_ci
228cabdff1aSopenharmony_ciint av_strncasecmp(const char *a, const char *b, size_t n)
229cabdff1aSopenharmony_ci{
230cabdff1aSopenharmony_ci    uint8_t c1, c2;
231cabdff1aSopenharmony_ci    if (n <= 0)
232cabdff1aSopenharmony_ci        return 0;
233cabdff1aSopenharmony_ci    do {
234cabdff1aSopenharmony_ci        c1 = av_tolower(*a++);
235cabdff1aSopenharmony_ci        c2 = av_tolower(*b++);
236cabdff1aSopenharmony_ci    } while (--n && c1 && c1 == c2);
237cabdff1aSopenharmony_ci    return c1 - c2;
238cabdff1aSopenharmony_ci}
239cabdff1aSopenharmony_ci
240cabdff1aSopenharmony_cichar *av_strireplace(const char *str, const char *from, const char *to)
241cabdff1aSopenharmony_ci{
242cabdff1aSopenharmony_ci    char *ret = NULL;
243cabdff1aSopenharmony_ci    const char *pstr2, *pstr = str;
244cabdff1aSopenharmony_ci    size_t tolen = strlen(to), fromlen = strlen(from);
245cabdff1aSopenharmony_ci    AVBPrint pbuf;
246cabdff1aSopenharmony_ci
247cabdff1aSopenharmony_ci    av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
248cabdff1aSopenharmony_ci    while ((pstr2 = av_stristr(pstr, from))) {
249cabdff1aSopenharmony_ci        av_bprint_append_data(&pbuf, pstr, pstr2 - pstr);
250cabdff1aSopenharmony_ci        pstr = pstr2 + fromlen;
251cabdff1aSopenharmony_ci        av_bprint_append_data(&pbuf, to, tolen);
252cabdff1aSopenharmony_ci    }
253cabdff1aSopenharmony_ci    av_bprint_append_data(&pbuf, pstr, strlen(pstr));
254cabdff1aSopenharmony_ci    if (!av_bprint_is_complete(&pbuf)) {
255cabdff1aSopenharmony_ci        av_bprint_finalize(&pbuf, NULL);
256cabdff1aSopenharmony_ci    } else {
257cabdff1aSopenharmony_ci        av_bprint_finalize(&pbuf, &ret);
258cabdff1aSopenharmony_ci    }
259cabdff1aSopenharmony_ci
260cabdff1aSopenharmony_ci    return ret;
261cabdff1aSopenharmony_ci}
262cabdff1aSopenharmony_ci
263cabdff1aSopenharmony_ciconst char *av_basename(const char *path)
264cabdff1aSopenharmony_ci{
265cabdff1aSopenharmony_ci    char *p;
266cabdff1aSopenharmony_ci#if HAVE_DOS_PATHS
267cabdff1aSopenharmony_ci    char *q, *d;
268cabdff1aSopenharmony_ci#endif
269cabdff1aSopenharmony_ci
270cabdff1aSopenharmony_ci    if (!path || *path == '\0')
271cabdff1aSopenharmony_ci        return ".";
272cabdff1aSopenharmony_ci
273cabdff1aSopenharmony_ci    p = strrchr(path, '/');
274cabdff1aSopenharmony_ci#if HAVE_DOS_PATHS
275cabdff1aSopenharmony_ci    q = strrchr(path, '\\');
276cabdff1aSopenharmony_ci    d = strchr(path, ':');
277cabdff1aSopenharmony_ci    p = FFMAX3(p, q, d);
278cabdff1aSopenharmony_ci#endif
279cabdff1aSopenharmony_ci
280cabdff1aSopenharmony_ci    if (!p)
281cabdff1aSopenharmony_ci        return path;
282cabdff1aSopenharmony_ci
283cabdff1aSopenharmony_ci    return p + 1;
284cabdff1aSopenharmony_ci}
285cabdff1aSopenharmony_ci
286cabdff1aSopenharmony_ciconst char *av_dirname(char *path)
287cabdff1aSopenharmony_ci{
288cabdff1aSopenharmony_ci    char *p = path ? strrchr(path, '/') : NULL;
289cabdff1aSopenharmony_ci
290cabdff1aSopenharmony_ci#if HAVE_DOS_PATHS
291cabdff1aSopenharmony_ci    char *q = path ? strrchr(path, '\\') : NULL;
292cabdff1aSopenharmony_ci    char *d = path ? strchr(path, ':')  : NULL;
293cabdff1aSopenharmony_ci
294cabdff1aSopenharmony_ci    d = d ? d + 1 : d;
295cabdff1aSopenharmony_ci
296cabdff1aSopenharmony_ci    p = FFMAX3(p, q, d);
297cabdff1aSopenharmony_ci#endif
298cabdff1aSopenharmony_ci
299cabdff1aSopenharmony_ci    if (!p)
300cabdff1aSopenharmony_ci        return ".";
301cabdff1aSopenharmony_ci
302cabdff1aSopenharmony_ci    *p = '\0';
303cabdff1aSopenharmony_ci
304cabdff1aSopenharmony_ci    return path;
305cabdff1aSopenharmony_ci}
306cabdff1aSopenharmony_ci
307cabdff1aSopenharmony_cichar *av_append_path_component(const char *path, const char *component)
308cabdff1aSopenharmony_ci{
309cabdff1aSopenharmony_ci    size_t p_len, c_len;
310cabdff1aSopenharmony_ci    char *fullpath;
311cabdff1aSopenharmony_ci
312cabdff1aSopenharmony_ci    if (!path)
313cabdff1aSopenharmony_ci        return av_strdup(component);
314cabdff1aSopenharmony_ci    if (!component)
315cabdff1aSopenharmony_ci        return av_strdup(path);
316cabdff1aSopenharmony_ci
317cabdff1aSopenharmony_ci    p_len = strlen(path);
318cabdff1aSopenharmony_ci    c_len = strlen(component);
319cabdff1aSopenharmony_ci    if (p_len > SIZE_MAX - c_len || p_len + c_len > SIZE_MAX - 2)
320cabdff1aSopenharmony_ci        return NULL;
321cabdff1aSopenharmony_ci    fullpath = av_malloc(p_len + c_len + 2);
322cabdff1aSopenharmony_ci    if (fullpath) {
323cabdff1aSopenharmony_ci        if (p_len) {
324cabdff1aSopenharmony_ci            av_strlcpy(fullpath, path, p_len + 1);
325cabdff1aSopenharmony_ci            if (c_len) {
326cabdff1aSopenharmony_ci                if (fullpath[p_len - 1] != '/' && component[0] != '/')
327cabdff1aSopenharmony_ci                    fullpath[p_len++] = '/';
328cabdff1aSopenharmony_ci                else if (fullpath[p_len - 1] == '/' && component[0] == '/')
329cabdff1aSopenharmony_ci                    p_len--;
330cabdff1aSopenharmony_ci            }
331cabdff1aSopenharmony_ci        }
332cabdff1aSopenharmony_ci        av_strlcpy(&fullpath[p_len], component, c_len + 1);
333cabdff1aSopenharmony_ci        fullpath[p_len + c_len] = 0;
334cabdff1aSopenharmony_ci    }
335cabdff1aSopenharmony_ci    return fullpath;
336cabdff1aSopenharmony_ci}
337cabdff1aSopenharmony_ci
338cabdff1aSopenharmony_ciint av_escape(char **dst, const char *src, const char *special_chars,
339cabdff1aSopenharmony_ci              enum AVEscapeMode mode, int flags)
340cabdff1aSopenharmony_ci{
341cabdff1aSopenharmony_ci    AVBPrint dstbuf;
342cabdff1aSopenharmony_ci    int ret;
343cabdff1aSopenharmony_ci
344cabdff1aSopenharmony_ci    av_bprint_init(&dstbuf, 1, INT_MAX); /* (int)dstbuf.len must be >= 0 */
345cabdff1aSopenharmony_ci    av_bprint_escape(&dstbuf, src, special_chars, mode, flags);
346cabdff1aSopenharmony_ci
347cabdff1aSopenharmony_ci    if (!av_bprint_is_complete(&dstbuf)) {
348cabdff1aSopenharmony_ci        av_bprint_finalize(&dstbuf, NULL);
349cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
350cabdff1aSopenharmony_ci    }
351cabdff1aSopenharmony_ci    if ((ret = av_bprint_finalize(&dstbuf, dst)) < 0)
352cabdff1aSopenharmony_ci        return ret;
353cabdff1aSopenharmony_ci    return dstbuf.len;
354cabdff1aSopenharmony_ci}
355cabdff1aSopenharmony_ci
356cabdff1aSopenharmony_ciint av_match_name(const char *name, const char *names)
357cabdff1aSopenharmony_ci{
358cabdff1aSopenharmony_ci    const char *p;
359cabdff1aSopenharmony_ci    int len, namelen;
360cabdff1aSopenharmony_ci
361cabdff1aSopenharmony_ci    if (!name || !names)
362cabdff1aSopenharmony_ci        return 0;
363cabdff1aSopenharmony_ci
364cabdff1aSopenharmony_ci    namelen = strlen(name);
365cabdff1aSopenharmony_ci    while (*names) {
366cabdff1aSopenharmony_ci        int negate = '-' == *names;
367cabdff1aSopenharmony_ci        p = strchr(names, ',');
368cabdff1aSopenharmony_ci        if (!p)
369cabdff1aSopenharmony_ci            p = names + strlen(names);
370cabdff1aSopenharmony_ci        names += negate;
371cabdff1aSopenharmony_ci        len = FFMAX(p - names, namelen);
372cabdff1aSopenharmony_ci        if (!av_strncasecmp(name, names, len) || !strncmp("ALL", names, FFMAX(3, p - names)))
373cabdff1aSopenharmony_ci            return !negate;
374cabdff1aSopenharmony_ci        names = p + (*p == ',');
375cabdff1aSopenharmony_ci    }
376cabdff1aSopenharmony_ci    return 0;
377cabdff1aSopenharmony_ci}
378cabdff1aSopenharmony_ci
379cabdff1aSopenharmony_ciint av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end,
380cabdff1aSopenharmony_ci                   unsigned int flags)
381cabdff1aSopenharmony_ci{
382cabdff1aSopenharmony_ci    const uint8_t *p = *bufp;
383cabdff1aSopenharmony_ci    uint32_t top;
384cabdff1aSopenharmony_ci    uint64_t code;
385cabdff1aSopenharmony_ci    int ret = 0, tail_len;
386cabdff1aSopenharmony_ci    uint32_t overlong_encoding_mins[6] = {
387cabdff1aSopenharmony_ci        0x00000000, 0x00000080, 0x00000800, 0x00010000, 0x00200000, 0x04000000,
388cabdff1aSopenharmony_ci    };
389cabdff1aSopenharmony_ci
390cabdff1aSopenharmony_ci    if (p >= buf_end)
391cabdff1aSopenharmony_ci        return 0;
392cabdff1aSopenharmony_ci
393cabdff1aSopenharmony_ci    code = *p++;
394cabdff1aSopenharmony_ci
395cabdff1aSopenharmony_ci    /* first sequence byte starts with 10, or is 1111-1110 or 1111-1111,
396cabdff1aSopenharmony_ci       which is not admitted */
397cabdff1aSopenharmony_ci    if ((code & 0xc0) == 0x80 || code >= 0xFE) {
398cabdff1aSopenharmony_ci        ret = AVERROR(EILSEQ);
399cabdff1aSopenharmony_ci        goto end;
400cabdff1aSopenharmony_ci    }
401cabdff1aSopenharmony_ci    top = (code & 128) >> 1;
402cabdff1aSopenharmony_ci
403cabdff1aSopenharmony_ci    tail_len = 0;
404cabdff1aSopenharmony_ci    while (code & top) {
405cabdff1aSopenharmony_ci        int tmp;
406cabdff1aSopenharmony_ci        tail_len++;
407cabdff1aSopenharmony_ci        if (p >= buf_end) {
408cabdff1aSopenharmony_ci            (*bufp) ++;
409cabdff1aSopenharmony_ci            return AVERROR(EILSEQ); /* incomplete sequence */
410cabdff1aSopenharmony_ci        }
411cabdff1aSopenharmony_ci
412cabdff1aSopenharmony_ci        /* we assume the byte to be in the form 10xx-xxxx */
413cabdff1aSopenharmony_ci        tmp = *p++ - 128;   /* strip leading 1 */
414cabdff1aSopenharmony_ci        if (tmp>>6) {
415cabdff1aSopenharmony_ci            (*bufp) ++;
416cabdff1aSopenharmony_ci            return AVERROR(EILSEQ);
417cabdff1aSopenharmony_ci        }
418cabdff1aSopenharmony_ci        code = (code<<6) + tmp;
419cabdff1aSopenharmony_ci        top <<= 5;
420cabdff1aSopenharmony_ci    }
421cabdff1aSopenharmony_ci    code &= (top << 1) - 1;
422cabdff1aSopenharmony_ci
423cabdff1aSopenharmony_ci    /* check for overlong encodings */
424cabdff1aSopenharmony_ci    av_assert0(tail_len <= 5);
425cabdff1aSopenharmony_ci    if (code < overlong_encoding_mins[tail_len]) {
426cabdff1aSopenharmony_ci        ret = AVERROR(EILSEQ);
427cabdff1aSopenharmony_ci        goto end;
428cabdff1aSopenharmony_ci    }
429cabdff1aSopenharmony_ci
430cabdff1aSopenharmony_ci    if (code >= 1U<<31) {
431cabdff1aSopenharmony_ci        ret = AVERROR(EILSEQ);  /* out-of-range value */
432cabdff1aSopenharmony_ci        goto end;
433cabdff1aSopenharmony_ci    }
434cabdff1aSopenharmony_ci
435cabdff1aSopenharmony_ci    *codep = code;
436cabdff1aSopenharmony_ci
437cabdff1aSopenharmony_ci    if (code > 0x10FFFF &&
438cabdff1aSopenharmony_ci        !(flags & AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES))
439cabdff1aSopenharmony_ci        ret = AVERROR(EILSEQ);
440cabdff1aSopenharmony_ci    if (code < 0x20 && code != 0x9 && code != 0xA && code != 0xD &&
441cabdff1aSopenharmony_ci        flags & AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES)
442cabdff1aSopenharmony_ci        ret = AVERROR(EILSEQ);
443cabdff1aSopenharmony_ci    if (code >= 0xD800 && code <= 0xDFFF &&
444cabdff1aSopenharmony_ci        !(flags & AV_UTF8_FLAG_ACCEPT_SURROGATES))
445cabdff1aSopenharmony_ci        ret = AVERROR(EILSEQ);
446cabdff1aSopenharmony_ci    if ((code == 0xFFFE || code == 0xFFFF) &&
447cabdff1aSopenharmony_ci        !(flags & AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS))
448cabdff1aSopenharmony_ci        ret = AVERROR(EILSEQ);
449cabdff1aSopenharmony_ci
450cabdff1aSopenharmony_ciend:
451cabdff1aSopenharmony_ci    *bufp = p;
452cabdff1aSopenharmony_ci    return ret;
453cabdff1aSopenharmony_ci}
454cabdff1aSopenharmony_ci
455cabdff1aSopenharmony_ciint av_match_list(const char *name, const char *list, char separator)
456cabdff1aSopenharmony_ci{
457cabdff1aSopenharmony_ci    const char *p, *q;
458cabdff1aSopenharmony_ci
459cabdff1aSopenharmony_ci    for (p = name; p && *p; ) {
460cabdff1aSopenharmony_ci        for (q = list; q && *q; ) {
461cabdff1aSopenharmony_ci            int k;
462cabdff1aSopenharmony_ci            for (k = 0; p[k] == q[k] || (p[k]*q[k] == 0 && p[k]+q[k] == separator); k++)
463cabdff1aSopenharmony_ci                if (k && (!p[k] || p[k] == separator))
464cabdff1aSopenharmony_ci                    return 1;
465cabdff1aSopenharmony_ci            q = strchr(q, separator);
466cabdff1aSopenharmony_ci            q += !!q;
467cabdff1aSopenharmony_ci        }
468cabdff1aSopenharmony_ci        p = strchr(p, separator);
469cabdff1aSopenharmony_ci        p += !!p;
470cabdff1aSopenharmony_ci    }
471cabdff1aSopenharmony_ci
472cabdff1aSopenharmony_ci    return 0;
473cabdff1aSopenharmony_ci}
474