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