Commit 28e9a0a0 28e9a0a06b996595db2dd7ad64c9adced80d3aca by Sergey Poznyakoff

Add iterator support to opool.

* include/mailutils/opool.h (mu_opool_get_iterator): New function.
* mailbox/opool.c (mu_opool_get_iterator): New function.
* mailbox/hdritr.c (hdr_data_dup): Bugfix: notify owner about the
new iterator.
1 parent 5845efba
2008-11-27 Sergey Poznyakoff <gray@gnu.org.ua>
Add iterator support to opool.
* include/mailutils/opool.h (mu_opool_get_iterator): New function.
* mailbox/opool.c (mu_opool_get_iterator): New function.
* mailbox/hdritr.c (hdr_data_dup): Bugfix: notify owner about the
new iterator.
2008-11-21 Sergey Poznyakoff <gray@gnu.org.ua>
* auth/sql.c (get_field): NULL value in an optional field is
......
......@@ -216,10 +216,10 @@ static struct argp argp = {
static const char *frm_argp_capa[] = {
"common",
"debug",
"license",
"mailbox",
"locking",
"debug",
NULL
};
......
......@@ -75,9 +75,6 @@ static const char *capa[] = {
"license",
"mailbox",
"locking",
#ifdef WITH_TLS
"tls",
#endif
NULL
};
......@@ -118,6 +115,9 @@ main (int argc, char **argv)
/* register the formats. */
mu_register_all_mbox_formats ();
#ifdef WITH_TLS
mu_gocs_register ("tls", mu_tls_module_init);
#endif
mu_argp_init (program_version, NULL);
if (mu_app_init (&argp, capa, NULL, argc, argv, 0, &c, NULL))
......
......@@ -68,4 +68,6 @@ void *mu_opool_head (mu_opool_t opool, size_t *psize);
return p; */
void *mu_opool_finish (mu_opool_t opool, size_t *psize);
int mu_opool_get_iterator (mu_opool_t opool, mu_iterator_t *piterator);
#endif
......
......@@ -106,10 +106,13 @@ hdr_curitem_p (void *owner, void *item)
static int
hdr_data_dup (void **ptr, void *owner)
{
struct header_iterator *itr = owner;
*ptr = malloc (sizeof (struct header_iterator));
if (*ptr == NULL)
return ENOMEM;
memcpy (*ptr, owner, sizeof (struct header_iterator));
mu_iterator_attach (&itr->header->itr, *ptr);
return 0;
}
......
......@@ -23,10 +23,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <mailutils/types.h>
#include <mailutils/alloc.h>
#include <mailutils/opool.h>
#include <mailutils/errno.h>
#include <mailutils/error.h>
#include <mailutils/nls.h>
#include <mailutils/iterator.h>
struct mu_opool_bucket
{
......@@ -39,6 +42,7 @@ struct mu_opool_bucket
struct _mu_opool
{
int memerr;
size_t itr_count;
struct mu_opool_bucket *head, *tail;
struct mu_opool_bucket *free;
};
......@@ -104,6 +108,7 @@ mu_opool_create (mu_opool_t *pret, int memerr)
return ENOMEM;
}
x->memerr = memerr;
x->itr_count = 0;
x->head = x->tail = x->free = 0;
*pret = x;
return 0;
......@@ -185,6 +190,8 @@ mu_opool_coalesce (mu_opool_t opool, size_t *psize)
{
size_t size;
if (opool->itr_count)
return MU_ERR_FAILURE;
if (opool->head && opool->head->next == NULL)
size = opool->head->level;
else {
......@@ -228,3 +235,130 @@ mu_opool_finish (mu_opool_t opool, size_t *psize)
return opool->free->buf;
}
/* Iterator support */
struct opool_iterator
{
mu_opool_t opool;
struct mu_opool_bucket *cur;
};
static int
opitr_first (void *owner)
{
struct opool_iterator *itr = owner;
itr->cur = itr->opool->head;
return 0;
}
static int
opitr_next (void *owner)
{
struct opool_iterator *itr = owner;
if (itr->cur)
{
itr->cur = itr->cur->next;
return 0;
}
return EINVAL;
}
static int
opitr_getitem (void *owner, void **pret, const void **pkey)
{
struct opool_iterator *itr = owner;
if (!itr->cur)
return MU_ERR_NOENT;
*pret = itr->cur->buf;
if (pkey)
*(size_t*) pkey = itr->cur->level;
return 0;
}
static int
opitr_finished_p (void *owner)
{
struct opool_iterator *itr = owner;
return itr->cur == NULL;
}
static int
opitr_curitem_p (void *owner, void *item)
{
struct opool_iterator *itr = owner;
return itr->cur && itr->cur->buf == item;
}
static int
opitr_destroy (mu_iterator_t iterator, void *data)
{
struct opool_iterator *itr = data;
if (itr->opool->itr_count == 0)
{
/* oops! */
mu_error (_("%s: INTERNAL ERROR: zero reference count"),
"opool_destroy");
}
else
itr->opool->itr_count--;
free (data);
return 0;
}
static int
opitr_data_dup (void **ptr, void *owner)
{
struct opool_iterator *itr = owner;
*ptr = malloc (sizeof (struct opool_iterator));
if (*ptr == NULL)
return ENOMEM;
memcpy (*ptr, owner, sizeof (struct opool_iterator));
itr->opool->itr_count++;
return 0;
}
int
mu_opool_get_iterator (mu_opool_t opool, mu_iterator_t *piterator)
{
mu_iterator_t iterator;
int status;
struct opool_iterator *itr;
if (!opool)
return EINVAL;
itr = calloc (1, sizeof *itr);
if (!itr)
return ENOMEM;
itr->opool = opool;
itr->cur = opool->head;
status = mu_iterator_create (&iterator, itr);
if (status)
{
free (itr);
return status;
}
mu_iterator_set_first (iterator, opitr_first);
mu_iterator_set_next (iterator, opitr_next);
mu_iterator_set_getitem (iterator, opitr_getitem);
mu_iterator_set_finished_p (iterator, opitr_finished_p);
mu_iterator_set_curitem_p (iterator, opitr_curitem_p);
mu_iterator_set_destroy (iterator, opitr_destroy);
mu_iterator_set_dup (iterator, opitr_data_dup);
opool->itr_count++;
*piterator = iterator;
return 0;
}
......