goa: Add missing linker flag (for real).
[platform/upstream/evolution-data-server.git] / libedataserver / e-list-iterator.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Authors:
4  *   Christopher James Lahey <clahey@umich.edu>
5  *
6  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
7  */
8
9 #include <config.h>
10
11 #include "e-list-iterator.h"
12 #include "e-list.h"
13
14 static void        e_list_iterator_invalidate (EIterator *iterator);
15 static gboolean    e_list_iterator_is_valid   (EIterator *iterator);
16 static void        e_list_iterator_set        (EIterator  *iterator,
17                                                gconstpointer object);
18 static void        e_list_iterator_remove     (EIterator  *iterator);
19 static void        e_list_iterator_insert     (EIterator  *iterator,
20                                                gconstpointer object,
21                                                gboolean    before);
22 static gboolean    e_list_iterator_prev       (EIterator  *iterator);
23 static gboolean    e_list_iterator_next       (EIterator  *iterator);
24 static void        e_list_iterator_reset      (EIterator *iterator);
25 static void        e_list_iterator_last       (EIterator *iterator);
26 static gconstpointer e_list_iterator_get        (EIterator *iterator);
27 static void        e_list_iterator_dispose    (GObject *object);
28
29 G_DEFINE_TYPE (EListIterator, e_list_iterator, E_TYPE_ITERATOR)
30
31 static void
32 e_list_iterator_class_init (EListIteratorClass *class)
33 {
34         GObjectClass *object_class;
35         EIteratorClass *iterator_class;
36
37         object_class = G_OBJECT_CLASS (class);
38         object_class->dispose = e_list_iterator_dispose;
39
40         iterator_class = E_ITERATOR_CLASS (class);
41         iterator_class->invalidate = e_list_iterator_invalidate;
42         iterator_class->get        = e_list_iterator_get;
43         iterator_class->reset      = e_list_iterator_reset;
44         iterator_class->last       = e_list_iterator_last;
45         iterator_class->next       = e_list_iterator_next;
46         iterator_class->prev       = e_list_iterator_prev;
47         iterator_class->remove     = e_list_iterator_remove;
48         iterator_class->insert     = e_list_iterator_insert;
49         iterator_class->set        = e_list_iterator_set;
50         iterator_class->is_valid   = e_list_iterator_is_valid;
51 }
52
53 /**
54  * e_list_iterator_init:
55  */
56 static void
57 e_list_iterator_init (EListIterator *list)
58 {
59 }
60
61 EIterator *
62 e_list_iterator_new (EList *list)
63 {
64         EListIterator *iterator = NULL;
65
66         g_return_val_if_fail (list != NULL, NULL);
67         g_return_val_if_fail (E_IS_LIST (list), NULL);
68
69         iterator = g_object_new (E_TYPE_LIST_ITERATOR, NULL);
70         if (!iterator)
71                 return NULL;
72         iterator->list = list;
73         g_object_ref (list);
74         iterator->iterator = list->list;
75
76         return E_ITERATOR (iterator);
77 }
78
79 /*
80  * Virtual functions:
81  */
82 static void
83 e_list_iterator_dispose (GObject *object)
84 {
85         EListIterator *iterator = E_LIST_ITERATOR (object);
86         e_list_remove_iterator (iterator->list, E_ITERATOR (iterator));
87         g_object_unref (iterator->list);
88
89         /* Chain up to parent's dispose() method. */
90         G_OBJECT_CLASS (e_list_iterator_parent_class)->dispose (object);
91 }
92
93 static gconstpointer
94 e_list_iterator_get (EIterator *_iterator)
95 {
96         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
97         if (iterator->iterator)
98                 return iterator->iterator->data;
99         else
100                 return NULL;
101 }
102
103 static void
104 e_list_iterator_reset (EIterator *_iterator)
105 {
106         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
107         iterator->iterator = iterator->list->list;
108 }
109
110 static void
111 e_list_iterator_last (EIterator *_iterator)
112 {
113         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
114         iterator->iterator = g_list_last (iterator->list->list);
115 }
116
117 static gboolean
118 e_list_iterator_next (EIterator *_iterator)
119 {
120         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
121         if (iterator->iterator)
122                 iterator->iterator = g_list_next (iterator->iterator);
123         else
124                 iterator->iterator = iterator->list->list;
125         return (iterator->iterator != NULL);
126 }
127
128 static gboolean
129 e_list_iterator_prev (EIterator *_iterator)
130 {
131         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
132         if (iterator->iterator)
133                 iterator->iterator = g_list_previous (iterator->iterator);
134         else
135                 iterator->iterator = g_list_last (iterator->list->list);
136         return (iterator->iterator != NULL);
137 }
138
139 static void
140 e_list_iterator_insert (EIterator *_iterator,
141                         gconstpointer object,
142                         gboolean before)
143 {
144         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
145         gpointer data;
146         if (iterator->list->copy)
147                 data = iterator->list->copy (object, iterator->list->closure);
148         else
149                 data = (gpointer) object;
150         if (iterator->iterator) {
151                 if (before) {
152                         iterator->list->list = g_list_first (g_list_prepend (iterator->iterator, data));
153                         iterator->iterator = iterator->iterator->prev;
154                 } else {
155                         if (iterator->iterator->next)
156                                 iterator->iterator->next = g_list_prepend (iterator->iterator->next, data);
157                         else
158                                 iterator->iterator = g_list_append (iterator->iterator, data);
159                         iterator->iterator = iterator->iterator->next;
160                 }
161                 e_list_invalidate_iterators (iterator->list, E_ITERATOR (iterator));
162         } else {
163                 if (before) {
164                         iterator->list->list = g_list_append (iterator->list->list, data);
165                         iterator->iterator = g_list_last (iterator->list->list);
166                 } else {
167                         iterator->list->list = g_list_prepend (iterator->list->list, data);
168                         iterator->iterator = iterator->list->list;
169                 }
170                 e_list_invalidate_iterators (iterator->list, E_ITERATOR (iterator));
171         }
172 }
173
174 static void
175 e_list_iterator_remove (EIterator *_iterator)
176 {
177         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
178         if (iterator->iterator) {
179                 e_list_remove_link (iterator->list, iterator->iterator);
180         }
181 }
182
183 static void
184 e_list_iterator_set (EIterator *_iterator,
185                      gconstpointer object)
186 {
187         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
188         if (iterator->iterator) {
189                 if (iterator->list->free)
190                         iterator->list->free (iterator->iterator->data, iterator->list->closure);
191                 if (iterator->list->copy)
192                         iterator->iterator->data = iterator->list->copy (object, iterator->list->closure);
193                 else
194                         iterator->iterator->data = (gpointer) object;
195         }
196 }
197
198 static gboolean
199 e_list_iterator_is_valid (EIterator *_iterator)
200 {
201         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
202         return iterator->iterator != NULL;
203 }
204
205 static void
206 e_list_iterator_invalidate (EIterator *_iterator)
207 {
208         EListIterator *iterator = E_LIST_ITERATOR (_iterator);
209         iterator->iterator = NULL;
210 }