Commit 979a3826 979a3826c2fe809b9a491ac8878da7a575f6dfb6 by Sergey Poznyakoff

(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.
1 parent e6066cdd
...@@ -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));
...@@ -32,6 +32,23 @@ extern int iterator_next __P ((iterator_t)); ...@@ -32,6 +32,23 @@ extern int iterator_next __P ((iterator_t));
32 extern int iterator_current __P ((iterator_t, void **pitem)); 32 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
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 *));
35 52
36 #ifdef __cplusplus 53 #ifdef __cplusplus
37 } 54 }
......
...@@ -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;
53 115 int status;
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
63 iterator->is_advanced = orig->is_advanced; 126 status = orig->dup(&iterator->owner, orig->owner);
64 iterator->next = orig->list->itr; 127 if (status)
65 orig->list->itr = iterator; 128 {
129 free (iterator);
130 return status;
131 }
132 iterator->is_advanced = orig->is_advanced;
133 iterator->first = orig->first;
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) 153
81 if (*piterator == itr) 154 free (*piterator);
82 break; 155 *piterator = NULL;
83
84 if (itr)
85 {
86 if (prev)
87 prev->next = itr->next;
88 else
89 itr->list->itr = itr->next;
90 free(itr);
91 *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 }
......