(iterator_create): Changed proto.
(iterator_attach,iterator_detach,iterator_advance) (iterator_set_first,iterator_set_next) (iterator_set_getitem,iterator_set_finished_p) (iterator_set_dup,iterator_set_destroy): New functions.
Showing
2 changed files
with
151 additions
and
46 deletions
... | @@ -24,7 +24,7 @@ | ... | @@ -24,7 +24,7 @@ |
24 | extern "C" { | 24 | extern "C" { |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | extern int iterator_create __P ((iterator_t *, list_t)); | 27 | extern int iterator_create __P ((iterator_t *, void *)); |
28 | extern int iterator_dup __P ((iterator_t *piterator, iterator_t orig)); | 28 | extern int iterator_dup __P ((iterator_t *piterator, iterator_t orig)); |
29 | extern void iterator_destroy __P ((iterator_t *)); | 29 | extern void iterator_destroy __P ((iterator_t *)); |
30 | extern int iterator_first __P ((iterator_t)); | 30 | extern int iterator_first __P ((iterator_t)); |
... | @@ -33,6 +33,23 @@ extern int iterator_current __P ((iterator_t, void **pitem)); | ... | @@ -33,6 +33,23 @@ extern int iterator_current __P ((iterator_t, void **pitem)); |
33 | extern int iterator_is_done __P ((iterator_t)); | 33 | extern int iterator_is_done __P ((iterator_t)); |
34 | extern int iterator_get_list __P ((iterator_t iterator, list_t *plist)); | 34 | extern int iterator_get_list __P ((iterator_t iterator, list_t *plist)); |
35 | 35 | ||
36 | extern int iterator_attach (iterator_t *root, iterator_t iterator); | ||
37 | extern int iterator_detach (iterator_t *root, iterator_t iterator); | ||
38 | extern void iterator_advance (iterator_t iterator, void *e); | ||
39 | |||
40 | extern int iterator_set_first (iterator_t, int (*first) (void *)); | ||
41 | extern int iterator_set_next (iterator_t, int (*next) (void *)); | ||
42 | extern int iterator_set_getitem (iterator_t, | ||
43 | int (*getitem) (void *, void **)); | ||
44 | extern int iterator_set_finished_p (iterator_t, | ||
45 | int (*finished_p) (void *)); | ||
46 | extern int iterator_set_dup (iterator_t itr, | ||
47 | int (dup) (void **ptr, void *data)); | ||
48 | extern int iterator_set_destroy (iterator_t itr, | ||
49 | int (destroy) (iterator_t, void *data)); | ||
50 | extern int iterator_set_curitem_p (iterator_t itr, | ||
51 | int (*curitem_p) (void *, void *)); | ||
52 | |||
36 | #ifdef __cplusplus | 53 | #ifdef __cplusplus |
37 | } | 54 | } |
38 | #endif | 55 | #endif | ... | ... |
... | @@ -27,42 +27,117 @@ | ... | @@ -27,42 +27,117 @@ |
27 | #include <mailutils/errno.h> | 27 | #include <mailutils/errno.h> |
28 | 28 | ||
29 | int | 29 | int |
30 | iterator_create (iterator_t *piterator, list_t list) | 30 | iterator_create (iterator_t *piterator, void *owner) |
31 | { | 31 | { |
32 | iterator_t iterator; | 32 | iterator_t iterator; |
33 | if (piterator == NULL) | 33 | if (piterator == NULL) |
34 | return MU_ERR_OUT_PTR_NULL; | 34 | return MU_ERR_OUT_PTR_NULL; |
35 | if (list == NULL) | 35 | if (owner == NULL) |
36 | return EINVAL; | 36 | return EINVAL; |
37 | iterator = calloc (sizeof (*iterator), 1); | 37 | iterator = calloc (sizeof (*iterator), 1); |
38 | if (iterator == NULL) | 38 | if (iterator == NULL) |
39 | return ENOMEM; | 39 | return ENOMEM; |
40 | iterator->list = list; | 40 | iterator->owner = owner; |
41 | iterator->cur = NULL; | ||
42 | iterator->next = list->itr; | ||
43 | list->itr = iterator; | ||
44 | iterator->is_advanced = 0; | ||
45 | *piterator = iterator; | 41 | *piterator = iterator; |
46 | return 0; | 42 | return 0; |
47 | } | 43 | } |
48 | 44 | ||
49 | int | 45 | int |
46 | iterator_set_first (iterator_t itr, int (*first) (void *)) | ||
47 | { | ||
48 | if (!itr) | ||
49 | return EINVAL; | ||
50 | itr->first = first; | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | int | ||
55 | iterator_set_next (iterator_t itr, int (*next) (void *)) | ||
56 | { | ||
57 | if (!itr) | ||
58 | return EINVAL; | ||
59 | itr->next = next; | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | int | ||
64 | iterator_set_getitem (iterator_t itr, int (*getitem) (void *, void **)) | ||
65 | { | ||
66 | if (!itr) | ||
67 | return EINVAL; | ||
68 | itr->getitem = getitem; | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | int | ||
73 | iterator_set_finished_p (iterator_t itr, int (*finished_p) (void *)) | ||
74 | { | ||
75 | if (!itr) | ||
76 | return EINVAL; | ||
77 | itr->finished_p = finished_p; | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | int | ||
82 | iterator_set_curitem_p (iterator_t itr, | ||
83 | int (*curitem_p) (void *, void *)) | ||
84 | { | ||
85 | if (!itr) | ||
86 | return EINVAL; | ||
87 | itr->curitem_p = curitem_p; | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | int | ||
92 | iterator_set_destroy (iterator_t itr, int (destroy) (iterator_t, void *)) | ||
93 | { | ||
94 | if (!itr) | ||
95 | return EINVAL; | ||
96 | itr->destroy = destroy; | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | int | ||
101 | iterator_set_dup (iterator_t itr, int (dup) (void **ptr, void *data)) | ||
102 | { | ||
103 | if (!itr) | ||
104 | return EINVAL; | ||
105 | itr->dup = dup; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | |||
110 | |||
111 | int | ||
50 | iterator_dup (iterator_t *piterator, iterator_t orig) | 112 | iterator_dup (iterator_t *piterator, iterator_t orig) |
51 | { | 113 | { |
52 | iterator_t iterator; | 114 | iterator_t iterator; |
115 | int status; | ||
53 | 116 | ||
54 | if (piterator == NULL) | 117 | if (piterator == NULL) |
55 | return MU_ERR_OUT_PTR_NULL; | 118 | return MU_ERR_OUT_PTR_NULL; |
56 | if (orig == NULL) | 119 | if (orig == NULL) |
57 | return EINVAL; | 120 | return EINVAL; |
58 | iterator = calloc (sizeof (*iterator), 1); | 121 | |
59 | if (iterator == NULL) | 122 | status = iterator_create (&iterator, orig->owner); |
60 | return ENOMEM; | 123 | if (status) |
61 | iterator->list = orig->list; | 124 | return status; |
62 | iterator->cur = orig->cur; | 125 | |
126 | status = orig->dup(&iterator->owner, orig->owner); | ||
127 | if (status) | ||
128 | { | ||
129 | free (iterator); | ||
130 | return status; | ||
131 | } | ||
63 | iterator->is_advanced = orig->is_advanced; | 132 | iterator->is_advanced = orig->is_advanced; |
64 | iterator->next = orig->list->itr; | 133 | iterator->first = orig->first; |
65 | orig->list->itr = iterator; | 134 | iterator->next = orig->next; |
135 | iterator->getitem = orig->getitem; | ||
136 | iterator->finished_p = orig->finished_p; | ||
137 | iterator->curitem_p = orig->curitem_p; | ||
138 | iterator->dup = orig->dup; | ||
139 | iterator->destroy = orig->destroy; | ||
140 | |||
66 | *piterator = iterator; | 141 | *piterator = iterator; |
67 | return 0; | 142 | return 0; |
68 | } | 143 | } |
... | @@ -70,52 +145,37 @@ iterator_dup (iterator_t *piterator, iterator_t orig) | ... | @@ -70,52 +145,37 @@ iterator_dup (iterator_t *piterator, iterator_t orig) |
70 | void | 145 | void |
71 | iterator_destroy (iterator_t *piterator) | 146 | iterator_destroy (iterator_t *piterator) |
72 | { | 147 | { |
73 | iterator_t itr, prev; | ||
74 | |||
75 | if (!piterator || !*piterator) | 148 | if (!piterator || !*piterator) |
76 | return; | 149 | return; |
77 | 150 | ||
78 | for (itr = (*piterator)->list->itr, prev = NULL; | 151 | if ((*piterator)->destroy) |
79 | itr; | 152 | (*piterator)->destroy (*piterator, (*piterator)->owner); |
80 | prev = itr, itr = itr->next) | ||
81 | if (*piterator == itr) | ||
82 | break; | ||
83 | 153 | ||
84 | if (itr) | 154 | free (*piterator); |
85 | { | ||
86 | if (prev) | ||
87 | prev->next = itr->next; | ||
88 | else | ||
89 | itr->list->itr = itr->next; | ||
90 | free(itr); | ||
91 | *piterator = NULL; | 155 | *piterator = NULL; |
92 | } | ||
93 | } | 156 | } |
94 | 157 | ||
95 | int | 158 | int |
96 | iterator_first (iterator_t iterator) | 159 | iterator_first (iterator_t iterator) |
97 | { | 160 | { |
98 | iterator->cur = iterator->list->head.next; | ||
99 | iterator->is_advanced = 0; | 161 | iterator->is_advanced = 0; |
100 | return 0; | 162 | return iterator->first (iterator->owner); |
101 | } | 163 | } |
102 | 164 | ||
103 | int | 165 | int |
104 | iterator_next (iterator_t iterator) | 166 | iterator_next (iterator_t iterator) |
105 | { | 167 | { |
168 | int status = 0; | ||
106 | if (!iterator->is_advanced) | 169 | if (!iterator->is_advanced) |
107 | iterator->cur = iterator->cur->next; | 170 | status = iterator->next (iterator->owner); |
108 | iterator->is_advanced = 0; | 171 | iterator->is_advanced = 0; |
109 | return 0; | 172 | return status; |
110 | } | 173 | } |
111 | 174 | ||
112 | int | 175 | int |
113 | iterator_current (iterator_t iterator, void **pitem) | 176 | iterator_current (iterator_t iterator, void **pitem) |
114 | { | 177 | { |
115 | if (!iterator->cur) | 178 | return iterator->getitem (iterator->owner, pitem); |
116 | return MU_ERR_NOENT; | ||
117 | *pitem = iterator->cur->item; | ||
118 | return 0; | ||
119 | } | 179 | } |
120 | 180 | ||
121 | int | 181 | int |
... | @@ -123,29 +183,57 @@ iterator_is_done (iterator_t iterator) | ... | @@ -123,29 +183,57 @@ iterator_is_done (iterator_t iterator) |
123 | { | 183 | { |
124 | if (iterator == NULL) | 184 | if (iterator == NULL) |
125 | return 1; | 185 | return 1; |
126 | return iterator->cur == NULL || iterator->cur == &iterator->list->head; | 186 | return iterator->finished_p (iterator->owner); |
127 | } | 187 | } |
128 | 188 | ||
129 | int | 189 | int |
130 | iterator_get_list (iterator_t iterator, list_t *plist) | 190 | iterator_get_owner (iterator_t iterator, void **powner) |
131 | { | 191 | { |
132 | if (!iterator) | 192 | if (!iterator) |
133 | return EINVAL; | 193 | return EINVAL; |
134 | if (!plist) | 194 | if (!powner) |
135 | return MU_ERR_OUT_PTR_NULL; | 195 | return MU_ERR_OUT_PTR_NULL; |
136 | *plist = iterator->list; | 196 | *powner = iterator->owner; |
137 | return 0; | 197 | return 0; |
138 | } | 198 | } |
139 | 199 | ||
140 | void | 200 | void |
141 | iterator_advance (iterator_t iterator, struct list_data *e) | 201 | iterator_advance (iterator_t iterator, void *e) |
142 | { | 202 | { |
143 | for (; iterator; iterator = iterator->next) | 203 | for (; iterator; iterator = iterator->next_itr) |
144 | { | 204 | { |
145 | if (iterator->cur == e) | 205 | if (iterator->curitem_p (iterator->owner, e)) |
146 | { | 206 | { |
147 | iterator->cur = e->next; | 207 | iterator->next (iterator->owner); |
148 | iterator->is_advanced++; | 208 | iterator->is_advanced++; |
149 | } | 209 | } |
150 | } | 210 | } |
151 | } | 211 | } |
212 | |||
213 | int | ||
214 | iterator_attach (iterator_t *root, iterator_t iterator) | ||
215 | { | ||
216 | iterator->next_itr = *root; | ||
217 | *root = iterator; | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | int | ||
222 | iterator_detach (iterator_t *root, iterator_t iterator) | ||
223 | { | ||
224 | iterator_t itr, prev; | ||
225 | |||
226 | for (itr = *root, prev = NULL; itr; prev = itr, itr = itr->next_itr) | ||
227 | if (iterator == itr) | ||
228 | break; | ||
229 | |||
230 | if (itr) | ||
231 | { | ||
232 | if (prev) | ||
233 | prev->next = itr->next; | ||
234 | else | ||
235 | *root = itr->next_itr; | ||
236 | } | ||
237 | |||
238 | return 0; | ||
239 | } | ... | ... |
-
Please register or sign in to post a comment