mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
VFS: Add function for search superblock by any condition via callback
This commit is contained in:
parent
b7ec1db5ae
commit
867687574f
@ -92,6 +92,13 @@ struct dirhandle
|
|||||||
struct vfs_s_inode *dir;
|
struct vfs_s_inode *dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vfs_path_t *vpath_archive;
|
||||||
|
const vfs_path_element_t *path_element;
|
||||||
|
void *cookie;
|
||||||
|
} vfs_get_by_vpath_data_t;
|
||||||
|
|
||||||
/*** file scope variables ************************************************************************/
|
/*** file scope variables ************************************************************************/
|
||||||
|
|
||||||
static volatile int total_inodes = 0, total_entries = 0;
|
static volatile int total_inodes = 0, total_entries = 0;
|
||||||
@ -868,56 +875,29 @@ vfs_s_dir_uptodate (struct vfs_class *me, struct vfs_s_inode *ino)
|
|||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* get superlock object by vpath
|
* Callback for search superblock via subclass->archive_same() call
|
||||||
*
|
*
|
||||||
* @param vpath path
|
* @param me class for search superblocks
|
||||||
* @return superlock object or NULL if not found
|
* @param cb_data some data for callback
|
||||||
|
* @param super superblock for comparsion
|
||||||
|
* @return TRUE if superblock is what we need, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct vfs_s_super *
|
static gboolean
|
||||||
vfs_get_sb_by_vpath (const vfs_path_t * vpath)
|
vfs_cb_archive_same (struct vfs_class *me, void *cb_data, struct vfs_s_super *super)
|
||||||
{
|
{
|
||||||
GList *iter;
|
vfs_get_by_vpath_data_t *vfs_get_by_vpath_data;
|
||||||
void *cookie = NULL;
|
|
||||||
const vfs_path_element_t *path_element;
|
|
||||||
struct vfs_s_subclass *subclass;
|
struct vfs_s_subclass *subclass;
|
||||||
struct vfs_s_super *super = NULL;
|
int ret;
|
||||||
vfs_path_t *vpath_archive;
|
|
||||||
|
|
||||||
path_element = vfs_path_get_by_index (vpath, -1);
|
vfs_get_by_vpath_data = (vfs_get_by_vpath_data_t *) cb_data;
|
||||||
subclass = ((struct vfs_s_subclass *) path_element->class->data);
|
subclass = (struct vfs_s_subclass *) me->data;
|
||||||
if (subclass == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
vpath_archive = vfs_path_clone (vpath);
|
ret = subclass->archive_same (vfs_get_by_vpath_data->path_element, super,
|
||||||
vfs_path_remove_element_by_index (vpath_archive, -1);
|
vfs_get_by_vpath_data->vpath_archive,
|
||||||
|
vfs_get_by_vpath_data->cookie);
|
||||||
|
|
||||||
if (subclass->archive_check != NULL)
|
return (ret != 0);
|
||||||
{
|
|
||||||
cookie = subclass->archive_check (vpath_archive);
|
|
||||||
if (cookie == NULL)
|
|
||||||
goto ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (iter = subclass->supers; iter != NULL; iter = g_list_next (iter))
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
super = (struct vfs_s_super *) iter->data;
|
|
||||||
|
|
||||||
/* 0 == other, 1 == same, return it, 2 == other but stop scanning */
|
|
||||||
i = subclass->archive_same (path_element, super, vpath_archive, cookie);
|
|
||||||
if (i == 1)
|
|
||||||
goto ret;
|
|
||||||
if (i != 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
super = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret:
|
|
||||||
vfs_path_free (vpath_archive);
|
|
||||||
return super;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1103,13 +1083,39 @@ struct vfs_s_super *
|
|||||||
vfs_get_super_by_vpath (const vfs_path_t * vpath, gboolean is_create_new)
|
vfs_get_super_by_vpath (const vfs_path_t * vpath, gboolean is_create_new)
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
struct vfs_s_super *super;
|
struct vfs_s_super *super = NULL;
|
||||||
const vfs_path_element_t *path_element;
|
const vfs_path_element_t *path_element;
|
||||||
struct vfs_s_subclass *subclass;
|
struct vfs_s_subclass *subclass;
|
||||||
|
vfs_get_by_vpath_data_t vfs_get_by_vpath_data;
|
||||||
|
|
||||||
path_element = vfs_path_get_by_index (vpath, -1);
|
path_element = vfs_path_get_by_index (vpath, -1);
|
||||||
|
subclass = ((struct vfs_s_subclass *) path_element->class->data);
|
||||||
|
if (subclass == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
vfs_get_by_vpath_data.path_element = path_element;
|
||||||
|
vfs_get_by_vpath_data.vpath_archive = vfs_path_clone (vpath);
|
||||||
|
vfs_path_remove_element_by_index (vfs_get_by_vpath_data.vpath_archive, -1);
|
||||||
|
|
||||||
|
{
|
||||||
|
gboolean is_search_called = TRUE;
|
||||||
|
if (subclass->archive_check != NULL)
|
||||||
|
{
|
||||||
|
vfs_get_by_vpath_data.cookie =
|
||||||
|
subclass->archive_check (vfs_get_by_vpath_data.vpath_archive);
|
||||||
|
if (vfs_get_by_vpath_data.cookie == NULL)
|
||||||
|
is_search_called = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vfs_get_by_vpath_data.cookie = NULL;
|
||||||
|
|
||||||
|
if (is_search_called)
|
||||||
|
super =
|
||||||
|
vfs_get_super_by_cb_conditions (path_element->class, vfs_cb_archive_same,
|
||||||
|
(void *) &vfs_get_by_vpath_data);
|
||||||
|
}
|
||||||
|
vfs_path_free (vfs_get_by_vpath_data.vpath_archive);
|
||||||
|
|
||||||
super = vfs_get_sb_by_vpath (vpath);
|
|
||||||
if (super != NULL)
|
if (super != NULL)
|
||||||
goto return_success;
|
goto return_success;
|
||||||
|
|
||||||
@ -1121,7 +1127,6 @@ vfs_get_super_by_vpath (const vfs_path_t * vpath, gboolean is_create_new)
|
|||||||
|
|
||||||
super = vfs_s_new_super (path_element->class);
|
super = vfs_s_new_super (path_element->class);
|
||||||
|
|
||||||
subclass = ((struct vfs_s_subclass *) path_element->class->data);
|
|
||||||
if (subclass->open_archive != NULL)
|
if (subclass->open_archive != NULL)
|
||||||
{
|
{
|
||||||
vfs_path_t *vpath_archive;
|
vfs_path_t *vpath_archive;
|
||||||
@ -1152,6 +1157,40 @@ vfs_get_super_by_vpath (const vfs_path_t * vpath, gboolean is_create_new)
|
|||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get superblock by callback function.
|
||||||
|
*
|
||||||
|
* @param me class for search superblocks
|
||||||
|
* @param cb_conditions callback function for getting needed superblock
|
||||||
|
* @param cb_data some data for callback
|
||||||
|
*
|
||||||
|
* @return if found, archive pointer to object for store superblock; NULL otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct vfs_s_super *
|
||||||
|
vfs_get_super_by_cb_conditions (struct vfs_class *me, cb_conditions_t * cb_conditions,
|
||||||
|
void *cb_data)
|
||||||
|
{
|
||||||
|
GList *iter;
|
||||||
|
struct vfs_s_subclass *subclass;
|
||||||
|
|
||||||
|
subclass = ((struct vfs_s_subclass *) me->data);
|
||||||
|
if (subclass == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (iter = subclass->supers; iter != NULL; iter = g_list_next (iter))
|
||||||
|
{
|
||||||
|
struct vfs_s_super *super;
|
||||||
|
|
||||||
|
super = (struct vfs_s_super *) iter->data;
|
||||||
|
if (cb_conditions (me, cb_data, super))
|
||||||
|
return super;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void
|
void
|
||||||
vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super)
|
vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super)
|
||||||
{
|
{
|
||||||
|
@ -153,6 +153,9 @@ struct vfs_s_subclass
|
|||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef gboolean (cb_conditions_t) (struct vfs_class * me, void *cb_data,
|
||||||
|
struct vfs_s_super * super);
|
||||||
|
|
||||||
/*** global variables defined in .c file *********************************************************/
|
/*** global variables defined in .c file *********************************************************/
|
||||||
|
|
||||||
/*** declarations of public functions ************************************************************/
|
/*** declarations of public functions ************************************************************/
|
||||||
@ -178,6 +181,9 @@ struct vfs_s_inode *vfs_s_find_root (struct vfs_class *me, struct vfs_s_entry *e
|
|||||||
/* outside interface */
|
/* outside interface */
|
||||||
void vfs_s_init_class (struct vfs_class *vclass, struct vfs_s_subclass *sub);
|
void vfs_s_init_class (struct vfs_class *vclass, struct vfs_s_subclass *sub);
|
||||||
struct vfs_s_super *vfs_get_super_by_vpath (const vfs_path_t * vpath, gboolean is_create_new);
|
struct vfs_s_super *vfs_get_super_by_vpath (const vfs_path_t * vpath, gboolean is_create_new);
|
||||||
|
struct vfs_s_super *vfs_get_super_by_cb_conditions (struct vfs_class *me,
|
||||||
|
cb_conditions_t * cb_conditions, void *cd_data);
|
||||||
|
|
||||||
|
|
||||||
void vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super);
|
void vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super);
|
||||||
char *vfs_s_fullpath (struct vfs_class *me, struct vfs_s_inode *ino);
|
char *vfs_s_fullpath (struct vfs_class *me, struct vfs_s_inode *ino);
|
||||||
|
Loading…
Reference in New Issue
Block a user