Move private definitions and prototypes to new wayland-private.h
[profile/ivi/wayland.git] / src / wayland-util.c
1 /*
2  * Copyright © 2008-2011 Kristian Høgsberg
3  * Copyright © 2011 Intel Corporation
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that copyright
8  * notice and this permission notice appear in supporting documentation, and
9  * that the name of the copyright holders not be used in advertising or
10  * publicity pertaining to distribution of the software without specific,
11  * written prior permission.  The copyright holders make no representations
12  * about the suitability of this software for any purpose.  It is provided "as
13  * is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21  * OF THIS SOFTWARE.
22  */
23
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <string.h>
27
28 #include "wayland-util.h"
29 #include "wayland-private.h"
30
31 WL_EXPORT void
32 wl_list_init(struct wl_list *list)
33 {
34         list->prev = list;
35         list->next = list;
36 }
37
38 WL_EXPORT void
39 wl_list_insert(struct wl_list *list, struct wl_list *elm)
40 {
41         elm->prev = list;
42         elm->next = list->next;
43         list->next = elm;
44         elm->next->prev = elm;
45 }
46
47 WL_EXPORT void
48 wl_list_remove(struct wl_list *elm)
49 {
50         elm->prev->next = elm->next;
51         elm->next->prev = elm->prev;
52 }
53
54 WL_EXPORT int
55 wl_list_length(struct wl_list *list)
56 {
57         struct wl_list *e;
58         int count;
59
60         count = 0;
61         e = list->next;
62         while (e != list) {
63                 e = e->next;
64                 count++;
65         }
66
67         return count;
68 }
69
70 WL_EXPORT int
71 wl_list_empty(struct wl_list *list)
72 {
73         return list->next == list;
74 }
75
76 WL_EXPORT void
77 wl_list_insert_list(struct wl_list *list, struct wl_list *other)
78 {
79         other->next->prev = list;
80         other->prev->next = list->next;
81         list->next->prev = other->prev;
82         list->next = other->next;
83 }
84
85 WL_EXPORT void
86 wl_array_init(struct wl_array *array)
87 {
88         memset(array, 0, sizeof *array);
89 }
90
91 WL_EXPORT void
92 wl_array_release(struct wl_array *array)
93 {
94         free(array->data);
95 }
96
97 WL_EXPORT void *
98 wl_array_add(struct wl_array *array, int size)
99 {
100         int alloc;
101         void *data, *p;
102
103         if (array->alloc > 0)
104                 alloc = array->alloc;
105         else
106                 alloc = 16;
107
108         while (alloc < array->size + size)
109                 alloc *= 2;
110
111         if (array->alloc < alloc) {
112                 if (array->alloc > 0)
113                         data = realloc(array->data, alloc);
114                 else
115                         data = malloc(alloc);
116
117                 if (data == NULL)
118                         return 0;
119                 array->data = data;
120                 array->alloc = alloc;
121         }
122
123         p = array->data + array->size;
124         array->size += size;
125
126         return p;
127 }
128
129 WL_EXPORT void
130 wl_array_copy(struct wl_array *array, struct wl_array *source)
131 {
132         array->size = 0;
133         wl_array_add(array, source->size);
134         memcpy(array->data, source->data, source->size);
135 }
136
137 union map_entry {
138         uintptr_t next;
139         void *data;
140 };
141
142 WL_EXPORT void
143 wl_map_init(struct wl_map *map)
144 {
145         memset(map, 0, sizeof *map);
146 }
147
148 WL_EXPORT void
149 wl_map_release(struct wl_map *map)
150 {
151         wl_array_release(&map->entries);
152 }
153
154 WL_EXPORT uint32_t
155 wl_map_insert_new(struct wl_map *map, void *data)
156 {
157         union map_entry *start, *entry;
158
159         if (map->free_list) {
160                 start = map->entries.data;
161                 entry = &start[map->free_list >> 1];
162                 map->free_list = entry->next;
163         } else {
164                 entry = wl_array_add(&map->entries, sizeof *entry);
165                 start = map->entries.data;
166         }
167
168         entry->data = data;
169
170         return entry - start;
171 }
172
173 WL_EXPORT int
174 wl_map_insert_at(struct wl_map *map, uint32_t i, void *data)
175 {
176         union map_entry *start;
177         uint32_t count;
178
179         /* assert(map->free_list == NULL */
180         count = map->entries.size / sizeof *start;
181
182         if (count < i)
183                 return -1;
184
185         if (count == i)
186                 wl_array_add(&map->entries, sizeof *start);
187
188         start = map->entries.data;
189         start[i].data = data;
190
191         return 0;
192 }
193
194 WL_EXPORT void
195 wl_map_remove(struct wl_map *map, uint32_t i)
196 {
197         union map_entry *start;
198
199         start = map->entries.data;
200         start[i].next = map->free_list;
201         map->free_list = (i << 1) | 1;
202 }
203
204 WL_EXPORT void *
205 wl_map_lookup(struct wl_map *map, uint32_t i)
206 {
207         union map_entry *start;
208         uint32_t count;
209
210         start = map->entries.data;
211         count = map->entries.size / sizeof *start;
212
213         if (i < count && !(start[i].next & 1))
214                 return start[i].data;
215
216         return NULL;
217 }
218
219 WL_EXPORT void
220 wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data)
221 {
222         union map_entry *start, *end, *p;
223
224         start = map->entries.data;
225         end = (union map_entry *) ((char *) map->entries.data + map->entries.size);
226
227         for (p = start; p < end; p++)
228                 if (p->data && !(p->next & 1))
229                         func(p->data, data);
230 }