Add functions to iterate over directory children.
This commit is contained in:
parent
e068fd1cf6
commit
051538b5c2
@ -13,6 +13,7 @@
|
||||
typedef struct Iso_Node IsoNode;
|
||||
typedef struct Iso_Dir IsoDir;
|
||||
typedef struct Iso_Symlink IsoSymlink;
|
||||
typedef struct Iso_Dir_Iter IsoDirIter;
|
||||
|
||||
/**
|
||||
* Increments the reference counting of the given node.
|
||||
@ -134,4 +135,67 @@ int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node);
|
||||
*/
|
||||
int iso_dir_get_nchildren(IsoDir *dir);
|
||||
|
||||
/**
|
||||
* Get an iterator for the children of the given dir.
|
||||
*
|
||||
* You can iterate over the children with iso_dir_iter_next. When finished,
|
||||
* you should free the iterator with iso_dir_iter_free.
|
||||
* You musn't delete a child of the same dir, using iso_node_take() or
|
||||
* iso_node_remove(), while you're using the iterator. You can use
|
||||
* iso_node_take_iter() or iso_node_remove_iter() instead.
|
||||
*
|
||||
* You can use the iterator in the way like this
|
||||
*
|
||||
* IsoDirIter *iter;
|
||||
* IsoNode *node;
|
||||
* if ( iso_dir_get_children(dir, &iter) != 1 ) {
|
||||
* // handle error
|
||||
* }
|
||||
* while ( iso_dir_iter_next(iter, &node) == 1 ) {
|
||||
* // do something with the child
|
||||
* }
|
||||
* iso_dir_iter_free(iter);
|
||||
*
|
||||
* An iterator is intended to be used in a single iteration over the
|
||||
* children of a dir. Thus, it should be treated as a temporary object,
|
||||
* and free as soon as possible.
|
||||
*
|
||||
* @return
|
||||
* 1 success, < 0 error
|
||||
* Possible errors:
|
||||
* ISO_NULL_POINTER, if dir or iter are NULL
|
||||
* ISO_OUT_OF_MEM
|
||||
*/
|
||||
int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter);
|
||||
|
||||
/**
|
||||
* Get the next child.
|
||||
* Take care that the node is owned by its parent, and will be unref() when
|
||||
* the parent is freed. If you want your own ref to it, call iso_node_ref()
|
||||
* on it.
|
||||
*
|
||||
* @return
|
||||
* 1 success, 0 if dir has no more elements, < 0 error
|
||||
* Possible errors:
|
||||
* ISO_NULL_POINTER, if node or iter are NULL
|
||||
* ISO_ERROR, on wrong iter usage, usual caused by modiying the
|
||||
* dir during iteration
|
||||
*/
|
||||
int iso_dir_iter_next(IsoDirIter *iter, IsoNode **node);
|
||||
|
||||
/**
|
||||
* Check if there're more children.
|
||||
*
|
||||
* @return
|
||||
* 1 dir has more elements, 0 no, < 0 error
|
||||
* Possible errors:
|
||||
* ISO_NULL_POINTER, if iter is NULL
|
||||
*/
|
||||
int iso_dir_iter_has_next(IsoDirIter *iter);
|
||||
|
||||
/**
|
||||
* Free a dir iterator.
|
||||
*/
|
||||
void iso_dir_iter_free(IsoDirIter *iter);
|
||||
|
||||
#endif /*LIBISO_LIBISOFS_H_*/
|
||||
|
54
src/node.c
54
src/node.c
@ -214,3 +214,57 @@ int iso_dir_get_nchildren(IsoDir *dir)
|
||||
}
|
||||
return dir->nchildren;
|
||||
}
|
||||
|
||||
int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter)
|
||||
{
|
||||
IsoDirIter *it;
|
||||
|
||||
if (dir == NULL || iter == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
it = malloc(sizeof(IsoDirIter));
|
||||
if (it == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
it->dir = dir;
|
||||
it->pos = dir->children;
|
||||
|
||||
*iter = it;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_dir_iter_next(IsoDirIter *iter, IsoNode **node)
|
||||
{
|
||||
IsoNode *n;
|
||||
if (iter == NULL || node == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
n = iter->pos;
|
||||
if (n == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (n->parent != iter->dir) {
|
||||
/* this can happen if the node has been moved to another dir */
|
||||
return ISO_ERROR;
|
||||
}
|
||||
*node = n;
|
||||
iter->pos = n->next;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there're more children.
|
||||
*
|
||||
* @return
|
||||
* 1 dir has more elements, 0 no, < 0 error
|
||||
* Possible errors:
|
||||
* ISO_NULL_POINTER, if iter is NULL
|
||||
*/
|
||||
int iso_dir_iter_has_next(IsoDirIter *iter)
|
||||
{
|
||||
if (iter == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
return iter->pos == NULL ? 0 : 1;
|
||||
}
|
||||
|
10
src/node.h
10
src/node.h
@ -107,4 +107,14 @@ struct Iso_Symlink
|
||||
char *dest;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* An iterator for directory children.
|
||||
*/
|
||||
struct Iso_Dir_Iter
|
||||
{
|
||||
const IsoDir *dir;
|
||||
IsoNode *pos;
|
||||
};
|
||||
|
||||
#endif /*LIBISO_NODE_H_*/
|
||||
|
Loading…
Reference in New Issue
Block a user