Switch to Vreixo development branch 383
This commit is contained in:
parent
b57ae766f5
commit
e50b3b6492
@ -55,6 +55,8 @@ libisofs_libisofs_la_SOURCES = \
|
|||||||
libisofs/iso1999.h \
|
libisofs/iso1999.h \
|
||||||
libisofs/iso1999.c \
|
libisofs/iso1999.c \
|
||||||
libisofs/data_source.c
|
libisofs/data_source.c
|
||||||
|
libisofs_libisofs_la_LIBADD= \
|
||||||
|
$(THREAD_LIBS)
|
||||||
libinclude_HEADERS = \
|
libinclude_HEADERS = \
|
||||||
libisofs/libisofs.h
|
libisofs/libisofs.h
|
||||||
|
|
||||||
|
@ -93,13 +93,20 @@ int find_iter_remove(IsoDirIter *iter)
|
|||||||
return iso_dir_iter_remove(data->iter);
|
return iso_dir_iter_remove(data->iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void find_notify_child_taken(IsoDirIter *iter, IsoNode *node)
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
struct iso_dir_iter_iface find_iter_class = {
|
struct iso_dir_iter_iface find_iter_class = {
|
||||||
find_iter_next,
|
find_iter_next,
|
||||||
find_iter_has_next,
|
find_iter_has_next,
|
||||||
find_iter_free,
|
find_iter_free,
|
||||||
find_iter_take,
|
find_iter_take,
|
||||||
find_iter_remove
|
find_iter_remove,
|
||||||
|
find_notify_child_taken
|
||||||
};
|
};
|
||||||
|
|
||||||
int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
|
int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
|
||||||
@ -134,6 +141,11 @@ int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
|
|||||||
data->iter = children;
|
data->iter = children;
|
||||||
data->cond = cond;
|
data->cond = cond;
|
||||||
it->data = data;
|
it->data = data;
|
||||||
|
|
||||||
|
if (iso_dir_iter_register(it) < 0) {
|
||||||
|
free(it);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
*iter = it;
|
*iter = it;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
@ -2731,6 +2731,35 @@ void iso_tree_set_report_callback(IsoImage *image,
|
|||||||
int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
|
int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
|
||||||
IsoNode **node);
|
IsoNode **node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new node to the image tree, from an existing file, and with the
|
||||||
|
* given name, that must not exist on dir.
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
* The image
|
||||||
|
* @param parent
|
||||||
|
* The directory in the image tree where the node will be added.
|
||||||
|
* @param name
|
||||||
|
* The name that the node will have on image.
|
||||||
|
* @param path
|
||||||
|
* The path of the file to add in the filesystem.
|
||||||
|
* @param node
|
||||||
|
* place where to store a pointer to the newly added file. No
|
||||||
|
* extra ref is addded, so you will need to call iso_node_ref() if you
|
||||||
|
* really need it. You can pass NULL in this parameter if you don't need
|
||||||
|
* the pointer.
|
||||||
|
* @return
|
||||||
|
* number of nodes in parent if success, < 0 otherwise
|
||||||
|
* Possible errors:
|
||||||
|
* ISO_NULL_POINTER, if image, parent or path are NULL
|
||||||
|
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
|
||||||
|
* ISO_OUT_OF_MEM
|
||||||
|
*
|
||||||
|
* @since 0.6.4
|
||||||
|
*/
|
||||||
|
int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
||||||
|
const char *path, IsoNode **node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the contents of a dir to a given directory of the iso tree.
|
* Add the contents of a dir to a given directory of the iso tree.
|
||||||
*
|
*
|
||||||
|
139
libisofs/node.c
139
libisofs/node.c
@ -485,6 +485,10 @@ int iso_node_take(IsoNode *node)
|
|||||||
/* should never occur */
|
/* should never occur */
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* notify iterators just before remove */
|
||||||
|
iso_notify_dir_iters(node, 0);
|
||||||
|
|
||||||
*pos = node->next;
|
*pos = node->next;
|
||||||
node->parent = NULL;
|
node->parent = NULL;
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
@ -531,7 +535,6 @@ static
|
|||||||
int iter_take(IsoDirIter *iter)
|
int iter_take(IsoDirIter *iter)
|
||||||
{
|
{
|
||||||
struct dir_iter_data *data;
|
struct dir_iter_data *data;
|
||||||
IsoNode *pos, *pre;
|
|
||||||
if (iter == NULL) {
|
if (iter == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
@ -549,38 +552,7 @@ int iter_take(IsoDirIter *iter)
|
|||||||
/* clear next flag */
|
/* clear next flag */
|
||||||
data->flag &= ~0x01;
|
data->flag &= ~0x01;
|
||||||
|
|
||||||
pos = iter->dir->children;
|
return iso_node_take(data->pos);
|
||||||
pre = NULL;
|
|
||||||
while (pos != NULL && pos != data->pos) {
|
|
||||||
pre = pos;
|
|
||||||
pos = pos->next;
|
|
||||||
}
|
|
||||||
if (pos == NULL) {
|
|
||||||
return ISO_ERROR; /* node not in dir */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos != data->pos) {
|
|
||||||
return ISO_ASSERT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dispose iterator reference */
|
|
||||||
iso_node_unref(data->pos);
|
|
||||||
|
|
||||||
if (pre == NULL) {
|
|
||||||
/* node is a first position */
|
|
||||||
iter->dir->children = pos->next;
|
|
||||||
data->pos = NULL;
|
|
||||||
} else {
|
|
||||||
pre->next = pos->next;
|
|
||||||
data->pos = pre;
|
|
||||||
iso_node_ref(pre); /* take iter ref */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* take pos */
|
|
||||||
pos->parent = NULL;
|
|
||||||
pos->next = NULL;
|
|
||||||
iter->dir->nchildren--;
|
|
||||||
return ISO_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -601,19 +573,49 @@ int iter_remove(IsoDirIter *iter)
|
|||||||
/* remove node */
|
/* remove node */
|
||||||
iso_node_unref(pos);
|
iso_node_unref(pos);
|
||||||
}
|
}
|
||||||
if (data->pos == pos) {
|
|
||||||
return ISO_ERROR;
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iter_notify_child_taken(IsoDirIter *iter, IsoNode *node)
|
||||||
|
{
|
||||||
|
IsoNode *pos, *pre;
|
||||||
|
struct dir_iter_data *data;
|
||||||
|
data = iter->data;
|
||||||
|
|
||||||
|
if (data->pos == node) {
|
||||||
|
pos = iter->dir->children;
|
||||||
|
pre = NULL;
|
||||||
|
while (pos != NULL && pos != data->pos) {
|
||||||
|
pre = pos;
|
||||||
|
pos = pos->next;
|
||||||
|
}
|
||||||
|
if (pos == NULL || pos != data->pos) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dispose iterator reference */
|
||||||
|
iso_node_unref(data->pos);
|
||||||
|
|
||||||
|
if (pre == NULL) {
|
||||||
|
/* node is a first position */
|
||||||
|
iter->dir->children = pos->next;
|
||||||
|
data->pos = NULL;
|
||||||
|
} else {
|
||||||
|
pre->next = pos->next;
|
||||||
|
data->pos = pre;
|
||||||
|
iso_node_ref(pre); /* take iter ref */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
struct iso_dir_iter_iface iter_class = {
|
struct iso_dir_iter_iface iter_class = {
|
||||||
iter_next,
|
iter_next,
|
||||||
iter_has_next,
|
iter_has_next,
|
||||||
iter_free,
|
iter_free,
|
||||||
iter_take,
|
iter_take,
|
||||||
iter_remove
|
iter_remove,
|
||||||
|
iter_notify_child_taken
|
||||||
};
|
};
|
||||||
|
|
||||||
int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter)
|
int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter)
|
||||||
@ -639,6 +641,11 @@ int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter)
|
|||||||
data->pos = NULL;
|
data->pos = NULL;
|
||||||
data->flag = 0x00;
|
data->flag = 0x00;
|
||||||
it->data = data;
|
it->data = data;
|
||||||
|
|
||||||
|
if (iso_dir_iter_register(it) < 0) {
|
||||||
|
free(it);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
*iter = it;
|
*iter = it;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -663,6 +670,7 @@ int iso_dir_iter_has_next(IsoDirIter *iter)
|
|||||||
void iso_dir_iter_free(IsoDirIter *iter)
|
void iso_dir_iter_free(IsoDirIter *iter)
|
||||||
{
|
{
|
||||||
if (iter != NULL) {
|
if (iter != NULL) {
|
||||||
|
iso_dir_iter_unregister(iter);
|
||||||
iter->class->free(iter);
|
iter->class->free(iter);
|
||||||
free(iter);
|
free(iter);
|
||||||
}
|
}
|
||||||
@ -970,6 +978,63 @@ int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos,
|
|||||||
return ++dir->nchildren;
|
return ++dir->nchildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* iterators are stored in a linked list */
|
||||||
|
struct iter_reg_node {
|
||||||
|
IsoDirIter *iter;
|
||||||
|
struct iter_reg_node *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* list header */
|
||||||
|
static
|
||||||
|
struct iter_reg_node *iter_reg = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new iterator to the registry. The iterator register keeps track of
|
||||||
|
* all iterators being used, and are notified when directory structure
|
||||||
|
* changes.
|
||||||
|
*/
|
||||||
|
int iso_dir_iter_register(IsoDirIter *iter)
|
||||||
|
{
|
||||||
|
struct iter_reg_node *new;
|
||||||
|
new = malloc(sizeof(struct iter_reg_node));
|
||||||
|
if (new == NULL) {
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
new->iter = iter;
|
||||||
|
new->next = iter_reg;
|
||||||
|
iter_reg = new;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister a directory iterator.
|
||||||
|
*/
|
||||||
|
void iso_dir_iter_unregister(IsoDirIter *iter)
|
||||||
|
{
|
||||||
|
struct iter_reg_node **pos;
|
||||||
|
pos = &iter_reg;
|
||||||
|
while (*pos != NULL && (*pos)->iter != iter) {
|
||||||
|
pos = &(*pos)->next;
|
||||||
|
}
|
||||||
|
if (*pos) {
|
||||||
|
struct iter_reg_node *tmp = (*pos)->next;
|
||||||
|
free(*pos);
|
||||||
|
*pos = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void iso_notify_dir_iters(IsoNode *node, int flag)
|
||||||
|
{
|
||||||
|
struct iter_reg_node *pos = iter_reg;
|
||||||
|
while (pos != NULL) {
|
||||||
|
IsoDirIter *iter = pos->iter;
|
||||||
|
if (iter->dir == node->parent) {
|
||||||
|
iter->class->notify_child_taken(iter, node);
|
||||||
|
}
|
||||||
|
pos = pos->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int iso_node_new_root(IsoDir **root)
|
int iso_node_new_root(IsoDir **root)
|
||||||
{
|
{
|
||||||
IsoDir *dir;
|
IsoDir *dir;
|
||||||
|
@ -161,6 +161,11 @@ struct iso_dir_iter_iface
|
|||||||
|
|
||||||
int (*remove)(IsoDirIter *iter);
|
int (*remove)(IsoDirIter *iter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called just before remove a node from a directory. The iterator
|
||||||
|
* may want to update its internal state according to this.
|
||||||
|
*/
|
||||||
|
void (*notify_child_taken)(IsoDirIter *iter, IsoNode *node);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -322,4 +327,18 @@ int iso_dir_exists(IsoDir *dir, const char *name, IsoNode ***pos);
|
|||||||
int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos,
|
int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos,
|
||||||
enum iso_replace_mode replace);
|
enum iso_replace_mode replace);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new iterator to the registry. The iterator register keeps track of
|
||||||
|
* all iterators being used, and are notified when directory structure
|
||||||
|
* changes.
|
||||||
|
*/
|
||||||
|
int iso_dir_iter_register(IsoDirIter *iter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister a directory iterator.
|
||||||
|
*/
|
||||||
|
void iso_dir_iter_unregister(IsoDirIter *iter);
|
||||||
|
|
||||||
|
void iso_notify_dir_iters(IsoNode *node, int flag);
|
||||||
|
|
||||||
#endif /*LIBISO_NODE_H_*/
|
#endif /*LIBISO_NODE_H_*/
|
||||||
|
@ -475,6 +475,59 @@ int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
||||||
|
const char *path, IsoNode **node)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
IsoFilesystem *fs;
|
||||||
|
IsoFileSource *file;
|
||||||
|
IsoNode *new;
|
||||||
|
IsoNode **pos;
|
||||||
|
|
||||||
|
if (image == NULL || parent == NULL || name == NULL || path == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node) {
|
||||||
|
*node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs = image->fs;
|
||||||
|
result = fs->get_by_path(fs, path, &file);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find place where to insert */
|
||||||
|
result = iso_dir_exists(parent, name, &pos);
|
||||||
|
if (result) {
|
||||||
|
/* a node with same name already exists */
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = image->builder->create_node(image->builder, image, file, &new);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free the file */
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
|
||||||
|
result = iso_node_set_name(new, name);
|
||||||
|
if (result < 0) {
|
||||||
|
iso_node_unref(new);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node) {
|
||||||
|
*node = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finally, add node to parent */
|
||||||
|
return iso_dir_insert(parent, new, pos, ISO_REPLACE_NEVER);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int check_excludes(IsoImage *image, const char *path)
|
int check_excludes(IsoImage *image, const char *path)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user