summaryrefslogtreecommitdiff
path: root/libavformat/url.c
diff options
context:
space:
mode:
authorNicolas George <george@nsup.org>2020-07-29 14:39:20 +0200
committerNicolas George <george@nsup.org>2020-08-12 16:33:09 +0200
commitd853293679f93ef882e6a5f1c47eb5a65ceddf3d (patch)
treea98280626780bd89a6d3294558667ed2bc617a27 /libavformat/url.c
parent64ff61b3c52af335e811fe04b85108775e1f2784 (diff)
downloadffmpeg-d853293679f93ef882e6a5f1c47eb5a65ceddf3d.tar.gz
lavf/url: add ff_url_decompose().
Diffstat (limited to 'libavformat/url.c')
-rw-r--r--libavformat/url.c71
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;