Commit 979a3826 979a3826c2fe809b9a491ac8878da7a575f6dfb6 by Sergey Poznyakoff

(iterator_create): Changed proto.

(iterator_attach,iterator_detach,iterator_advance)
(iterator_set_first,iterator_set_next)
(iterator_set_getitem,iterator_set_finished_p)
(iterator_set_dup,iterator_set_destroy): New functions.
1 parent e6066cdd
......@@ -24,7 +24,7 @@
extern "C" {
#endif
extern int iterator_create __P ((iterator_t *, list_t));
extern int iterator_create __P ((iterator_t *, void *));
extern int iterator_dup __P ((iterator_t *piterator, iterator_t orig));
extern void iterator_destroy __P ((iterator_t *));
extern int iterator_first __P ((iterator_t));
......@@ -32,6 +32,23 @@ extern int iterator_next __P ((iterator_t));
extern int iterator_current __P ((iterator_t, void **pitem));
extern int iterator_is_done __P ((iterator_t));
extern int iterator_get_list __P ((iterator_t iterator, list_t *plist));
extern int iterator_attach (iterator_t *root, iterator_t iterator);
extern int iterator_detach (iterator_t *root, iterator_t iterator);
extern void iterator_advance (iterator_t iterator, void *e);
extern int iterator_set_first (iterator_t, int (*first) (void *));
extern int iterator_set_next (iterator_t, int (*next) (void *));
extern int iterator_set_getitem (iterator_t,
int (*getitem) (void *, void **));
extern int iterator_set_finished_p (iterator_t,
int (*finished_p) (void *));
extern int iterator_set_dup (iterator_t itr,
int (dup) (void **ptr, void *data));
extern int iterator_set_destroy (iterator_t itr,
int (destroy) (iterator_t, void *data));
extern int iterator_set_curitem_p (iterator_t itr,
int (*curitem_p) (void *, void *));
#ifdef __cplusplus
}
......
......@@ -27,42 +27,117 @@
#include <mailutils/errno.h>
int
iterator_create (iterator_t *piterator, list_t list)
iterator_create (iterator_t *piterator, void *owner)
{
iterator_t iterator;
if (piterator == NULL)
return MU_ERR_OUT_PTR_NULL;
if (list == NULL)
if (owner == NULL)
return EINVAL;
iterator = calloc (sizeof (*iterator), 1);
if (iterator == NULL)
return ENOMEM;
iterator->list = list;
iterator->cur = NULL;
iterator->next = list->itr;
list->itr = iterator;
iterator->is_advanced = 0;
iterator->owner = owner;
*piterator = iterator;
return 0;
}
int
iterator_set_first (iterator_t itr, int (*first) (void *))
{
if (!itr)
return EINVAL;
itr->first = first;
return 0;
}
int
iterator_set_next (iterator_t itr, int (*next) (void *))
{
if (!itr)
return EINVAL;
itr->next = next;
return 0;
}
int
iterator_set_getitem (iterator_t itr, int (*getitem) (void *, void **))
{
if (!itr)
return EINVAL;
itr->getitem = getitem;
return 0;
}
int
iterator_set_finished_p (iterator_t itr, int (*finished_p) (void *))
{
if (!itr)
return EINVAL;
itr->finished_p = finished_p;
return 0;
}
int
iterator_set_curitem_p (iterator_t itr,
int (*curitem_p) (void *, void *))
{
if (!itr)
return EINVAL;
itr->curitem_p = curitem_p;
return 0;
}
int
iterator_set_destroy (iterator_t itr, int (destroy) (iterator_t, void *))
{
if (!itr)
return EINVAL;
itr->destroy = destroy;
return 0;
}
int
iterator_set_dup (iterator_t itr, int (dup) (void **ptr, void *data))
{
if (!itr)
return EINVAL;
itr->dup = dup;
return 0;
}
int
iterator_dup (iterator_t *piterator, iterator_t orig)
{
iterator_t iterator;
int status;
if (piterator == NULL)
return MU_ERR_OUT_PTR_NULL;
if (orig == NULL)
return EINVAL;
iterator = calloc (sizeof (*iterator), 1);
if (iterator == NULL)
return ENOMEM;
iterator->list = orig->list;
iterator->cur = orig->cur;
iterator->is_advanced = orig->is_advanced;
iterator->next = orig->list->itr;
orig->list->itr = iterator;
status = iterator_create (&iterator, orig->owner);
if (status)
return status;
status = orig->dup(&iterator->owner, orig->owner);
if (status)
{
free (iterator);
return status;
}
iterator->is_advanced = orig->is_advanced;
iterator->first = orig->first;
iterator->next = orig->next;
iterator->getitem = orig->getitem;
iterator->finished_p = orig->finished_p;
iterator->curitem_p = orig->curitem_p;
iterator->dup = orig->dup;
iterator->destroy = orig->destroy;
*piterator = iterator;
return 0;
}
......@@ -70,52 +145,37 @@ iterator_dup (iterator_t *piterator, iterator_t orig)
void
iterator_destroy (iterator_t *piterator)
{
iterator_t itr, prev;
if (!piterator || !*piterator)
return;
for (itr = (*piterator)->list->itr, prev = NULL;
itr;
prev = itr, itr = itr->next)
if (*piterator == itr)
break;
if (itr)
{
if (prev)
prev->next = itr->next;
else
itr->list->itr = itr->next;
free(itr);
*piterator = NULL;
}
if ((*piterator)->destroy)
(*piterator)->destroy (*piterator, (*piterator)->owner);
free (*piterator);
*piterator = NULL;
}
int
iterator_first (iterator_t iterator)
{
iterator->cur = iterator->list->head.next;
iterator->is_advanced = 0;
return 0;
return iterator->first (iterator->owner);
}
int
iterator_next (iterator_t iterator)
{
int status = 0;
if (!iterator->is_advanced)
iterator->cur = iterator->cur->next;
status = iterator->next (iterator->owner);
iterator->is_advanced = 0;
return 0;
return status;
}
int
iterator_current (iterator_t iterator, void **pitem)
{
if (!iterator->cur)
return MU_ERR_NOENT;
*pitem = iterator->cur->item;
return 0;
return iterator->getitem (iterator->owner, pitem);
}
int
......@@ -123,29 +183,57 @@ iterator_is_done (iterator_t iterator)
{
if (iterator == NULL)
return 1;
return iterator->cur == NULL || iterator->cur == &iterator->list->head;
return iterator->finished_p (iterator->owner);
}
int
iterator_get_list (iterator_t iterator, list_t *plist)
iterator_get_owner (iterator_t iterator, void **powner)
{
if (!iterator)
return EINVAL;
if (!plist)
if (!powner)
return MU_ERR_OUT_PTR_NULL;
*plist = iterator->list;
*powner = iterator->owner;
return 0;
}
void
iterator_advance (iterator_t iterator, struct list_data *e)
iterator_advance (iterator_t iterator, void *e)
{
for (; iterator; iterator = iterator->next)
for (; iterator; iterator = iterator->next_itr)
{
if (iterator->cur == e)
if (iterator->curitem_p (iterator->owner, e))
{
iterator->cur = e->next;
iterator->next (iterator->owner);
iterator->is_advanced++;
}
}
}
int
iterator_attach (iterator_t *root, iterator_t iterator)
{
iterator->next_itr = *root;
*root = iterator;
return 0;
}
int
iterator_detach (iterator_t *root, iterator_t iterator)
{
iterator_t itr, prev;
for (itr = *root, prev = NULL; itr; prev = itr, itr = itr->next_itr)
if (iterator == itr)
break;
if (itr)
{
if (prev)
prev->next = itr->next;
else
*root = itr->next_itr;
}
return 0;
}
......