Move terms and tags code to a new tags.cc file.
[notmuch] / tags.cc
1 /* tags.cc - Iterator for tags returned from message or thread
2  *
3  * Copyright © 2009 Carl Worth
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see http://www.gnu.org/licenses/ .
17  *
18  * Author: Carl Worth <cworth@cworth.org>
19  */
20
21 #include "notmuch-private-cxx.h"
22 #include "database-private.h"
23
24 #include <xapian.h>
25
26 /* We end up having to call the destructors explicitly because we had
27  * to use "placement new" in order to initialize C++ objects within a
28  * block that we allocated with talloc. So C++ is making talloc
29  * slightly less simple to use, (we wouldn't need
30  * talloc_set_destructor at all otherwise).
31  */
32 static int
33 _notmuch_terms_destructor (notmuch_terms_t *terms)
34 {
35     terms->iterator.~TermIterator ();
36     terms->iterator_end.~TermIterator ();
37
38     return 0;
39 }
40
41 notmuch_terms_t *
42 _notmuch_terms_create (void *ctx,
43                        Xapian::Document doc,
44                        const char *prefix_name)
45 {
46     notmuch_terms_t *terms;
47     const char *prefix = _find_prefix (prefix_name);
48
49     /* Currently, notmuch_terms_t is written with the assumption that
50      * any prefix its derivatives use will be only a single
51      * character. */
52     assert (strlen (prefix) == 1);
53
54     terms = talloc (ctx, notmuch_terms_t);
55     if (unlikely (terms == NULL))
56         return NULL;
57
58     terms->prefix_char = *prefix;
59     new (&terms->iterator) Xapian::TermIterator;
60     new (&terms->iterator_end) Xapian::TermIterator;
61
62     talloc_set_destructor (terms, _notmuch_terms_destructor);
63
64     terms->iterator = doc.termlist_begin ();
65     terms->iterator.skip_to (prefix);
66     terms->iterator_end = doc.termlist_end ();
67
68     return terms;
69 }
70
71 static notmuch_bool_t
72 _notmuch_terms_has_more (notmuch_terms_t *terms)
73 {
74     std::string s;
75
76     if (terms->iterator == terms->iterator_end)
77         return FALSE;
78
79     s = *terms->iterator;
80     if (! s.empty () && s[0] == terms->prefix_char)
81         return TRUE;
82     else
83         return FALSE;
84 }
85
86 static const char *
87 _notmuch_terms_get (notmuch_terms_t *terms)
88 {
89     return talloc_strdup (terms, (*terms->iterator).c_str () + 1);
90 }
91
92 static void
93 _notmuch_terms_advance (notmuch_terms_t *terms)
94 {
95     terms->iterator++;
96 }
97
98 static void
99 _notmuch_terms_destroy (notmuch_terms_t *terms)
100 {
101     talloc_free (terms);
102 }
103
104 notmuch_bool_t
105 notmuch_tags_has_more (notmuch_tags_t *tags)
106 {
107     return _notmuch_terms_has_more (&tags->terms);
108 }
109
110 const char *
111 notmuch_tags_get (notmuch_tags_t *tags)
112 {
113     return _notmuch_terms_get (&tags->terms);
114 }
115
116 void
117 notmuch_tags_advance (notmuch_tags_t *tags)
118 {
119     return _notmuch_terms_advance (&tags->terms);
120 }
121
122 void
123 notmuch_tags_destroy (notmuch_tags_t *tags)
124 {
125     return _notmuch_terms_destroy (&tags->terms);
126 }