Switch to Vreixo development branch 383

This commit is contained in:
Thomas Schmitt 2008-03-08 09:09:43 +00:00
parent b57ae766f5
commit e50b3b6492
6 changed files with 218 additions and 38 deletions

View File

@ -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

View File

@ -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;

View File

@ -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.
* *

View File

@ -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;

View File

@ -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_*/

View File

@ -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)
{ {