Add functions to remove nodes from a dir. Handle deletion of dirs
propertly.
This commit is contained in:
parent
051538b5c2
commit
5ec93b50f4
@ -23,6 +23,7 @@
|
||||
|
||||
#define ISO_NODE_ALREADY_ADDED -50
|
||||
#define ISO_NODE_NAME_NOT_UNIQUE -51
|
||||
#define ISO_NODE_NOT_ADDED_TO_DIR -52
|
||||
|
||||
#define ISO_FILE_ERROR -100
|
||||
#define ISO_FILE_ALREADY_OPENNED -101
|
||||
|
@ -198,4 +198,29 @@ int iso_dir_iter_has_next(IsoDirIter *iter);
|
||||
*/
|
||||
void iso_dir_iter_free(IsoDirIter *iter);
|
||||
|
||||
/**
|
||||
* Removes a child from a directory.
|
||||
* The child is not freed, so you will become the owner of the node. Later
|
||||
* you can add the node to another dir (calling iso_dir_add_node), or free
|
||||
* it if you don't need it (with iso_node_unref).
|
||||
*
|
||||
* @return
|
||||
* 1 on success, < 0 error
|
||||
* Possible errors:
|
||||
* ISO_NULL_POINTER, if node is NULL
|
||||
* ISO_NODE_NOT_ADDED_TO_DIR, if node doesn't belong to a dir
|
||||
*/
|
||||
int iso_node_take(IsoNode *node);
|
||||
|
||||
/**
|
||||
* Removes a child from a directory and free (unref) it.
|
||||
* If you want to keep the child alive, you need to iso_node_ref() it
|
||||
* before this call, but in that case iso_node_take() is a better
|
||||
* alternative.
|
||||
*
|
||||
* @return
|
||||
* 1 on success, < 0 error
|
||||
*/
|
||||
int iso_node_remove(IsoNode *node);
|
||||
|
||||
#endif /*LIBISO_LIBISOFS_H_*/
|
||||
|
79
src/node.c
79
src/node.c
@ -29,7 +29,21 @@ void iso_node_ref(IsoNode *node)
|
||||
void iso_node_unref(IsoNode *node)
|
||||
{
|
||||
if (--node->refcount == 0) {
|
||||
/* TODO #00002 handle deletion of each kind of node */
|
||||
switch(node->type) {
|
||||
case LIBISO_DIR:
|
||||
{
|
||||
IsoNode *child = ((IsoDir*)node)->children;
|
||||
while (child != NULL) {
|
||||
IsoNode *tmp = child->next;
|
||||
iso_node_unref(child);
|
||||
child = tmp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* TODO #00002 handle deletion of each kind of node */
|
||||
break;
|
||||
}
|
||||
free(node->name);
|
||||
free(node);
|
||||
}
|
||||
@ -268,3 +282,66 @@ int iso_dir_iter_has_next(IsoDirIter *iter)
|
||||
}
|
||||
return iter->pos == NULL ? 0 : 1;
|
||||
}
|
||||
|
||||
static IsoNode**
|
||||
iso_dir_find_node(IsoDir *dir, IsoNode *node)
|
||||
{
|
||||
IsoNode **pos;
|
||||
pos = &(dir->children);
|
||||
while (*pos != NULL && *pos != node) {
|
||||
pos = &((*pos)->next);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a child from a directory.
|
||||
* The child is not freed, so you will become the owner of the node. Later
|
||||
* you can add the node to another dir (calling iso_dir_add_node), or free
|
||||
* it if you don't need it (with iso_node_unref).
|
||||
*
|
||||
* @return
|
||||
* 1 on success, < 0 error
|
||||
*/
|
||||
int iso_node_take(IsoNode *node)
|
||||
{
|
||||
IsoNode **pos;
|
||||
IsoDir* dir;
|
||||
|
||||
if (node == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
dir = node->parent;
|
||||
if (dir == NULL) {
|
||||
return ISO_NODE_NOT_ADDED_TO_DIR;
|
||||
}
|
||||
pos = iso_dir_find_node(dir, node);
|
||||
if (pos == NULL) {
|
||||
/* should never occur */
|
||||
return ISO_ERROR;
|
||||
}
|
||||
*pos = node->next;
|
||||
node->parent = NULL;
|
||||
node->next = NULL;
|
||||
dir->nchildren--;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a child from a directory and free (unref) it.
|
||||
* If you want to keep the child alive, you need to iso_node_ref() it
|
||||
* before this call, but in that case iso_node_take() is a better
|
||||
* alternative.
|
||||
*
|
||||
* @return
|
||||
* 1 on success, < 0 error
|
||||
*/
|
||||
int iso_node_remove(IsoNode *node)
|
||||
{
|
||||
int ret;
|
||||
ret = iso_node_take(node);
|
||||
if (ret == ISO_SUCCESS) {
|
||||
iso_node_unref(node);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user