changeset 4070:040243a50bd3

- modified playlist_load_ins_file() and playlist_load_ins_file_tuple(). path builder and ext_hash checker have been extracted from playlist_load_ins_file_tuple() and are provided as individual functions. - path builder is available to plugins as aud_construct_uri() and it allows container plugins to construct valid uri. - replaced __playlist_ins_with_info_tuple() with the superset __playlist_ins_file(). it can accept both tuple and title/length pair. - changed call dependency among playlist_load_ins_file(), playlist_load_ins_file_tuple() and __playlist_ins_file(). playlist_load_ins_file() no longer calls playlist_load_ins_file_tuple() nor builds any tuple. - made some cleanups.
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Fri, 07 Dec 2007 01:11:25 +0900
parents b26a96a5da69
children 155e8893e05c
files src/audacious/playlist.c src/audacious/plugin.h src/audacious/pluginenum.c src/audacious/strings.c src/audacious/strings.h src/audacious/tuple_formatter.c src/audacious/util.c src/audacious/util.h
diffstat 8 files changed, 178 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/src/audacious/playlist.c	Thu Dec 06 16:55:32 2007 +0100
+++ b/src/audacious/playlist.c	Fri Dec 07 01:11:25 2007 +0900
@@ -26,6 +26,8 @@
  *  Audacious or using our public API to be a derived work.
  */
 
+/* #define AUD_DEBUG 1 */
+
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
@@ -153,6 +155,7 @@
 
 static gint filter_by_extension(const gchar *filename);
 static gboolean is_http(const gchar *filename);
+static gboolean do_precheck(Playlist *playlist, const gchar *uri, ProbeResult *pr);
 
 static mowgli_heap_t *playlist_entry_heap = NULL;
 
@@ -656,11 +659,13 @@
 }
 
 static void
-__playlist_ins_with_info_tuple(Playlist * playlist,
-			       const gchar * filename,
-			       gint pos,
-			       Tuple *tuple,
-			       InputPlugin * dec)
+__playlist_ins_file(Playlist * playlist,
+                    const gchar * filename,
+                    gint pos,
+                    Tuple *tuple,
+                    const gchar *title, // may NULL
+                    gint len,
+                    InputPlugin * dec)
 {
     PlaylistEntry *entry;
     Tuple *parent_tuple = NULL;
@@ -693,12 +698,18 @@
         } else
             filename_entry = g_strdup(filename);
         
-        
-        entry = playlist_entry_new(filename_entry,
-            tuple ? tuple_get_string(tuple, FIELD_TITLE, NULL) : NULL,
-            tuple ? tuple_get_int(tuple, FIELD_LENGTH, NULL) : -1, dec);
+        if(tuple) {
+            entry = playlist_entry_new(filename_entry,
+                                       tuple_get_string(tuple, FIELD_TITLE, NULL),
+                                       tuple_get_int(tuple, FIELD_LENGTH, NULL), dec);
+        }
+        else {
+            entry = playlist_entry_new(filename_entry, title, len, dec);
+        }
+
         g_free(filename_entry);
 
+
         PLAYLIST_LOCK(playlist);
         
         if (!playlist->tail)
@@ -757,7 +768,6 @@
     ProbeResult *pr = NULL;
     InputPlugin *dec = NULL;
     Tuple *tuple = NULL;
-    gint ext_flag;
     gboolean http_flag;
 
     g_return_val_if_fail(playlist != NULL, FALSE);
@@ -771,44 +781,25 @@
         return TRUE;
     }
 
