Encapsulate insertion of nodes in node.c. Define replace behavior.

This commit is contained in:
Vreixo Formoso 2008-01-12 18:03:59 +01:00
parent bff5cb9333
commit f118b0a48d
4 changed files with 151 additions and 108 deletions

View File

@ -68,6 +68,27 @@ enum eltorito_boot_media_type {
ELTORITO_NO_EMUL
};
/**
* Replace mode used when addding a node to a file.
* TODO comment
*/
enum iso_replace_mode {
/**
* Never replace an existing node, and instead fail with
* ISO_NODE_NAME_NOT_UNIQUE.
*/
ISO_REPLACE_NEVER,
/**
* Always replace the old node with the new.
*/
ISO_REPLACE_ALWAYS
/*
* TODO #00006 define more values
* -to replace only if both are the same kind of file
* -if both are dirs, add contents (and what to do with conflicts?)
*/
};
/**
* Holds the options for the image generation.
*/
@ -770,11 +791,6 @@ void iso_node_set_hidden(IsoNode *node, int hide_attrs);
* @param replace
* if the dir already contains a node with the same name, whether to
* replace or not the old node with this.
* - 0 not replace (will fail with ISO_NODE_NAME_NOT_UNIQUE)
* - 1 replace
* TODO #00006 define more values
* to replace only if both are the same kind of file
* if both are dirs, add contents (and what to do with conflicts?)
* @return
* number of nodes in dir if succes, < 0 otherwise
* Possible errors:
@ -783,7 +799,8 @@ void iso_node_set_hidden(IsoNode *node, int hide_attrs);
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_WRONG_ARG_VALUE, if child == dir, or replace != (0,1)
*/
int iso_dir_add_node(IsoDir *dir, IsoNode *child, int replace);
int iso_dir_add_node(IsoDir *dir, IsoNode *child,
enum iso_replace_mode replace);
/**
* Locate a node inside a given dir.
@ -1251,7 +1268,7 @@ int iso_image_obtain_msgs(IsoImage *image, char *minimum_severity,
/**
* Return the messenger object handle used by the given image. This handle
* may be used by related libraries to replace their own compatible
* may be used by related libraries to their own compatible
* messenger objects and thus to direct their messages to the libisofs
* message queue. See also: libburn, API function burn_set_messenger().
*

View File

@ -259,10 +259,14 @@ void iso_node_set_hidden(IsoNode *node, int hide_attrs)
* to other dir, and that the node name is unique inside the child.
* Otherwise this function will return a failure, and the child won't be
* inserted.
* @param replace
* if the dir already contains a node with the same name, whether to
* replace or not the old node with this.
* @return
* number of nodes in dir if succes, < 0 otherwise
*/
int iso_dir_add_node(IsoDir *dir, IsoNode *child, int replace)
int iso_dir_add_node(IsoDir *dir, IsoNode *child,
enum iso_replace_mode replace)
{
IsoNode **pos;
@ -281,32 +285,8 @@ int iso_dir_add_node(IsoDir *dir, IsoNode *child, int replace)
return ISO_NODE_ALREADY_ADDED;
}
pos = &(dir->children);
while (*pos != NULL && strcmp((*pos)->name, child->name) < 0) {
pos = &((*pos)->next);
}
if (*pos != NULL && !strcmp((*pos)->name, child->name)) {
/* a node with same name already exists */
if (replace == 0) {
return ISO_NODE_NAME_NOT_UNIQUE;
} else if (replace == 1) {
child->next = (*pos)->next;
(*pos)->parent = NULL;
(*pos)->next = NULL;
iso_node_unref(*pos);
*pos = child;
child->parent = dir;
return dir->nchildren;
} else {
return ISO_WRONG_ARG_VALUE;
}
}
child->next = *pos;
*pos = child;
child->parent = dir;
return ++dir->nchildren;
iso_dir_find(dir, child->name, &pos);
return iso_dir_insert(dir, child, pos, replace);
}
/**
@ -328,17 +308,14 @@ int iso_dir_add_node(IsoDir *dir, IsoNode *child, int replace)
*/
int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node)
{
IsoNode *pos;
int ret;
IsoNode **pos;
if (dir == NULL || name == NULL) {
return ISO_NULL_POINTER;
}
pos = dir->children;
while (pos != NULL && strcmp(pos->name, name) < 0) {
pos = pos->next;
}
if (pos == NULL || strcmp(pos->name, name)) {
ret = iso_dir_exists(dir, name, &pos);
if (ret == 0) {
if (node) {
*node = NULL;
}
@ -346,7 +323,7 @@ int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node)
}
if (node) {
*node = pos;
*node = *pos;
}
return 1;
}
@ -686,6 +663,53 @@ int iso_node_is_valid_link_dest(const char *dest)
return ret;
}
void iso_dir_find(IsoDir *dir, const char *name, IsoNode ***pos)
{
*pos = &(dir->children);
while (**pos != NULL && strcmp((**pos)->name, name) < 0) {
*pos = &((**pos)->next);
}
}
int iso_dir_exists(IsoDir *dir, const char *name, IsoNode ***pos)
{
IsoNode **node;
iso_dir_find(dir, name, &node);
if (pos) {
*pos = node;
}
return (*node != NULL && !strcmp((*node)->name, name)) ? 1 : 0;
}
int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos,
enum iso_replace_mode replace)
{
if (*pos != NULL && !strcmp((*pos)->name, node->name)) {
/* a node with same name already exists */
if (replace == ISO_REPLACE_NEVER) {
return ISO_NODE_NAME_NOT_UNIQUE;
} else if (replace == ISO_REPLACE_ALWAYS) {
node->next = (*pos)->next;
(*pos)->parent = NULL;
(*pos)->next = NULL;
iso_node_unref(*pos);
*pos = node;
node->parent = dir;
return dir->nchildren;
} else {
/* CAN'T HAPPEN */
return ISO_WRONG_ARG_VALUE;
}
}
node->next = *pos;
*pos = node;
node->parent = dir;
return ++dir->nchildren;
}
int iso_node_new_root(IsoDir **root)
{
IsoDir *dir;

View File

@ -123,4 +123,50 @@ int iso_node_is_valid_name(const char *name);
*/
int iso_node_is_valid_link_dest(const char *dest);
/**
* Find the position where to insert a node
*
* @param dir
* A valid dir. It can't be NULL
* @param name
* The node name to search for. It can't be NULL
* @param pos
* Will be filled with the position where to insert. It can't be NULL
*/
void iso_dir_find(IsoDir *dir, const char *name, IsoNode ***pos);
/**
* Check if a node with the given name exists in a dir.
*
* @param dir
* A valid dir. It can't be NULL
* @param name
* The node name to search for. It can't be NULL
* @param pos
* If not NULL, will be filled with the position where to insert. If the
* node exists, (**pos) will refer to the given node.
* @return
* 1 if node exists, 0 if not
*/
int iso_dir_exists(IsoDir *dir, const char *name, IsoNode ***pos);
/**
* Inserts a given node in a dir, at the specified position.
*
* @param dir
* Dir where to insert. It can't be NULL
* @param node
* The node to insert. It can't be NULL
* @param pos
* Position where the node will be inserted. It is a pointer previously
* obtained with a call to iso_dir_exists() or iso_dir_find().
* It can't be NULL.
* @param replace
* Whether to replace an old node with the same name with the new node.
* @return
* If success, number of children in dir. < 0 on error
*/
int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos,
enum iso_replace_mode replace);
#endif /*LIBISO_NODE_H_*/

