[vlc-commits] input: extends readdir_helper_additem()
Thomas Guillem
git at videolan.org
Wed Sep 20 16:57:26 CEST 2017
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Wed Sep 20 12:57:05 2017 +0200| [020de86e1a0c2becb43e47d7fa5298b392ece603] | committer: Thomas Guillem
input: extends readdir_helper_additem()
Add a new parameter: psz_flatpath. If not NULL, readdir_helper_additem() will
un-flatten the folder hierarchy. It will create an input item for each sub
folders (separated by '/') of psz_nullpath.
Example: a stream directory that have the following items:
- "foo/bar/item1"
- "foo/bar/item2"
will output the following items while using this new parameter:
- foo
- bar
- item1
- item2
This functionality can be used by "stream directory" modules that have a
flattened folder hierarchy, like libarchive.
Access modules should not need this functionality.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=020de86e1a0c2becb43e47d7fa5298b392ece603
---
include/vlc_input_item.h | 13 +++++-
modules/access/directory.c | 3 +-
modules/access/dsm/access.c | 3 +-
modules/access/ftp.c | 2 +-
modules/access/nfs.c | 4 +-
modules/access/sftp.c | 4 +-
modules/access/smb.c | 2 +-
src/input/item.c | 109 +++++++++++++++++++++++++++++++++++++++++---
8 files changed, 123 insertions(+), 17 deletions(-)
diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h
index 7ff57304d5..99f69eba96 100644
--- a/include/vlc_input_item.h
+++ b/include/vlc_input_item.h
@@ -421,6 +421,8 @@ struct readdir_helper
input_item_node_t *p_node;
void **pp_slaves;
size_t i_slaves;
+ void **pp_dirs;
+ size_t i_dirs;
int i_sub_autodetect_fuzzy;
bool b_show_hiddenfiles;
char *psz_ignored_exts;
@@ -449,12 +451,19 @@ VLC_API void readdir_helper_finish(struct readdir_helper *p_rdh, bool b_success)
*
* \param p_rdh previously inited readdir_helper struct
* \param psz_uri uri of the new item
- * \param psz_filename file name of the new item
+ * \param psz_flatpath flattened path of the new item. If not NULL, this
+ * function will create an input item for each sub folders (separated
+ * by '/') of psz_flatpath (so, this will un-flatten the folder
+ * hierarchy). Either psz_flatpath or psz_filename must be valid.
+ * \param psz_filename file name of the new item. If NULL, the file part of path
+ * will be used as a filename. Either psz_flatpath or psz_filename must
+ * be valid.
* \param i_type see \ref input_item_type_e
* \param i_net see \ref input_item_net_type
*/
VLC_API int readdir_helper_additem(struct readdir_helper *p_rdh,
- const char *psz_uri, const char *psz_filename,
+ const char *psz_uri, const char *psz_flatpath,
+ const char *psz_filename,
int i_type, int i_net);
#endif
diff --git a/modules/access/directory.c b/modules/access/directory.c
index 3f9b0b62fd..68bbcbddac 100644
--- a/modules/access/directory.c
+++ b/modules/access/directory.c
@@ -181,7 +181,8 @@ int DirRead (stream_t *access, input_item_node_t *node)
ret = VLC_ENOMEM;
break;
}
- ret = readdir_helper_additem(&rdh, uri, entry, type, ITEM_NET_UNKNOWN);
+ ret = readdir_helper_additem(&rdh, uri, NULL, entry, type,
+ ITEM_NET_UNKNOWN);
free(uri);
}
diff --git a/modules/access/dsm/access.c b/modules/access/dsm/access.c
index 6bbe3ebf32..72e647a896 100644
--- a/modules/access/dsm/access.c
+++ b/modules/access/dsm/access.c
@@ -529,7 +529,8 @@ static int add_item( stream_t *p_access, struct readdir_helper *p_rdh,
if( i_ret == -1 )
return VLC_ENOMEM;
- return readdir_helper_additem( p_rdh, psz_uri, psz_name, i_type, ITEM_NET );
+ return readdir_helper_additem( p_rdh, psz_uri, NULL, psz_name, i_type,
+ ITEM_NET );
}
static int BrowseShare( stream_t *p_access, input_item_node_t *p_node )
diff --git a/modules/access/ftp.c b/modules/access/ftp.c
index 3a3c4105e2..6e648daad2 100644
--- a/modules/access/ftp.c
+++ b/modules/access/ftp.c
@@ -956,7 +956,7 @@ static int DirRead (stream_t *p_access, input_item_node_t *p_current_node)
p_sys->url.psz_path ? p_sys->url.psz_path : "",
psz_filename ) != -1 )
{
- i_ret = readdir_helper_additem( &rdh, psz_uri, psz_file,
+ i_ret = readdir_helper_additem( &rdh, psz_uri, NULL, psz_file,
type, ITEM_NET );
free( psz_uri );
}
diff --git a/modules/access/nfs.c b/modules/access/nfs.c
index 93bbe4f0e7..f4390f90f9 100644
--- a/modules/access/nfs.c
+++ b/modules/access/nfs.c
@@ -361,7 +361,7 @@ DirRead(stream_t *p_access, input_item_node_t *p_node)
default:
i_type = ITEM_TYPE_UNKNOWN;
}
- i_ret = readdir_helper_additem(&rdh, psz_url, p_nfsdirent->name,
+ i_ret = readdir_helper_additem(&rdh, psz_url, NULL, p_nfsdirent->name,
i_type, ITEM_NET);
free(psz_url);
}
@@ -391,7 +391,7 @@ MountRead(stream_t *p_access, input_item_node_t *p_node)
i_ret = VLC_ENOMEM;
break;
}
- i_ret = readdir_helper_additem(&rdh, psz_url, psz_name,
+ i_ret = readdir_helper_additem(&rdh, psz_url, NULL, psz_name,
ITEM_TYPE_DIRECTORY, ITEM_NET);
free(psz_url);
}
diff --git a/modules/access/sftp.c b/modules/access/sftp.c
index e46d6c64d7..8e6aa4efdf 100644
--- a/modules/access/sftp.c
+++ b/modules/access/sftp.c
@@ -589,8 +589,8 @@ static int DirRead (stream_t *p_access, input_item_node_t *p_current_node)
free( psz_uri );
int i_type = LIBSSH2_SFTP_S_ISDIR( attrs.permissions ) ? ITEM_TYPE_DIRECTORY : ITEM_TYPE_FILE;
- i_ret = readdir_helper_additem( &rdh, psz_full_uri, psz_file, i_type,
- ITEM_NET );
+ i_ret = readdir_helper_additem( &rdh, psz_full_uri, NULL, psz_file,
+ i_type, ITEM_NET );
free( psz_full_uri );
}
diff --git a/modules/access/smb.c b/modules/access/smb.c
index 47e459f098..ba65ecc39c 100644
--- a/modules/access/smb.c
+++ b/modules/access/smb.c
@@ -388,7 +388,7 @@ static int DirRead (stream_t *p_access, input_item_node_t *p_node )
break;
}
free(psz_encoded_name);
- i_ret = readdir_helper_additem( &rdh, psz_uri, p_entry->name,
+ i_ret = readdir_helper_additem( &rdh, psz_uri, NULL, p_entry->name,
i_type, ITEM_NET );
free( psz_uri );
}
diff --git a/src/input/item.c b/src/input/item.c
index 2e14218c2a..68bb68c2e0 100644
--- a/src/input/item.c
+++ b/src/input/item.c
@@ -1408,6 +1408,12 @@ struct rdh_slave
input_item_node_t *p_node;
};
+struct rdh_dir
+{
+ input_item_node_t *p_node;
+ char psz_path[];
+};
+
static char *rdh_name_from_filename(const char *psz_filename)
{
/* remove leading white spaces */
@@ -1589,6 +1595,72 @@ static void rdh_attach_slaves(struct readdir_helper *p_rdh)
}
}
+static int rdh_unflatten(struct readdir_helper *p_rdh,
+ input_item_node_t **pp_node, const char *psz_path,
+ int i_net)
+{
+ /* Create an input input for each sub folders that is contained in the full
+ * path. Update pp_node to point to the direct parent of the future item to
+ * add. */
+
+ assert(psz_path != NULL);
+ const char *psz_subpaths = psz_path;
+
+ while ((psz_subpaths = strchr(psz_subpaths, '/')))
+ {
+ input_item_node_t *p_subnode = NULL;
+
+ /* Check if this sub folder item was already added */
+ for (size_t i = 0; i < p_rdh->i_dirs && p_subnode == NULL; i++)
+ {
+ struct rdh_dir *rdh_dir = p_rdh->pp_dirs[i];
+ if (!strncmp(rdh_dir->psz_path, psz_path, psz_subpaths - psz_path))
+ p_subnode = rdh_dir->p_node;
+ }
+
+ /* The sub folder item doesn't exist, so create it */
+ if (p_subnode == NULL)
+ {
+ size_t i_sub_path_len = psz_subpaths - psz_path;
+ struct rdh_dir *p_rdh_dir =
+ malloc(sizeof(struct rdh_dir) + 1 + i_sub_path_len);
+ if (p_rdh_dir == NULL)
+ return VLC_ENOMEM;
+ strncpy(p_rdh_dir->psz_path, psz_path, i_sub_path_len);
+ p_rdh_dir->psz_path[i_sub_path_len] = 0;
+
+ const char *psz_subpathname = strrchr(p_rdh_dir->psz_path, '/');
+ if (psz_subpathname != NULL)
+ ++psz_subpathname;
+ else
+ psz_subpathname = p_rdh_dir->psz_path;
+
+ input_item_t *p_item =
+ input_item_NewExt("vlc://nop", psz_subpathname, -1,
+ ITEM_TYPE_DIRECTORY, i_net);
+ if (p_item == NULL)
+ {
+ free(p_rdh_dir);
+ return VLC_ENOMEM;
+ }
+ input_item_CopyOptions(p_item, (*pp_node)->p_item);
+ *pp_node = input_item_node_AppendItem(*pp_node, p_item);
+ input_item_Release(p_item);
+ if (*pp_node == NULL)
+ {
+ free(p_rdh_dir);
+ return VLC_ENOMEM;
+ }
+ p_rdh_dir->p_node = *pp_node;
+ TAB_APPEND(p_rdh->i_dirs, p_rdh->pp_dirs, p_rdh_dir);
+ }
+ else
+ *pp_node = p_subnode;
+ psz_subpaths++;
+ }
+ return VLC_SUCCESS;
+}
+
#undef readdir_helper_init
void readdir_helper_init(struct readdir_helper *p_rdh,
vlc_object_t *p_obj, input_item_node_t *p_node)
@@ -1600,6 +1672,7 @@ void readdir_helper_init(struct readdir_helper *p_rdh,
p_rdh->i_sub_autodetect_fuzzy = !b_autodetect ? 0 :
var_InheritInteger(p_obj, "sub-autodetect-fuzzy");
TAB_INIT(p_rdh->i_slaves, p_rdh->pp_slaves);
+ TAB_INIT(p_rdh->i_dirs, p_rdh->pp_dirs);
}
void readdir_helper_finish(struct readdir_helper *p_rdh, bool b_success)
@@ -1623,15 +1696,28 @@ void readdir_helper_finish(struct readdir_helper *p_rdh, bool b_success)
}
}
TAB_CLEAN(p_rdh->i_slaves, p_rdh->pp_slaves);
+
+ for (size_t i = 0; i < p_rdh->i_dirs; i++)
+ free(p_rdh->pp_dirs[i]);
+ TAB_CLEAN(p_rdh->i_dirs, p_rdh->pp_dirs);
}
int readdir_helper_additem(struct readdir_helper *p_rdh,
- const char *psz_uri, const char *psz_filename,
- int i_type, int i_net)
+ const char *psz_uri, const char *psz_flatpath,
+ const char *psz_filename, int i_type, int i_net)
{
enum slave_type i_slave_type;
struct rdh_slave *p_rdh_slave = NULL;
- input_item_node_t *p_node;
+ assert(psz_flatpath || psz_filename);
+
+ if (psz_filename == NULL)
+ {
+ psz_filename = strrchr(psz_flatpath, '/');
+ if (psz_filename != NULL)
+ ++psz_filename;
+ else
+ psz_filename = psz_flatpath;
+ }
if (p_rdh->i_sub_autodetect_fuzzy != 0
&& input_item_slave_GetType(psz_filename, &i_slave_type))
@@ -1657,13 +1743,22 @@ int readdir_helper_additem(struct readdir_helper *p_rdh,
if (rdh_file_is_ignored(p_rdh, psz_filename))
return VLC_SUCCESS;
- input_item_t *p_item = input_item_NewExt(psz_uri, psz_filename, -1,
- i_type, i_net);
+ input_item_node_t *p_node = p_rdh->p_node;
+
+ if (psz_flatpath != NULL)
+ {
+ int i_ret = rdh_unflatten(p_rdh, &p_node, psz_flatpath, i_net);
+ if (i_ret != VLC_SUCCESS)
+ return i_ret;
+ }
+
+ input_item_t *p_item = input_item_NewExt(psz_uri, psz_filename, -1, i_type,
+ i_net);
if (p_item == NULL)
return VLC_ENOMEM;
- input_item_CopyOptions(p_item, p_rdh->p_node->p_item);
- p_node = input_item_node_AppendItem(p_rdh->p_node, p_item);
+ input_item_CopyOptions(p_item, p_node->p_item);
+ p_node = input_item_node_AppendItem(p_node, p_item);
input_item_Release(p_item);
if (p_node == NULL)
return VLC_ENOMEM;
More information about the vlc-commits
mailing list