# HG changeset patch # User mstorsjo # Date 1267828305 0 # Node ID dbc61b2840eb9dbca56daec098eaa5257fadde0d # Parent 65b77d0674d02dc9726a8f683c15db2945f37d88 Add a function ff_url_join for assembling URLs diff -r 65b77d0674d0 -r dbc61b2840eb avformat.h --- a/avformat.h Fri Mar 05 22:30:21 2010 +0000 +++ b/avformat.h Fri Mar 05 22:31:45 2010 +0000 @@ -1350,6 +1350,30 @@ char *path, int path_size, const char *url); +/** + * Assembles a URL string from components. This is the reverse operation + * of url_split. + * + * Note, this requires networking to be initialized, so the caller must + * ensure ff_network_init has been called. + * + * @see url_split + * + * @param str the buffer to fill with the url + * @param size the size of the str buffer + * @param proto the protocol identifier, if null, the separator + * after the identifier is left out, too + * @param authorization an optional authorization string, may be null + * @param hostname the host name string + * @param port the port number, left out from the string if negative + * @param fmt a generic format string for everything to add after the + * host/port, may be null + * @return the number of characters written to the destination buffer + */ +int ff_url_join(char *str, int size, const char *proto, + const char *authorization, const char *hostname, + int port, const char *fmt, ...); + #if LIBAVFORMAT_VERSION_MAJOR < 53 /** * @deprecated Use av_match_ext() instead. diff -r 65b77d0674d0 -r dbc61b2840eb utils.c --- a/utils.c Fri Mar 05 22:30:21 2010 +0000 +++ b/utils.c Fri Mar 05 22:31:45 2010 +0000 @@ -27,6 +27,10 @@ #include #include #include +#include +#if CONFIG_NETWORK +#include "network.h" +#endif #undef NDEBUG #include @@ -3446,3 +3450,48 @@ if(!s->time_base.num || !s->time_base.den) s->time_base.num= s->time_base.den= 0; } + +int ff_url_join(char *str, int size, const char *proto, + const char *authorization, const char *hostname, + int port, const char *fmt, ...) +{ +#if CONFIG_NETWORK + struct addrinfo hints, *ai; +#endif + + str[0] = '\0'; + if (proto) + av_strlcatf(str, size, "%s://", proto); + if (authorization) + av_strlcatf(str, size, "%s@", authorization); +#if CONFIG_NETWORK && defined(AF_INET6) + /* Determine if hostname is a numerical IPv6 address, + * properly escape it within [] in that case. */ + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_NUMERICHOST; + if (!getaddrinfo(hostname, NULL, &hints, &ai)) { + if (ai->ai_family == AF_INET6) { + av_strlcat(str, "[", size); + av_strlcat(str, hostname, size); + av_strlcat(str, "]", size); + } else { + av_strlcat(str, hostname, size); + } + freeaddrinfo(ai); + } else +#endif + /* Not an IPv6 address, just output the plain string. */ + av_strlcat(str, hostname, size); + + if (port >= 0) + av_strlcatf(str, size, ":%d", port); + if (fmt) { + va_list vl; + int len = strlen(str); + + va_start(vl, fmt); + vsnprintf(str + len, size > len ? size - len : 0, fmt, vl); + va_end(vl); + } + return strlen(str); +}