From cc112d8fcbdebb49fbad1e92bc9029cf2a6ced0a Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sun, 10 May 2009 15:23:18 +0300 Subject: [PATCH] make_URI: make a URI out of a path, if needed --- include/vlc_url.h | 1 + src/libvlccore.sym | 1 + src/text/strings.c | 107 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 96 insertions(+), 13 deletions(-) diff --git a/include/vlc_url.h b/include/vlc_url.h index 271e4d2702..448c685435 100644 --- a/include/vlc_url.h +++ b/include/vlc_url.h @@ -50,6 +50,7 @@ VLC_EXPORT( void, unescape_URI, ( char *psz ) ); VLC_EXPORT( char *, decode_URI_duplicate, ( const char *psz ) ); VLC_EXPORT( char *, decode_URI, ( char *psz ) ); VLC_EXPORT( char *, encode_URI_component, ( const char *psz ) ); +VLC_EXPORT( char *, make_URI, ( const char *path ) ); /***************************************************************************** * vlc_UrlParse: diff --git a/src/libvlccore.sym b/src/libvlccore.sym index ac68b0e2e3..d72c10f805 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -216,6 +216,7 @@ libvlc_InternalInit libvlc_InternalWait libvlc_Quit LocaleFree +make_URI mdate module_config_free module_config_get diff --git a/src/text/strings.c b/src/text/strings.c index 4eea72fd16..860aae7c22 100644 --- a/src/text/strings.c +++ b/src/text/strings.c @@ -2,6 +2,7 @@ * strings.c: String related functions ***************************************************************************** * Copyright (C) 2006 the VideoLAN team + * Copyright (C) 2008-2009 Rémi Denis-Courmont * $Id$ * * Authors: Antoine Cellerier @@ -203,23 +204,13 @@ static inline bool isurisafe( int c ) || ( strchr( "-._~", c ) != NULL ); } -/** - * Encodes an URI component (RFC3986 §2). - * - * @param psz_uri nul-terminated UTF-8 representation of the component. - * Obviously, you can't pass an URI containing a nul character, but you don't - * want to do that, do you? - * - * @return encoded string (must be free()'d), or NULL for ENOMEM. - */ -char *encode_URI_component( const char *psz_uri ) +static char *encode_URI_bytes (const char *psz_uri, size_t len) { - char *psz_enc = malloc ((3 * strlen (psz_uri)) + 1), *out = psz_enc; - + char *psz_enc = malloc (3 * len + 1), *out = psz_enc; if (psz_enc == NULL) return NULL; - while (*psz_uri) + for (size_t i = 0; i < len; i++) { static const char hex[16] = "0123456789ABCDEF"; uint8_t c = *psz_uri; @@ -242,6 +233,21 @@ char *encode_URI_component( const char *psz_uri ) return out ? out : psz_enc; /* realloc() can fail (safe) */ } +/** + * Encodes an URI component (RFC3986 §2). + * + * @param psz_uri nul-terminated UTF-8 representation of the component. + * Obviously, you can't pass an URI containing a nul character, but you don't + * want to do that, do you? + * + * @return encoded string (must be free()'d), or NULL for ENOMEM. + */ +char *encode_URI_component( const char *psz_uri ) +{ + return encode_URI_bytes (psz_uri, strlen (psz_uri)); +} + + static const struct xml_entity_s { char psz_entity[8]; @@ -1130,3 +1136,78 @@ void path_sanitize( char *str ) str++; } } + +#include + +/** + * Convert a file path to an URI. If already an URI, do nothing. + */ +char *make_URI (const char *path) +{ + if (path == NULL) + return NULL; + if (strstr (path, "://") != NULL) + return strdup (path); /* Already an URI */ + /* Note: VLC cannot handle URI schemes without double slash after the + * scheme name (such as mailto: or news:). */ + + char *buf; +#ifdef WIN32 + if (isalpha (path[0]) && (path[1] == ':')) + { + if (asprintf (&buf, "file:///%c:", path[0]) == -1) + buf = NULL; + path += 2; + } + else +#endif +#if 0 + /* Windows UNC paths (file://host/share/path instead of file:///path) */ + if (!strncmp (path, "\\\\", 2)) + { + path += 2; + buf = strdup ("file://"); + } + else +#endif + if (path[0] != DIR_SEP_CHAR) + { /* Relative path: prepend the current working directory */ + char cwd[PATH_MAX]; + + if (getcwd (cwd, sizeof (cwd)) == NULL) /* FIXME: UTF8? */ + return NULL; + if (asprintf (&buf, "%s/%s", cwd, path) == -1) + return NULL; + char *ret = make_URI (buf); + free (buf); + return ret; + } + else + buf = strdup ("file://"); + if (buf == NULL) + return NULL; + + assert (path[0] == DIR_SEP_CHAR); + + /* Absolute file path */ + for (const char *ptr = path + 1;; ptr++) + { + size_t len = strcspn (ptr, DIR_SEP); + char *component = encode_URI_bytes (ptr, len); + if (component == NULL) + { + free (buf); + return NULL; + } + char *uri; + int val = asprintf (&uri, "%s/%s", buf, component); + free (component); + free (buf); + if (val == -1) + return NULL; + buf = uri; + ptr += len; + if (*ptr == '\0') + return buf; + } +} -- 2.39.2