-    ext_flag = filter_by_extension(filename);
-    http_flag = is_http(filename);
-
-    /* playlist file or remote uri */
-    if (playlist->loading_playlist == TRUE || http_flag == TRUE) {
-        dec = NULL;
-    }
-
-    /* local file and on-demand probing is on */
-    else if (cfg.playlist_detect == TRUE && ext_flag != EXT_HAVE_SUBTUNE && ext_flag != EXT_CUSTOM) {
-        dec = NULL;
-        if(cfg.use_extension_probing && ext_flag == EXT_FALSE)
-            return FALSE;
-    }
-
-    /* find decorder for local file */
-    else {
-        pr = input_check_file(filename, TRUE);
-
-        if (pr) {
+    if(do_precheck(playlist, filename, pr)) {
+        if(pr) {
             dec = pr->ip;
             tuple = pr->tuple;
         }
-        g_free(pr);
-    }
-
-    /* add filename to playlist */
-    if (cfg.playlist_detect == TRUE ||
-        playlist->loading_playlist == TRUE ||
-       (playlist->loading_playlist == FALSE && dec != NULL) ||
-       (playlist->loading_playlist == FALSE && !is_playlist_name(filename) && http_flag) ) {
-
-        __playlist_ins_with_info_tuple(playlist, filename, pos, tuple, dec);
-
-        playlist_generate_shuffle_list(playlist);
-        playlistwin_update_list(playlist);
-        playlist_manager_update();
-        return TRUE;
+        /* add filename to playlist */
+        if (cfg.playlist_detect == TRUE ||
+            playlist->loading_playlist == TRUE ||
+            (playlist->loading_playlist == FALSE && dec != NULL) ||
+            (playlist->loading_playlist == FALSE && !is_playlist_name(filename) && http_flag) ) {
+
+            __playlist_ins_file(playlist, filename, pos, tuple, NULL, -1, dec);
+
+            g_free(pr);
+            playlist_generate_shuffle_list(playlist);
+            playlistwin_update_list(playlist);
+            playlist_manager_update();
+            return TRUE;
+        }
     }
 
     /* Some files (typically produced by some cgi-scripts) don't have
@@ -1104,7 +1095,7 @@
     }
 
     playlist_recalc_total_time(playlist);
-    PLAYLIST_INCR_SERIAL(playlist); //probably necessary because there is no underlying __playlist_ins --yaz
+    PLAYLIST_INCR_SERIAL(playlist);
     playlist_generate_shuffle_list(playlist);
     playlistwin_update_list(playlist);
 
@@ -1696,100 +1687,75 @@
 
 void
 playlist_load_ins_file(Playlist *playlist,
-                       const gchar * filename_p,
+                       const gchar * uri,
                        const gchar * playlist_name, gint pos,
                        const gchar * title, gint len)
 {
-    Tuple *tuple;
-
-    if (vfs_is_remote(filename_p)) {
-      tuple = tuple_new();
-      tuple_associate_string(tuple, FIELD_FILE_NAME, NULL, filename_p);        
-    } else {
-      tuple = tuple_new_from_filename(filename_p);
+    ProbeResult *pr = NULL;
+
+    g_return_if_fail(uri != NULL);
+    g_return_if_fail(playlist_name != NULL);
+    g_return_if_fail(playlist != NULL);
+
+    if(do_precheck(playlist, uri, pr)) {
+        __playlist_ins_file(playlist, uri, pos, NULL, title, len, pr ? pr->ip : NULL);
     }
-
-    tuple_associate_string(tuple, FIELD_TITLE, NULL, title);
-    tuple_associate_int(tuple, FIELD_LENGTH, NULL, len);
-    tuple_associate_int(tuple, FIELD_MTIME, NULL, -1); // invalidate to make tuple renew
-
-    playlist_load_ins_file_tuple(playlist, filename_p, playlist_name, pos, tuple);
+    g_free(pr);
 }
 
 void
 playlist_load_ins_file_tuple(Playlist * playlist,
-                             const gchar * filename_p,      //filename to add
+                             const gchar * uri,
                              const gchar * playlist_name,   //path of playlist file itself
                              gint pos,
                              Tuple *tuple)
 {
-    gchar *filename;
-    gchar *tmp, *path;
     ProbeResult *pr = NULL;		/* for decoder cache */
-    gchar *uri = NULL;
-
-
-    g_return_if_fail(filename_p != NULL);
+
+    g_return_if_fail(uri != NULL);
     g_return_if_fail(playlist_name != NULL);
     g_return_if_fail(playlist != NULL);
 
-    filename = g_strchug(g_strdup(filename_p));
-
-
-    /* convert backslash to slash */
-    if (cfg.convert_slash)
-        while ((tmp = strchr(filename, '\\')) != NULL)
-            *tmp = '/';
-
-
-    /* make full path uri here */
-    // case 1: filename is raw full path or uri
-    if (filename[0] == '/' || strstr(filename, "://")) {
-        uri = g_filename_to_uri(filename, NULL, NULL);
-        if(!uri) {
-            uri = g_strdup(filename);
-        }
-        g_free(filename);
+    if(do_precheck(playlist, uri, pr)) {
+        __playlist_ins_file(playlist, uri, pos, tuple, NULL, -1, pr ? pr->ip : NULL);
     }
-    // case 2: filename is not raw full path nor uri, playlist path is full path
-    // make full path by replacing last part of playlist path with filename. (using g_build_filename)
-    else if (playlist_name[0] == '/' || strstr(playlist_name, "://")) {
-        path = g_strdup(playlist_name);
-        tmp = strrchr(path, '/'); *tmp = '\0';
-        tmp = g_build_filename(path, filename, NULL);
-        uri = g_filename_to_uri(tmp, NULL, NULL);
-        g_free(tmp); g_free(filename);
-    }
-    // case 3: filename is not raw full path nor uri, playlist path is not full path
-    // just abort.
-    else {
-        g_free(filename);
-        return;
-    }
-
-
-    /* apply pre check and add to playlist */
+    g_free(pr);
+
+}
+
+static gboolean
+do_precheck(Playlist *playlist, const gchar *uri, ProbeResult *pr)
+{
     gint ext_flag = filter_by_extension(uri);
     gboolean http_flag = is_http(uri);
+    gboolean rv = FALSE;
 
     /* playlist file or remote uri */
     if ((playlist->loading_playlist == TRUE && ext_flag != EXT_HAVE_SUBTUNE ) || http_flag == TRUE) {
         pr = NULL;
+        rv = TRUE;
     }
     /* local file and on-demand probing is on */
     else if (cfg.playlist_detect == TRUE && ext_flag != EXT_HAVE_SUBTUNE && ext_flag != EXT_CUSTOM) {
-        pr = NULL;
-        if(cfg.use_extension_probing && ext_flag == EXT_FALSE)
-            return;
+        if(cfg.use_extension_probing && ext_flag == EXT_FALSE) {
+            AUDDBG("reject %s\n", uri);
+            rv = FALSE;
+        }
+        else {
+            pr = NULL;
+            rv = TRUE;
+        }
     }
     /* find decorder for local file */
     else {
         pr = input_check_file(uri, TRUE);
+        if(pr) {
+            AUDDBG("got pr\n");
+            rv = TRUE;
+        }
     }
 
-    __playlist_ins_with_info_tuple(playlist, uri, pos, tuple, pr ? pr->ip : NULL);
-    g_free(pr);
-
+    return rv;
 }
 
 static guint
@@ -2684,7 +2650,7 @@
         g_cond_wait(cond_scan, mutex_scan);
         g_mutex_unlock(mutex_scan);
 
-//        g_print("scanner invoked\n");
+//        AUDDBG("scanner invoked\n");
 
     } // while
 
@@ -3411,6 +3377,8 @@
     gint rv;
     GList **lhandle, *node;
     InputPlugin *ip;
+
+    g_return_val_if_fail(uri != NULL, EXT_FALSE);
     
     /* Some URIs will end in ?<subsong> to determine the subsong requested. */
     tmp_uri = g_strdup(uri);
@@ -3437,7 +3405,7 @@
 
     if(!ext) {
         g_free(base);
-        return 0;
+        return EXT_FALSE;
     }
 
     lext = g_ascii_strdown(ext+1, -1);
--- a/src/audacious/plugin.h	Thu Dec 06 16:55:32 2007 +0100
+++ b/src/audacious/plugin.h	Fri Dec 07 01:11:25 2007 +0900
@@ -590,6 +590,8 @@
     GList *(*get_output_list)(void);
 
     void (*input_get_volume)(gint * l, gint * r);
+
+    gchar *(*construct_uri)(gchar *string, const gchar *playlist_name);
 };
 
 /* Convenience macros for accessing the public API. */
