[vlc-devel] [PATCHv2 12/13] access: attach slaves to input items
Thomas Guillem
thomas at gllm.fr
Tue May 3 19:02:39 CEST 2016
From: Benjamin Adolphi <b.adolphi at gmail.com>
Also-by: Thomas Guillem <thomas at gllm.fr>
Signed-off-by: Thomas Guillem <thomas at gllm.fr>
---
include/vlc_access.h | 3 +
src/input/access.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 176 insertions(+), 1 deletion(-)
diff --git a/include/vlc_access.h b/include/vlc_access.h
index a35d62b..77297dc 100644
--- a/include/vlc_access.h
+++ b/include/vlc_access.h
@@ -278,6 +278,9 @@ struct access_fsdir
{
access_t *p_access;
input_item_node_t *p_node;
+ void **pp_slaves;
+ unsigned int i_slaves;
+ int i_sub_autodetect_fuzzy;
bool b_show_hiddenfiles;
char *psz_ignored_exts;
};
diff --git a/src/input/access.c b/src/input/access.c
index 73ac7b9..bd8e474 100644
--- a/src/input/access.c
+++ b/src/input/access.c
@@ -28,6 +28,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <vlc_common.h>
#include <vlc_url.h>
@@ -528,6 +529,126 @@ static bool fsdir_is_ignored(struct access_fsdir *p_fsdir,
|| fsdir_has_ext(psz_filename, p_fsdir->psz_ignored_exts));
}
+struct fsdir_slave
+{
+ input_item_slave *p_slave;
+ char *psz_filename;
+ input_item_node_t *p_node;
+};
+
+static char *fsdir_name_from_filename(const char *psz_filename)
+{
+ /* remove leading white spaces */
+ while (*psz_filename != '\0' && *psz_filename == ' ')
+ psz_filename++;
+
+ char *psz_name = strdup(psz_filename);
+ if (!psz_name)
+ return NULL;
+
+ /* remove extension */
+ char *psz_ptr = strrchr(psz_name, '.');
+ if (psz_ptr)
+ *psz_ptr = '\0';
+
+ /* remove trailing white spaces */
+ int i = strlen(psz_name) - 1;
+ while (psz_name[i] == ' ' && i >= 0)
+ psz_name[i--] = '\0';
+
+ /* convert to lower case */
+ psz_ptr = psz_name;
+ while (*psz_ptr != '\0')
+ {
+ *psz_ptr = tolower(*psz_ptr);
+ psz_ptr++;
+ }
+
+ return psz_name;
+}
+
+static uint8_t fsdir_get_slave_priority(input_item_t *p_item,
+ input_item_slave *p_slave,
+ const char *psz_slave_filename)
+{
+ char *psz_item_name = fsdir_name_from_filename(p_item->psz_name);
+ char *psz_slave_name = fsdir_name_from_filename(psz_slave_filename);
+
+ if (!psz_item_name || !psz_slave_name)
+ {
+ p_slave->i_priority = SLAVE_PRIORITY_NONE;
+ goto done;
+ }
+
+ /* check if the names match exactly */
+ if (!strcmp(psz_item_name, psz_slave_name))
+ {
+ p_slave->i_priority = SLAVE_PRIORITY_MATCH_ALL;
+ goto done;
+ }
+
+ /* check if the item name is a substring of the slave name */
+ const char *psz_sub = strstr(psz_slave_name, psz_item_name);
+
+ if (psz_sub)
+ {
+ /* check if the item name was found at the end of the slave name */
+ if (strlen(psz_sub + strlen(psz_item_name)) == 0)
+ {
+ p_slave->i_priority = SLAVE_PRIORITY_MATCH_RIGHT;
+ goto done;
+ }
+ else
+ {
+ p_slave->i_priority = SLAVE_PRIORITY_MATCH_LEFT;
+ goto done;
+ }
+ }
+ p_slave->i_priority = SLAVE_PRIORITY_MATCH_NONE;
+done:
+ free(psz_item_name);
+ free(psz_slave_name);
+ return p_slave->i_priority;
+}
+
+static void fsdir_attach_slaves(struct access_fsdir *p_fsdir)
+{
+ if (p_fsdir->i_sub_autodetect_fuzzy == 0)
+ return;
+
+ /* Try to match slaves for each items of the node */
+ for (int i = 0; i < p_fsdir->p_node->i_children; i++)
+ {
+ input_item_node_t *p_node = p_fsdir->p_node->pp_children[i];
+ input_item_t *p_item = p_node->p_item;
+
+ for (unsigned int j = 0; j < p_fsdir->i_slaves; j++)
+ {
+ struct fsdir_slave *p_fsdir_slave = p_fsdir->pp_slaves[j];
+
+ if (p_fsdir_slave != NULL
+ && p_fsdir_slave->p_node != p_node
+ && fsdir_get_slave_priority(p_item, p_fsdir_slave->p_slave,
+ p_fsdir_slave->psz_filename)
+ >= p_fsdir->i_sub_autodetect_fuzzy)
+ {
+ input_item_AddSlave(p_item, p_fsdir_slave->p_slave);
+
+ /* Remove the corresponding node if any: This slave won't be
+ * added in the parent node */
+ if (p_fsdir_slave->p_node != NULL)
+ input_item_node_Delete(p_fsdir_slave->p_node);
+
+ /* Remove this slave from the list: we don't want to match
+ * other items */
+ free(p_fsdir_slave->psz_filename);
+ free(p_fsdir_slave);
+ p_fsdir->pp_slaves[j] = NULL;
+ }
+ }
+ }
+}
+
void access_fsdir_init(struct access_fsdir *p_fsdir,
access_t *p_access, input_item_node_t *p_node)
{
@@ -535,19 +656,64 @@ void access_fsdir_init(struct access_fsdir *p_fsdir,
p_fsdir->p_node = p_node;
p_fsdir->b_show_hiddenfiles = var_InheritBool(p_access, "show-hiddenfiles");
p_fsdir->psz_ignored_exts = var_InheritString(p_access, "ignore-filetypes");
+ p_fsdir->i_sub_autodetect_fuzzy =
+ var_InheritInteger(p_access, "sub-autodetect-fuzzy");
+ TAB_INIT(p_fsdir->i_slaves, p_fsdir->pp_slaves);
}
void access_fsdir_finish(struct access_fsdir *p_fsdir, bool b_success)
{
if (b_success)
+ {
+ fsdir_attach_slaves(p_fsdir);
fsdir_sort(p_fsdir);
+ }
free(p_fsdir->psz_ignored_exts);
+
+ /* Remove unmatched slaves */
+ for (unsigned int i = 0; i < p_fsdir->i_slaves; i++)
+ {
+ struct fsdir_slave *p_fsdir_slave = p_fsdir->pp_slaves[i];
+ if (p_fsdir_slave != NULL)
+ {
+ input_item_slave_Delete(p_fsdir_slave->p_slave);
+ free(p_fsdir_slave->psz_filename);
+ free(p_fsdir_slave);
+ }
+ }
+ TAB_CLEAN(p_fsdir->i_slaves, p_fsdir->pp_slaves);
}
int access_fsdir_additem(struct access_fsdir *p_fsdir,
const char *psz_uri, const char *psz_filename,
int i_type, int i_net)
{
+ enum slave_type i_slave_type;
+ struct fsdir_slave *p_fsdir_slave = NULL;
+ input_item_node_t *p_node;
+
+ if (p_fsdir->i_sub_autodetect_fuzzy != 0
+ && input_item_slave_GetType(psz_filename, &i_slave_type))
+ {
+ p_fsdir_slave = malloc(sizeof(*p_fsdir_slave));
+ if (!p_fsdir_slave)
+ return VLC_ENOMEM;
+
+ p_fsdir_slave->p_node = NULL;
+ p_fsdir_slave->psz_filename = strdup(psz_filename);
+ p_fsdir_slave->p_slave = input_item_slave_New(psz_uri, i_slave_type,
+ SLAVE_PRIORITY_NONE);
+ if (!p_fsdir_slave->p_slave || !p_fsdir_slave->psz_filename)
+ {
+ free(p_fsdir_slave->psz_filename);
+ free(p_fsdir_slave);
+ return VLC_ENOMEM;
+ }
+
+ INSERT_ELEM(p_fsdir->pp_slaves, p_fsdir->i_slaves,
+ p_fsdir->i_slaves, p_fsdir_slave);
+ }
+
if (fsdir_is_ignored(p_fsdir, psz_filename))
return VLC_SUCCESS;
@@ -557,7 +723,13 @@ int access_fsdir_additem(struct access_fsdir *p_fsdir,
return VLC_ENOMEM;
input_item_CopyOptions(p_item, p_fsdir->p_node->p_item);
- input_item_node_AppendItem(p_fsdir->p_node, p_item);
+ p_node = input_item_node_AppendItem(p_fsdir->p_node, p_item);
input_item_Release(p_item);
+
+ /* A slave can also be an item. If there is a match, this item will be
+ * removed from the parent node. This is not a common case, since most
+ * slaves will be ignored by fsdir_is_ignored() */
+ if (p_fsdir_slave != NULL)
+ p_fsdir_slave->p_node = p_node;
return VLC_SUCCESS;
}
--
2.8.0.rc3
More information about the vlc-devel
mailing list