]> git.sesse.net Git - vlc/commitdiff
make_path: make a local file path from an URI
authorRémi Denis-Courmont <remi@remlab.net>
Sat, 30 Jan 2010 16:18:04 +0000 (18:18 +0200)
committerRémi Denis-Courmont <remi@remlab.net>
Sat, 30 Jan 2010 16:34:28 +0000 (18:34 +0200)
include/vlc_url.h
src/libvlccore.sym
src/text/strings.c

index 714a3f24da5f46047ae2985477c853c826dbab6b..35bea922fdccb977d479e16bd4a2a50117fd4179 100644 (file)
@@ -49,6 +49,7 @@ 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_EXPORT( char *, make_path, ( const char *url ) );
 
 /*****************************************************************************
  * vlc_UrlParse:
index 8ce0034f557e0cfa81b4e46ca125bfdd1b8b8d2f..ab7e21e8a553de4dec046e82ec835f6889afacaf 100644 (file)
@@ -227,6 +227,7 @@ libvlc_InternalWait
 libvlc_Quit
 LocaleFree
 make_URI
+make_path
 mdate
 module_config_free
 module_config_get
index f136a595c63233dddc26d774ee39161ea0127203..a37fe165ead0f408ac1f694240d81a0f4fdc7c45 100644 (file)
@@ -1146,3 +1146,93 @@ char *make_URI (const char *path)
             return buf;
     }
 }
+
+/**
+ * Tries to convert an URI to a local (UTF-8-encoded) file path.
+ * @param url URI to convert
+ * @return NULL on error, a nul-terminated string otherwise
+ * (use free() to release it)
+ */
+char *make_path (const char *url)
+{
+    char *ret = NULL;
+    char *end;
+
+    char *path = strstr (url, "://");
+    if (path == NULL)
+        return NULL; /* unsupported scheme or invalid syntax */
+
+    end = memchr (url, '/', path - url);
+    size_t schemelen = ((end != NULL) ? end : path) - url;
+    path += 3; /* skip "://" */
+
+    /* Remove HTML anchor if present */
+    end = strchr (path, '#');
+    if (end)
+        path = strndup (path, end - path);
+    else
+        path = strdup (path);
+    if (unlikely(path == NULL))
+        return NULL; /* boom! */
+
+    /* Decode path */
+    decode_URI (path);
+
+    if (schemelen == 4 && !strncasecmp (url, "file", 4))
+    {
+#if (DIR_SEP_CHAR != '/')
+        for (char *p = strchr (path, '/'); p; p = strchr (p, '/'))
+            *p == DIR_SEP_CHAR;
+#endif
+        if (*path == DIR_SEP_CHAR)
+            return path;
+
+        /* Local path disguised as a remote one (MacOS X) */
+        if (!strncasecmp (path, "localhost"DIR_SEP, 10))
+        {
+            memmove (path, path + 9, strlen (path + 9) + 1);
+            return path;
+        }
+
+#ifdef WIN32
+        if (*path && asprintf (&ret, "\\\\%s", path) == -1)
+            ret = NULL;
+#endif
+        /* non-local path :-( */
+    }
+    else
+    if (schemelen == 2 && !strncasecmp (url, "fd", 2))
+    {
+        int fd = strtol (path, &end, 0);
+
+        if (*end)
+            goto out;
+
+#ifndef WIN32
+        switch (fd)
+        {
+            case 0:
+                ret = strdup ("/dev/stdin");
+                break;
+            case 1:
+                ret = strdup ("/dev/stdout");
+                break;
+            case 2:
+                ret = strdup ("/dev/strerr");
+                break;
+            default:
+                if (asprintf (&ret, "/dev/fd/%d", fd) == -1)
+                    ret = NULL;
+        }
+#else
+        if (fd < 2)
+            ret = strdup ("CON");
+        else
+            ret = NULL;
+#endif
+    }
+
+out:
+    free (path);
+    return ret; /* unknown scheme */
+}