@@ -931,6 +933,9 @@
 
 #define aud_input_get_volume			_audvt->input_get_volume
 
+#define aud_construct_uri        _audvt->construct_uri
+
+
 #include "audacious/auddrct.h"
 
 /* for multi-file plugins :( */
--- a/src/audacious/pluginenum.c	Thu Dec 06 16:55:32 2007 +0100
+++ b/src/audacious/pluginenum.c	Fri Dec 07 01:11:25 2007 +0900
@@ -388,6 +388,7 @@
     .get_output_list = get_output_list,
 
     .input_get_volume = input_get_volume,
+    .construct_uri = construct_uri,
 };
 
 /*****************************************************************/
--- a/src/audacious/strings.c	Thu Dec 06 16:55:32 2007 +0100
+++ b/src/audacious/strings.c	Fri Dec 07 01:11:25 2007 +0900
@@ -73,6 +73,7 @@
     return escaped;
 }
 
+/* replace %20 with ' ' in place */
 static gchar *
 str_twenty_to_space(gchar * str)
 {
@@ -91,6 +92,26 @@
     return str;
 }
 
+/* replace drive letter with '/' in place */
+static gchar *
+str_replace_drive_letter(gchar * str)
+{
+    gchar *match, *match_end;
+
+    g_return_val_if_fail(str != NULL, NULL);
+
+    while ((match = strstr(str, ":\\"))) {
+        match--;
+        match_end = match + 3;
+        *match++ = '/';
+        while (*match_end)
+            *match++ = *match_end++;
+        *match = 0; /* the end of line */
+    }
+
+    return str;
+}
+
 static gchar *
 str_replace_char(gchar * str, gchar old, gchar new)
 {
@@ -263,7 +284,22 @@
     return title;
 }
 
