Libinfo-324.tar.gz
[apple/libinfo.git] / lookup.subproj / si_data.c
1 /*
2 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <assert.h>
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <libkern/OSAtomic.h>
28 #include "si_data.h"
29 #include "si_module.h"
30
31 si_list_t *
32 si_list_add(si_list_t *l, si_item_t *e)
33 {
34 size_t size;
35
36 if (e == NULL) return l;
37
38 if (l == NULL)
39 {
40 l = (si_list_t *)calloc(1, sizeof(si_list_t));
41 l->refcount = 1;
42 }
43
44 if (l != NULL)
45 {
46 size = (l->count + 1) * sizeof(si_item_t *);
47
48 l->entry = (si_item_t **)reallocf(l->entry, size);
49 if (l->entry != NULL)
50 {
51 l->entry[l->count++] = si_item_retain(e);
52 }
53 }
54
55 if ((l == NULL) || (l->entry == NULL))
56 {
57 free(l);
58 l = NULL;
59 errno = ENOMEM;
60 }
61
62 return l;
63 }
64
65 si_list_t *
66 si_list_concat(si_list_t *l, si_list_t *x)
67 {
68 si_item_t *item;
69 uint32_t newcount;
70 size_t size;
71 int i;
72
73 if ((x == NULL) || (x->count == 0)) return l;
74
75 if (l == NULL)
76 {
77 l = (si_list_t *)calloc(1, sizeof(si_list_t));
78 l->refcount = 1;
79 }
80
81 if (l != NULL)
82 {
83 newcount = l->count + x->count;
84 size = newcount * sizeof(si_item_t *);
85
86 l->entry = (si_item_t **)reallocf(l->entry, size);
87 if (l->entry)
88 {
89 for (i = 0; i < x->count; ++i)
90 {
91 item = x->entry[i];
92 si_item_retain(item);
93 l->entry[l->count + i] = item;
94 }
95
96 l->count += x->count;
97 }
98 else
99 {
100 l->count = 0;
101 l = NULL;
102 }
103 }
104
105 if (l == NULL) errno = ENOMEM;
106
107 return l;
108 }
109
110 si_item_t *
111 si_list_next(si_list_t *list)
112 {
113 if (list == NULL) return NULL;
114 if (list->curr >= list->count) return NULL;
115
116 return list->entry[list->curr++];
117 }
118
119 void
120 si_list_reset(si_list_t *list)
121 {
122 if (list != NULL) list->curr = 0;
123 }
124
125 si_list_t *
126 si_list_retain(si_list_t *list)
127 {
128 int32_t rc;
129
130 if (list == NULL) return NULL;
131
132 rc = OSAtomicIncrement32Barrier(&list->refcount);
133 assert(rc >= 1);
134
135 return list;
136 }
137
138 void
139 si_list_release(si_list_t *list)
140 {
141 int32_t rc, i;
142
143 if (list == NULL) return;
144
145 rc = OSAtomicDecrement32Barrier(&list->refcount);
146 assert(rc >= 0);
147
148 if (rc == 0)
149 {
150 for (i = 0; i < list->count; i++)
151 {
152 si_item_release(list->entry[i]);
153 }
154
155 free(list->entry);
156 free(list);
157 }
158 }
159
160 si_item_t *
161 si_item_retain(si_item_t *item)
162 {
163 int32_t rc;
164
165 if (item == NULL) return NULL;
166
167 rc = OSAtomicIncrement32Barrier(&item->refcount);
168 assert(rc >= 1);
169
170 return item;
171 }
172
173 void
174 si_item_release(si_item_t *item)
175 {
176 int32_t rc;
177
178 if (item == NULL) return;
179
180 rc = OSAtomicDecrement32Barrier(&item->refcount);
181 assert(rc >= 0);
182
183 if (rc == 0) free(item);
184 }