]> git.sesse.net Git - vlc/commitdiff
make_URI: make a URI out of a path, if needed
authorRémi Denis-Courmont <remi@remlab.net>
Sun, 10 May 2009 12:23:18 +0000 (15:23 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Sun, 10 May 2009 12:23:18 +0000 (15:23 +0300)
include/vlc_url.h
src/libvlccore.sym
src/text/strings.c

index 271e4d2702fd32916ff187ec2295619c10e9048a..448c685435182eee1e5e59ffca78a5712afc9eff 100644 (file)
@@ -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:
index ac68b0e2e3b64d329d094ef43fcef5b3786be1e2..d72c10f8051a2271ad641244972b59e4f3f6cc6d 100644 (file)
@@ -216,6 +216,7 @@ libvlc_InternalInit
 libvlc_InternalWait
 libvlc_Quit
 LocaleFree
+make_URI
 mdate
 module_config_free
 module_config_get
index 4eea72fd161f05652a1ae985fb482d7a54e68c75..860aae7c22748903e9483509cd521b29fd545469 100644 (file)
@@ -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 <dionoea at videolan dot org>
@@ -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 <vlc_url.h>
+
+/**
+ * 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;
+    }
+}