-gchar *chardet_to_utf8(const gchar *str, gssize len,
+gchar *
+convert_dos_path(gchar * path)
+{
+    g_return_val_if_fail(path != NULL, NULL);
+
+    /* replace drive letter with '/' */
+    str_replace_drive_letter(path);
+
+    /* replace '\' with '/' */
+    str_replace_char(path, '\\', '/');
+
+    return path;
+}
+
+gchar *
+chardet_to_utf8(const gchar *str, gssize len,
                        gsize *arg_bytes_read, gsize *arg_bytes_write,
 					   GError **arg_error)
 {
--- a/src/audacious/strings.h	Thu Dec 06 16:55:32 2007 +0100
+++ b/src/audacious/strings.h	Fri Dec 07 01:11:25 2007 +0900
@@ -45,6 +45,7 @@
 const gchar *str_skip_chars(const gchar * str, const gchar * chars);
 
 gchar *convert_title_text(gchar * text);
+gchar *convert_dos_path(gchar * text);
 
 gchar *chardet_to_utf8(const gchar *str, gssize len,
                        gsize *arg_bytes_read, gsize *arg_bytes_write,
--- a/src/audacious/tuple_formatter.c	Thu Dec 06 16:55:32 2007 +0100
+++ b/src/audacious/tuple_formatter.c	Fri Dec 07 01:11:25 2007 +0900
@@ -598,11 +598,17 @@
 
     if(!rv || !strcmp(rv, "")) {
         const gchar *file_name = tuple_get_string(tuple, FIELD_FILE_NAME, NULL);
-        gchar *realfn = file_name != NULL ? g_filename_from_uri(file_name, NULL, NULL) : g_strdup("<unknown>");
 
-        g_free(rv);
-        rv = str_to_utf8(realfn ? realfn : file_name);
-        g_free(realfn);
+        if(file_name) {
+            gchar *realfn = g_filename_from_uri(file_name, NULL, NULL);
+            g_free(rv);
+            rv = str_to_utf8(realfn ? realfn : file_name);
+            g_free(realfn);
+        }
+        else {
+            g_free(rv);
+            rv = g_strdup("<unknown>");
+        }
     }
 
     return rv;
--- a/src/audacious/util.c	Thu Dec 06 16:55:32 2007 +0100
+++ b/src/audacious/util.c	Fri Dec 07 01:11:25 2007 +0900
@@ -23,6 +23,8 @@
  *  Audacious or using our public API to be a derived work.
  */
 
+/* #define AUD_DEBUG 1 */
+
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
@@ -967,3 +969,46 @@
   return datadir;
 }
 
+
+gchar *
+construct_uri(gchar *string, const gchar *playlist_name) // uri, path and anything else
+{
+    gchar *filename = g_strdup(string);
+    gchar *tmp, *path;
+    gchar *uri = NULL;
+
+    /* try to translate dos path */
+    convert_dos_path(filename); /* in place replacement */
+
+    /* convert backslash to slash */
+    while ((tmp = strchr(filename, '\\')) != NULL)
+        *tmp = '/';
+
+    // make full path uri here
+    // case 1: filename is raw full path or uri
+    if (filename[0] == '/' || strstr(filename, "://")) {
+        uri = g_filename_to_uri(filename, NULL, NULL);
+        if(!uri) {
+            uri = g_strdup(filename);
+        }
+        g_free(filename);
+    }
+    // case 2: filename is not raw full path nor uri, playlist path is full path
+    // make full path by replacing last part of playlist path with filename. (using g_build_filename)
+    else if (playlist_name[0] == '/' || strstr(playlist_name, "://")) {
+        path = g_strdup(playlist_name);
+        tmp = strrchr(path, '/'); *tmp = '\0';
+        tmp = g_build_filename(path, filename, NULL);
+        uri = g_filename_to_uri(tmp, NULL, NULL);
+        g_free(tmp); g_free(filename);
+    }
+    // case 3: filename is not raw full path nor uri, playlist path is not full path
+    // just abort.
+    else {
+        g_free(filename);
+        return NULL;
+    }
+
+    AUDDBG("uri=%s\n", uri);
+    return uri;
+}
--- a/src/audacious/util.h	Thu Dec 06 16:55:32 2007 +0100
+++ b/src/audacious/util.h	Fri Dec 07 01:11:25 2007 +0900
@@ -105,6 +105,7 @@
 /* menu-related function */
 void util_menu_main_show(gint x, gint y, guint button, guint time);
 
+gchar *construct_uri(gchar *string, const gchar *playlist_name);
 
 G_END_DECLS