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    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
74void
75FcPtrListIterInit (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
85void
86FcPtrListIterInitAtLast (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
101FcBool
102FcPtrListIterNext (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
115FcBool
116FcPtrListIterIsValid (const FcPtrList	*list,
117		    const FcPtrListIter	*iter)
118{
119    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
120
121    return list == priv->list && priv->entry;
122}
123
124void *
125FcPtrListIterGetValue (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
137FcBool
138FcPtrListIterAdd (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
178FcBool
179FcPtrListIterRemove (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__
204