1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
| | /* tags.c - Iterator for tags returned from message or thread
*
* Copyright © 2009 Carl Worth
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
#include "notmuch-private.h"
#include <glib.h> /* GList */
struct _notmuch_tags {
int sorted;
GList *tags;
GList *previous_node;
GList *iterator;
};
/* XXX: Should write some talloc-friendly list to avoid the need for
* this. */
static int
_notmuch_tags_destructor (notmuch_tags_t *tags)
{
g_list_free (tags->tags);
return 0;
}
/* Create a new notmuch_tags_t object, with 'ctx' as its talloc owner.
*
* This function can return NULL in case of out-of-memory.
*/
notmuch_tags_t *
_notmuch_tags_create (void *ctx)
{
notmuch_tags_t *tags;
tags = talloc (ctx, notmuch_tags_t);
if (unlikely (tags == NULL))
return NULL;
talloc_set_destructor (tags, _notmuch_tags_destructor);
tags->sorted = 1;
tags->tags = NULL;
tags->previous_node = NULL;
tags->iterator = NULL;
return tags;
}
/* Add a new tag to 'tags'. The tags object will create its own copy
* of the string.
*
* Note: The tags object will not do anything to prevent duplicate
* tags being stored, so the caller really shouldn't pass
* duplicates. */
void
_notmuch_tags_add_tag (notmuch_tags_t *tags, const char *tag)
{
tags->tags = g_list_prepend (tags->tags, talloc_strdup (tags, tag));
tags->sorted = 0;
}
/* Prepare 'tag' for iteration.
*
* The internal creator of 'tags' should call this function before
* returning 'tags' to the user to call the public functions such as
* notmuch_tags_has_more, notmuch_tags_get, and notmuch_tags_advance. */
void
_notmuch_tags_prepare_iterator (notmuch_tags_t *tags)
{
if (! tags->sorted)
tags->tags = g_list_sort (tags->tags, (GCompareFunc) strcmp);
tags->sorted = 1;
tags->iterator = tags->tags;
}
notmuch_bool_t
notmuch_tags_has_more (notmuch_tags_t *tags)
{
return tags->iterator != NULL;
}
notmuch_bool_t
notmuch_tags_is_first (notmuch_tags_t *tags)
{
return tags->previous_node == NULL;
}
const char *
notmuch_tags_get (notmuch_tags_t *tags)
{
if (tags->iterator == NULL)
return NULL;
return (char *) tags->iterator->data;
}
void
notmuch_tags_advance (notmuch_tags_t *tags)
{
if (tags->iterator == NULL)
return;
tags->previous_node = tags->iterator;
tags->iterator = tags->iterator->next;
}
void
notmuch_tags_regress (notmuch_tags_t *tags)
{
if (tags->previous_node == NULL)
return;
tags->iterator = tags->previous_node;
tags->previous_node = tags->iterator->prev;
}
void
notmuch_tags_destroy (notmuch_tags_t *tags)
{
talloc_free (tags);
}
|