View File

@ -62,12 +62,8 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir)
return ISO_WRONG_ARG_VALUE;
}
/* find place where to insert */
pos = &(parent->children);
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
pos = &((*pos)->next);
}
if (*pos != NULL && !strcmp((*pos)->name, name)) {
/* find place where to insert and check if it exists */
if (iso_dir_exists(parent, name, &pos)) {
/* a node with same name already exists */
return ISO_NODE_NAME_NOT_UNIQUE;
}
@ -97,15 +93,12 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir)
node->node.ctime = now;
node->node.mtime = now;
/* add to dir */
node->node.parent = parent;
node->node.next = *pos;
*pos = (IsoNode*)node;
if (dir) {
*dir = node;
}
return ++parent->nchildren;
/* add to dir */
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
}
/**
@ -158,11 +151,7 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
}
/* find place where to insert */
pos = &(parent->children);
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
pos = &((*pos)->next);
}
if (*pos != NULL && !strcmp((*pos)->name, name)) {
if (iso_dir_exists(parent, name, &pos)) {
/* a node with same name already exists */
return ISO_NODE_NAME_NOT_UNIQUE;
}
@ -199,15 +188,12 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
node->node.ctime = now;
node->node.mtime = now;
/* add to dir */
node->node.parent = parent;
node->node.next = *pos;
*pos = (IsoNode*)node;
if (link) {
*link = node;
}
return ++parent->nchildren;
/* add to dir */
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
}
/**
@ -271,11 +257,7 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode,
}
/* find place where to insert */
pos = &(parent->children);
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
pos = &((*pos)->next);
}
if (*pos != NULL && !strcmp((*pos)->name, name)) {
if (iso_dir_exists(parent, name, &pos)) {
/* a node with same name already exists */
return ISO_NODE_NAME_NOT_UNIQUE;
}
@ -307,15 +289,12 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode,
node->node.ctime = now;
node->node.mtime = now;
/* add to dir */
node->node.parent = parent;
node->node.next = *pos;
*pos = (IsoNode*)node;
if (special) {
*special = node;
}
return ++parent->nchildren;
/* add to dir */
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
}
/**
@ -395,30 +374,24 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
name = iso_file_source_get_name(src);
/* find place where to insert */
pos = &(parent->children);
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
pos = &((*pos)->next);
}
if (*pos != NULL && !strcmp((*pos)->name, name)) {
result = iso_dir_exists(parent, name, &pos);
free(name);
if (result) {
/* a node with same name already exists */
return ISO_NODE_NAME_NOT_UNIQUE;
}
free(name);
result = builder->create_node(builder, image, src, &new);
if (result < 0) {
return result;
}
/* finally, add node to parent */
new->parent = parent;
new->next = *pos;
*pos = new;
if (node) {
*node = new;
}
return ++parent->nchildren;
/* finally, add node to parent */
return iso_dir_insert(parent, (IsoNode*)new, pos, ISO_REPLACE_NEVER);
}
int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
@ -513,11 +486,7 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
/* find place where to insert */
flag = 0;
pos = &(parent->children);
while (*pos != NULL && strcmp((*pos)->name, name) < 0) {
pos = &((*pos)->next);
}
if (*pos != NULL && !strcmp((*pos)->name, name)) {
if (iso_dir_exists(parent, name, &pos)) {
flag = 1;
if (action == 1 && image->recOpts.replace == 0) {
action = 2;
@ -569,21 +538,8 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
}
/* ok, node has correctly created, we need to add it */
if (flag) {
/* replace node */
new->next = (*pos)->next;
(*pos)->parent = NULL;
(*pos)->next = NULL;
iso_node_unref(*pos);
*pos = new;
new->parent = parent;
} else {
/* just add */
new->next = *pos;
*pos = new;
new->parent = parent;
++parent->nchildren;
}
iso_dir_insert(parent, new, pos, flag ? ISO_REPLACE_ALWAYS :
ISO_REPLACE_NEVER);
/* finally, if the node is a directory we need to recurse */
if (new->type == LIBISO_DIR) {