Commit a736b7a9 a736b7a9a775db4b82806a6214deefc3ac7a4dd4 by Sergey Poznyakoff

imap client: redo capability and id support via list mappers.

* libproto/imap/capability.c (mu_imap_capability): Use mu_list_map to
create the capability list.
* libproto/imap/id.c (_id_convert): Likewise for ID pairs.
1 parent e4a76054
......@@ -44,6 +44,27 @@ capa_comp (const void *item, const void *value)
return !(*capa == 0 || *capa == '=');
}
static int
_map_capa (void **itmv, size_t itmc, void *call_data)
{
int *n = call_data;
struct imap_list_element *elt = itmv[0];
if (elt->type != imap_eltype_string)
return MU_LIST_MAP_STOP;
if (*n == 0)
{
++*n;
if (strcmp (elt->v.string, "CAPABILITY") == 0)
return MU_LIST_MAP_SKIP;
else
return MU_LIST_MAP_STOP;
}
itmv[0] = elt->v.string;
elt->v.string = NULL;
return MU_LIST_MAP_OK;
}
int
mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter)
{
......@@ -100,28 +121,9 @@ mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter)
if (mu_list_get (imap->untagged_resp, 0, (void*)&elt) == 0)
{
/* Top-level elements are always of imap_eltype_list type. */
mu_iterator_t itr;
mu_list_get_iterator (elt->v.list, &itr);
mu_iterator_first (itr);
if (mu_iterator_is_done (itr))
return MU_ERR_PARSE;
mu_iterator_current (itr, (void **) &elt);
if (elt->type == imap_eltype_string &&
strcmp (elt->v.string, "CAPABILITY") == 0)
{
for (mu_iterator_next (itr); !mu_iterator_is_done (itr);
mu_iterator_next (itr))
{
mu_iterator_current (itr, (void **) &elt);
if (elt->type == imap_eltype_string)
{
mu_list_append (imap->capa, elt->v.string);
elt->v.string = NULL;
}
}
}
mu_iterator_destroy (&itr);
int n = 0;
status = mu_list_map (elt->v.list, _map_capa, &n, 1,
&imap->capa);
}
if (piter)
status = mu_list_get_iterator (imap->capa, piter);
......
......@@ -34,6 +34,20 @@ _id_free (void *data)
free (s);
}
static int
_id_mapper (void **itmv, size_t itmc, void *call_data)
{
int rc;
mu_assoc_t assoc = call_data;
struct imap_list_element *key = itmv[0], *val = itmv[1];
if (key->type != imap_eltype_string || val->type != imap_eltype_string)
return MU_ERR_FAILURE;
rc = mu_assoc_install (assoc, key->v.string, &val->v.string);
if (rc == 0)
val->v.string = NULL;
return rc;
}
struct id_convert_state
{
int item;
......@@ -61,32 +75,7 @@ _id_convert (void *item, void *data)
case 1:
if (elt->type == imap_eltype_list)
{
mu_iterator_t itr;
mu_list_get_iterator (elt->v.list, &itr);
for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
mu_iterator_next (itr))
{
char *key, *val;
mu_iterator_current (itr, (void **) &elt);
if (elt->type != imap_eltype_string)
break;
key = elt->v.string;
elt->v.string = NULL;
mu_iterator_next (itr);
if (mu_iterator_is_done (itr))
break;
mu_iterator_current (itr, (void **) &elt);
if (elt->type != imap_eltype_string)
break;
val = elt->v.string;
elt->v.string = NULL;
mu_assoc_install (stp->assoc, key, &val);
}
}
mu_list_gmap (elt->v.list, _id_mapper, 2, stp->assoc);
}
return 1;
}
......