Commit c1421c3a c1421c3a608c87f900733fe336f807546cac93b1 by Sergey Poznyakoff

mailbox iterator: implement reverse direction and itrctl.

* libmailutils/mailbox/mbxitr.c (mailbox_iterator)<backwards>: New member.
(mbx_first): Position to the last message if itr->backwards is set.
(mbx_next): Decrement index if itr->backwards is set.
(mbx_finished_p): Take into account iteration direction.
(mbx_itrctl): new method.
(mu_mailbox_get_iterator): Set itrctl method.
1 parent 2428c02e
......@@ -175,9 +175,7 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name)
}
/* The Mailbox Factory.
Create an iterator for registrar and see if any url scheme match,
Then we call the mailbox's mu_url_create() to parse the URL. Last
initialize the concrete mailbox and folder. */
*/
int
mu_mailbox_create (mu_mailbox_t *pmbox, const char *name)
{
......
......@@ -27,6 +27,8 @@
#include <mailutils/errno.h>
#include <mailutils/error.h>
#include <mailutils/iterator.h>
#include <mailutils/message.h>
#include <mailutils/attribute.h>
#include <mailutils/sys/mailbox.h>
......@@ -34,12 +36,16 @@ struct mailbox_iterator
{
mu_mailbox_t mbx;
size_t idx;
int backwards;
};
static int
mbx_first (void *owner)
{
struct mailbox_iterator *itr = owner;
if (itr->backwards)
return mu_mailbox_messages_count (itr->mbx, &itr->idx);
else
itr->idx = 1;
return 0;
}
......@@ -48,6 +54,13 @@ static int
mbx_next (void *owner)
{
struct mailbox_iterator *itr = owner;
if (itr->backwards)
{
if (itr->idx)
--itr->idx;
}
else
itr->idx++;
return 0;
}
......@@ -74,11 +87,17 @@ static int
mbx_finished_p (void *owner)
{
struct mailbox_iterator *itr = owner;
if (itr->backwards)
return itr->idx == 0;
else
{
size_t count;
if (mu_mailbox_messages_count (itr->mbx, &count))
return 1;
return itr->idx > count;
}
}
static int
......@@ -114,6 +133,55 @@ mbx_data_dup (void **ptr, void *owner)
return 0;
}
static int
mbx_itrctl (void *owner, enum mu_itrctl_req req, void *arg)
{
int rc;
struct mailbox_iterator *itr = owner;
mu_message_t msg;
mu_attribute_t attr;
if (itr->idx == 0)
return MU_ERR_NOENT;
switch (req)
{
case mu_itrctl_tell:
*(size_t*)arg = itr->idx;
break;
case mu_itrctl_delete:
rc = mu_mailbox_get_message (itr->mbx, itr->idx, &msg);
if (rc)
return rc;
rc = mu_message_get_attribute (msg, &attr);
if (rc)
return rc;
rc = mu_attribute_set_deleted (attr);
if (rc)
return rc;
break;
case mu_itrctl_qry_direction:
if (!arg)
return EINVAL;
else
*(int*)arg = itr->backwards;
break;
case mu_itrctl_set_direction:
if (!arg)
return EINVAL;
else
itr->backwards = !!*(int*)arg;
break;
default:
return ENOSYS;
}
return 0;
}
int
mu_mailbox_get_iterator (mu_mailbox_t mbx, mu_iterator_t *piterator)
{
......@@ -129,6 +197,7 @@ mu_mailbox_get_iterator (mu_mailbox_t mbx, mu_iterator_t *piterator)
return ENOMEM;
itr->mbx = mbx;
itr->idx = 1;
itr->backwards = 0;
status = mu_iterator_create (&iterator, itr);
if (status)
......@@ -144,6 +213,7 @@ mu_mailbox_get_iterator (mu_mailbox_t mbx, mu_iterator_t *piterator)
mu_iterator_set_curitem_p (iterator, mbx_curitem_p);
mu_iterator_set_destroy (iterator, mbx_destroy);
mu_iterator_set_dup (iterator, mbx_data_dup);
mu_iterator_set_itrctl (iterator, mbx_itrctl);
mu_iterator_attach (&mbx->iterator, iterator);
......