1 /*
2 * fontconfig/src/fcptrlist.c
3 *
4 * Copyright © 2000 Keith Packard
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of the author(s) not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. The authors make no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
15 *
16 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 */
24
25 #include "fcint.h"
26
27 typedef struct _FcPtrListEntry {
28 struct _FcPtrListEntry *next;
29 void *data;
30 } FcPtrListEntry;
31 struct _FcPtrList {
32 FcDestroyFunc destroy_func;
33 FcPtrListEntry *list;
34 };
35 typedef struct _FcPtrListIterPrivate {
36 const FcPtrList *list;
37 FcPtrListEntry *entry;
38 FcPtrListEntry *prev;
39 } FcPtrListIterPrivate;
40
41 FcPtrList *
42 FcPtrListCreate (FcDestroyFunc func)
43 {
44 FcPtrList *ret = (FcPtrList *) malloc (sizeof (FcPtrList));
45
46 if (ret)
47 {
48 ret->destroy_func = func;
49 ret->list = NULL;
50 }
51
52 return ret;
53 }
54
55 void
56 FcPtrListDestroy (FcPtrList *list)
57 {
58 FcPtrListIter iter;
59
60 if (list)
61 {
62 FcPtrListIterInit (list, &iter);
63 do
64 {
65 if (FcPtrListIterGetValue (list, &iter))
66 list->destroy_func (FcPtrListIterGetValue (list, &iter));
67 FcPtrListIterRemove (list, &iter);
68 } while (FcPtrListIterIsValid (list, &iter));
69
70 free (list);
71 }
72 }
73
74 void
75 FcPtrListIterInit (const FcPtrList *list,
76 FcPtrListIter *iter)
77 {
78 FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
79
80 priv->list = list;
81 priv->entry = list->list;
82 priv->prev = NULL;
83 }
84
85 void
86 FcPtrListIterInitAtLast (FcPtrList *list,
87 FcPtrListIter *iter)
88 {
89 FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
90 FcPtrListEntry **e, **p;
91
92 e = &list->list;
93 p = e;
94 for (; *e; p = e, e = &(*e)->next);
95
96 priv->list = list;
97 priv->entry = *e;
98 priv->prev = *p;
99 }
100
101 FcBool
102 FcPtrListIterNext (const FcPtrList *list,
103 FcPtrListIter *iter)
104 {
105 FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
106
107 if (list != priv->list)
108 return FcFalse;
109 priv->prev = priv->entry;
110 priv->entry = priv->entry->next;
111
112 return priv->entry != NULL;
113 }
114
115 FcBool
116 FcPtrListIterIsValid (const FcPtrList *list,
117 const FcPtrListIter *iter)
118 {
119 FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
120
121 return list == priv->list && priv->entry;
122 }
123
124 void *
125 FcPtrListIterGetValue (const FcPtrList *list,
126 const FcPtrListIter *iter)
127 {
128 FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
129
130 if (list != priv->list ||
131 !priv->entry)
132 return NULL;
133
134 return priv->entry->data;
135 }
136
137 FcBool
138 FcPtrListIterAdd (FcPtrList *list,
139 FcPtrListIter *iter,
140 void *data)
141 {
142 FcPtrListEntry *e;
143 FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
144
145 if (list != priv->list)
146 return FcFalse;
147
148 e = (FcPtrListEntry *) malloc (sizeof (FcPtrListEntry));
149 if (!e)
150 return FcFalse;
151 e->data = data;
152
153 if (priv->entry)
154 {
155 e->next = priv->entry->next;
156 priv->entry->next = e;
157 }
158 else
159 {
160 e->next = NULL;
161 if (priv->prev)
162 {
163 priv->prev->next = e;
164 priv->entry = priv->prev;
165 }
166 else
167 {
168 list->list = e;
169 priv->entry = e;
170
171 return FcTrue;
172 }
173 }
174
175 return FcPtrListIterNext (list, iter);
176 }
177
178 FcBool
179 FcPtrListIterRemove (FcPtrList *list,
180 FcPtrListIter *iter)
181 {
182 FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
183 FcPtrListEntry *e;
184
185 if (list != priv->list)
186 return FcFalse;
187 if (!priv->entry)
188 return FcTrue;
189
190 if (list->list == priv->entry)
191 list->list = list->list->next;
192 e = priv->entry;
193 if (priv->prev)
194 priv->prev->next = priv->entry->next;
195 priv->entry = priv->entry->next;
196 free (e);
197
198 return FcTrue;
199 }
200
201 #define __fcplist__
202 #include "fcaliastail.h"
203 #undef __fcplist__