diff options
author | Nicolas George <george@nsup.org> | 2020-07-29 14:39:20 +0200 |
---|---|---|
committer | Nicolas George <george@nsup.org> | 2020-08-12 16:33:09 +0200 |
commit | d853293679f93ef882e6a5f1c47eb5a65ceddf3d (patch) | |
tree | a98280626780bd89a6d3294558667ed2bc617a27 /libavformat/url.c | |
parent | 64ff61b3c52af335e811fe04b85108775e1f2784 (diff) | |
download | ffmpeg-d853293679f93ef882e6a5f1c47eb5a65ceddf3d.tar.gz |
lavf/url: add ff_url_decompose().
Diffstat (limited to 'libavformat/url.c')
-rw-r--r-- | libavformat/url.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/libavformat/url.c b/libavformat/url.c index 20463a6674..b92409f6b2 100644 --- a/libavformat/url.c +++ b/libavformat/url.c @@ -27,6 +27,7 @@ #if CONFIG_NETWORK #include "network.h" #endif +#include "libavutil/avassert.h" #include "libavutil/avstring.h" /** @@ -78,6 +79,76 @@ int ff_url_join(char *str, int size, const char *proto, return strlen(str); } +static const char *find_delim(const char *delim, const char *cur, const char *end) +{ + while (cur < end && !strchr(delim, *cur)) + cur++; + return cur; +} + +int ff_url_decompose(URLComponents *uc, const char *url, const char *end) +{ + const char *cur, *aend, *p; + + av_assert0(url); + if (!end) + end = url + strlen(url); + cur = uc->url = url; + + /* scheme */ + uc->scheme = cur; + p = find_delim(":/", cur, end); /* lavf "schemes" can contain options */ + if (*p == ':') + cur = p + 1; + + /* authority */ + uc->authority = cur; + if (end - cur >= 2 && cur[0] == '/' && cur[1] == '/') { + cur += 2; + aend = find_delim("/?#", cur, end); + + /* userinfo */ + uc->userinfo = cur; + p = find_delim("@", cur, aend); + if (*p == '@') + cur = p + 1; + + /* host */ + uc->host = cur; + if (*cur == '[') { /* hello IPv6, thanks for using colons! */ + p = find_delim("]", cur, aend); + if (*p != ']') + return AVERROR(EINVAL); + if (p + 1 < aend && p[1] != ':') + return AVERROR(EINVAL); + cur = p + 1; + } else { + cur = find_delim(":", cur, aend); + } + + /* port */ + uc->port = cur; + cur = aend; + } else { + uc->userinfo = uc->host = uc->port = cur; + } + + /* path */ + uc->path = cur; + cur = find_delim("?#", cur, end); + + /* query */ + uc->query = cur; + if (*cur == '?') + cur = find_delim("#", cur, end); + + /* fragment */ + uc->fragment = cur; + + uc->end = end; + return 0; +} + static void trim_double_dot_url(char *buf, const char *rel, int size) { const char *p = rel; |