fcptrlist.c revision a32e9e42
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
27typedef struct _FcPtrListEntry {
28    struct _FcPtrListEntry	*next;
29    void			*data;
30} FcPtrListEntry;
31struct _FcPtrList {
32    FcDestroyFunc	destroy_func;
33    FcPtrListEntry	*list;
34};
35typedef struct _FcPtrListIterPrivate {
36    const FcPtrList	*list;
37    FcPtrListEntry	*entry;
38    FcPtrListEntry	*prev;
39} FcPtrListIterPrivate;
40
41FcPtrList *
42FcPtrListCreate (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
55void
56FcPtrListDestroy (FcPtrList *list)
57{
58    FcPtrListIter iter;
59
60    FcPtrListIterInit (list, &iter);
61    do
62    {
63	if (FcPtrListIterGetValue (list, &iter))
64	    list->destroy_func (FcPtrListIterGetValue (list, &iter));
65	FcPtrListIterRemove (list, &iter);
66    } while (FcPtrListIterIsValid (list, &iter));
67
68    free (list);
69}
70
71void
72FcPtrListIterInit (const FcPtrList	*list,
73		 FcPtrListIter		*iter)
74{
75    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
76
77    priv->list = list;
78    priv->entry = list->list;
79    priv->prev = NULL;
80}
81
82void
83FcPtrListIterInitAtLast (FcPtrList	*list,
84		       FcPtrListIter	*iter)
85{
86    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
87    FcPtrListEntry **e, **p;
88
89    e = &list->list;
90    p = e;
91    for (; *e; p = e, e = &(*e)->next);
92
93    priv->list = list;
94    priv->entry = *e;
95    priv->prev = *p;
96}
97
98FcBool
99FcPtrListIterNext (const FcPtrList	*list,
100		 FcPtrListIter		*iter)
101{
102    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
103
104    if (list != priv->list)
105	return FcFalse;
106    priv->prev = priv->entry;
107    priv->entry = priv->entry->next;
108
109    return priv->entry != NULL;
110}
111
112FcBool
113FcPtrListIterIsValid (const FcPtrList	*list,
114		    const FcPtrListIter	*iter)
115{
116    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
117
118    return list == priv->list && priv->entry;
119}
120
121void *
122FcPtrListIterGetValue (const FcPtrList		*list,
123		     const FcPtrListIter	*iter)
124{
125    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
126
127    if (list != priv->list ||
128	!priv->entry)
129	return NULL;
130
131    return priv->entry->data;
132}
133
134FcBool
135FcPtrListIterAdd (FcPtrList	*list,
136		FcPtrListIter	*iter,
137		void		*data)
138{
139    FcPtrListEntry *e;
140    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
141
142    if (list != priv->list)
143	return FcFalse;
144
145    e = (FcPtrListEntry *) malloc (sizeof (FcPtrListEntry));
146    if (!e)
147	return FcFalse;
148    e->data = data;
149
150    if (priv->entry)
151    {
152	e->next = priv->entry->next;
153	priv->entry->next = e;
154    }
155    else
156    {
157	e->next = NULL;
158	if (priv->prev)
159	{
160	    priv->prev->next = e;
161	    priv->entry = priv->prev;
162	}
163	else
164	{
165	    list->list = e;
166	    priv->entry = e;
167
168	    return FcTrue;
169	}
170    }
171
172    return FcPtrListIterNext (list, iter);
173}
174
175FcBool
176FcPtrListIterRemove (FcPtrList		*list,
177		   FcPtrListIter	*iter)
178{
179    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
180    FcPtrListEntry *e;
181
182    if (list != priv->list)
183	return FcFalse;
184    if (!priv->entry)
185	return FcTrue;
186
187    if (list->list == priv->entry)
188	list->list = list->list->next;
189    e = priv->entry;
190    if (priv->prev)
191	priv->prev->next = priv->entry->next;
192    priv->entry = priv->entry->next;
193    free (e);
194
195    return FcTrue;
196}
197
198#define __fcplist__
199#include "fcaliastail.h"
200#undef __fcplist__
201