1 /*
2 * Copyright 2014-2015 iXsystems, Inc.
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 *
26 */
27
28 #include <sys/types.h>
29 #include <mach/mach.h>
30 #include <xpc/launchd.h>
31 #include "xpc_internal.h"
32
33 xpc_object_t
xpc_array_create(const xpc_object_t * objects,size_t count)34 xpc_array_create(const xpc_object_t *objects, size_t count)
35 {
36 struct xpc_object *xo;
37 size_t i;
38 xpc_u val;
39
40 xo = _xpc_prim_create(_XPC_TYPE_ARRAY, val, 0);
41
42 for (i = 0; i < count; i++)
43 xpc_array_append_value(xo, objects[i]);
44
45 return (xo);
46 }
47
48 void
xpc_array_set_value(xpc_object_t xarray,size_t index,xpc_object_t value)49 xpc_array_set_value(xpc_object_t xarray, size_t index, xpc_object_t value)
50 {
51 struct xpc_object *xo, *xotmp, *xotmp2;
52 struct xpc_array_head *arr;
53 size_t i;
54
55 xo = xarray;
56 arr = &xo->xo_array;
57 i = 0;
58
59 if (index == XPC_ARRAY_APPEND)
60 return xpc_array_append_value(xarray, value);
61
62 if (index >= (size_t)xo->xo_size)
63 return;
64
65 TAILQ_FOREACH_SAFE(xotmp, arr, xo_link, xotmp2) {
66 if (i++ == index) {
67 TAILQ_INSERT_AFTER(arr, (struct xpc_object *)value,
68 xotmp, xo_link);
69 TAILQ_REMOVE(arr, xotmp, xo_link);
70 xpc_retain(value);
71 free(xotmp);
72 break;
73 }
74 }
75 }
76
77 void
xpc_array_append_value(xpc_object_t xarray,xpc_object_t value)78 xpc_array_append_value(xpc_object_t xarray, xpc_object_t value)
79 {
80 struct xpc_object *xo;
81 struct xpc_array_head *arr;
82
83 xo = xarray;
84 arr = &xo->xo_array;
85
86 TAILQ_INSERT_TAIL(arr, (struct xpc_object *)value, xo_link);
87 xpc_retain(value);
88 }
89
90
91 xpc_object_t
xpc_array_get_value(xpc_object_t xarray,size_t index)92 xpc_array_get_value(xpc_object_t xarray, size_t index)
93 {
94 struct xpc_object *xo, *xotmp;
95 struct xpc_array_head *arr;
96 size_t i;
97
98 xo = xarray;
99 arr = &xo->xo_array;
100 i = 0;
101
102 if (index > xo->xo_size)
103 return (NULL);
104
105 TAILQ_FOREACH(xotmp, arr, xo_link) {
106 if (i++ == index)
107 return (xotmp);
108 }
109
110 return (NULL);
111 }
112
113 size_t
xpc_array_get_count(xpc_object_t xarray)114 xpc_array_get_count(xpc_object_t xarray)
115 {
116 struct xpc_object *xo;
117
118 xo = xarray;
119 return (xo->xo_size);
120 }
121
122 void
xpc_array_set_bool(xpc_object_t xarray,size_t index,bool value)123 xpc_array_set_bool(xpc_object_t xarray, size_t index, bool value)
124 {
125 struct xpc_object *xo, *xotmp;
126
127 xo = xarray;
128 xotmp = xpc_bool_create(value);
129 return (xpc_array_set_value(xarray, index, xotmp));
130 }
131
132
133 void
xpc_array_set_int64(xpc_object_t xarray,size_t index,int64_t value)134 xpc_array_set_int64(xpc_object_t xarray, size_t index, int64_t value)
135 {
136 struct xpc_object *xo, *xotmp;
137
138 xo = xarray;
139 xotmp = xpc_int64_create(value);
140 return (xpc_array_set_value(xarray, index, xotmp));
141 }
142
143 void
xpc_array_set_uint64(xpc_object_t xarray,size_t index,uint64_t value)144 xpc_array_set_uint64(xpc_object_t xarray, size_t index, uint64_t value)
145 {
146 struct xpc_object *xo, *xotmp;
147
148 xo = xarray;
149 xotmp = xpc_uint64_create(value);
150 return (xpc_array_set_value(xarray, index, xotmp));
151 }
152
153 void
xpc_array_set_double(xpc_object_t xarray,size_t index,double value)154 xpc_array_set_double(xpc_object_t xarray, size_t index, double value)
155 {
156 struct xpc_object *xo, *xotmp;
157
158 xo = xarray;
159 xotmp = xpc_double_create(value);
160 return (xpc_array_set_value(xarray, index, xotmp));
161 }
162
163 void
xpc_array_set_date(xpc_object_t xarray,size_t index,int64_t value)164 xpc_array_set_date(xpc_object_t xarray, size_t index, int64_t value)
165 {
166 struct xpc_object *xo, *xotmp;
167
168 xo = xarray;
169 xotmp = xpc_date_create(value);
170 return (xpc_array_set_value(xarray, index, xotmp));
171 }
172
173 void
xpc_array_set_data(xpc_object_t xarray,size_t index,const void * data,size_t length)174 xpc_array_set_data(xpc_object_t xarray, size_t index, const void *data,
175 size_t length)
176 {
177 struct xpc_object *xo, *xotmp;
178
179 xo = xarray;
180 xotmp = xpc_data_create(data, length);
181 return (xpc_array_set_value(xarray, index, xotmp));
182 }
183
184 void
xpc_array_set_string(xpc_object_t xarray,size_t index,const char * string)185 xpc_array_set_string(xpc_object_t xarray, size_t index, const char *string)
186 {
187 struct xpc_object *xo, *xotmp;
188
189 xo = xarray;
190 xotmp = xpc_string_create(string);
191 return (xpc_array_set_value(xarray, index, xotmp));
192 }
193
194 void
xpc_array_set_uuid(xpc_object_t xarray,size_t index,const uuid_t value)195 xpc_array_set_uuid(xpc_object_t xarray, size_t index, const uuid_t value)
196 {
197 struct xpc_object *xo, *xotmp;
198
199 xo = xarray;
200 xotmp = xpc_uuid_create(value);
201 return (xpc_array_set_value(xarray, index, xotmp));
202 }
203
204 void
xpc_array_set_fd(xpc_object_t xarray,size_t index,int value)205 xpc_array_set_fd(xpc_object_t xarray, size_t index, int value)
206 {
207 struct xpc_object *xo, *xotmp;
208
209 xo = xarray;
210 //xotmp = xpc_fd_create(value);
211 return (xpc_array_set_value(xarray, index, xotmp));
212 }
213
214 void
xpc_array_set_connection(xpc_object_t xarray,size_t index,xpc_connection_t value)215 xpc_array_set_connection(xpc_object_t xarray, size_t index,
216 xpc_connection_t value)
217 {
218
219 }
220
221 bool
xpc_array_get_bool(xpc_object_t xarray,size_t index)222 xpc_array_get_bool(xpc_object_t xarray, size_t index)
223 {
224 struct xpc_object *xotmp;
225
226 xotmp = xpc_array_get_value(xarray, index);
227 return (xpc_bool_get_value(xotmp));
228 }
229
230 int64_t
xpc_array_get_int64(xpc_object_t xarray,size_t index)231 xpc_array_get_int64(xpc_object_t xarray, size_t index)
232 {
233 struct xpc_object *xotmp;
234
235 xotmp = xpc_array_get_value(xarray, index);
236 return (xpc_int64_get_value(xotmp));
237 }
238
239 uint64_t
xpc_array_get_uint64(xpc_object_t xarray,size_t index)240 xpc_array_get_uint64(xpc_object_t xarray, size_t index)
241 {
242 struct xpc_object *xotmp;
243
244 xotmp = xpc_array_get_value(xarray, index);
245 return (xpc_uint64_get_value(xotmp));
246 }
247
248 double
xpc_array_get_double(xpc_object_t xarray,size_t index)249 xpc_array_get_double(xpc_object_t xarray, size_t index)
250 {
251 struct xpc_object *xotmp;
252
253 xotmp = xpc_array_get_value(xarray, index);
254 return (xpc_double_get_value(xotmp));
255 }
256
257 int64_t
xpc_array_get_date(xpc_object_t xarray,size_t index)258 xpc_array_get_date(xpc_object_t xarray, size_t index)
259 {
260 struct xpc_object *xotmp;
261
262 xotmp = xpc_array_get_value(xarray, index);
263 return (xpc_date_get_value(xotmp));
264 }
265
266 const void *
xpc_array_get_data(xpc_object_t xarray,size_t index,size_t * length)267 xpc_array_get_data(xpc_object_t xarray, size_t index, size_t *length)
268 {
269 struct xpc_object *xotmp;
270
271 xotmp = xpc_array_get_value(xarray, index);
272 *length = xpc_data_get_length(xotmp);
273 return (xpc_data_get_bytes_ptr(xotmp));
274 }
275
276 const uint8_t *
xpc_array_get_uuid(xpc_object_t xarray,size_t index)277 xpc_array_get_uuid(xpc_object_t xarray, size_t index)
278 {
279 struct xpc_object *xotmp;
280
281 xotmp = xpc_array_get_value(xarray, index);
282 return (xpc_uuid_get_bytes(xotmp));
283 }
284
285 const char *
xpc_array_get_string(xpc_object_t xarray,size_t index)286 xpc_array_get_string(xpc_object_t xarray, size_t index)
287 {
288 struct xpc_object *xotmp;
289
290 xotmp = xpc_array_get_value(xarray, index);
291 return (xpc_string_get_string_ptr(xotmp));
292 }
293
294 int
xpc_array_dup_fd(xpc_object_t array,size_t index)295 xpc_array_dup_fd(xpc_object_t array, size_t index)
296 {
297 /* XXX */
298 return (-1);
299 }
300
301 xpc_connection_t
xpc_array_get_connection(xpc_object_t array,size_t index)302 xpc_array_get_connection(xpc_object_t array, size_t index)
303 {
304 /* XXX */
305 return (NULL);
306 }
307
308 bool
xpc_array_apply(xpc_object_t xarray,xpc_array_applier_t applier)309 xpc_array_apply(xpc_object_t xarray, xpc_array_applier_t applier)
310 {
311 struct xpc_object *xo, *xotmp;
312 struct xpc_array_head *arr;
313 size_t i;
314
315 i = 0;
316 xo = xarray;
317 arr = &xo->xo_array;
318
319 TAILQ_FOREACH(xotmp, arr, xo_link) {
320 if (!applier(i++, xotmp))
321 return (false);
322 }
323
324 return (true);
325 }
326