]> git.saurik.com Git - apple/syslog.git/blob - libsystem_asl.tproj/src/asl_object.c
39286bff4b9cf68b29e673a489da1ce864eeada9
[apple/syslog.git] / libsystem_asl.tproj / src / asl_object.c
1 /*
2 * Copyright (c) 2007-2013 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 #include <asl_object.h>
24 #include <asl_core.h>
25 #include <asl_private.h>
26 #include <asl_msg.h>
27 #include <asl_msg_list.h>
28 #include <asl_client.h>
29 #include <asl_store.h>
30 #include <asl_file.h>
31 #include <dispatch/dispatch.h>
32 #include <libkern/OSAtomic.h>
33
34 static const asl_jump_table_t *asl_jump[ASL_TYPE_COUNT];
35 static dispatch_once_t asl_object_once;
36
37 static void
38 _asl_object_init(void)
39 {
40 asl_jump[ASL_TYPE_MSG] = asl_msg_jump_table();
41 asl_jump[ASL_TYPE_QUERY] = asl_msg_jump_table();
42 asl_jump[ASL_TYPE_LIST] = asl_msg_list_jump_table();
43 asl_jump[ASL_TYPE_FILE] = asl_file_jump_table();
44 asl_jump[ASL_TYPE_STORE] = asl_store_jump_table();
45 asl_jump[ASL_TYPE_CLIENT] = asl_client_jump_table();
46 }
47
48 #pragma mark -
49 #pragma mark asl_object
50
51 int
52 asl_object_set_key_val_op(asl_object_private_t *obj, const char *key, const char *val, uint16_t op)
53 {
54 if (obj == NULL) return -1;
55 if (obj->asl_type >= ASL_TYPE_COUNT) return -1;
56
57 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
58 if (asl_jump[obj->asl_type]->set_key_val_op == NULL) return -1;
59 return asl_jump[obj->asl_type]->set_key_val_op(obj, key, val, op);
60 }
61
62 void
63 asl_object_unset_key(asl_object_private_t *obj, const char *key)
64 {
65 if (obj == NULL) return;
66 if (obj->asl_type >= ASL_TYPE_COUNT) return;
67
68 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
69 if (asl_jump[obj->asl_type]->unset_key == NULL) return;
70 asl_jump[obj->asl_type]->unset_key(obj, key);
71 }
72
73 int
74 asl_object_get_val_op_for_key(asl_object_private_t *obj, const char *key, const char **val, uint16_t *op)
75 {
76 if (obj == NULL) return -1;
77 if (obj->asl_type >= ASL_TYPE_COUNT) return -1;
78
79 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
80 if (asl_jump[obj->asl_type]->get_val_op_for_key == NULL) return -1;
81 return asl_jump[obj->asl_type]->get_val_op_for_key(obj, key, val, op);
82 }
83
84 int
85 asl_object_get_key_val_op_at_index(asl_object_private_t *obj, size_t n, const char **key, const char **val, uint16_t *op)
86 {
87 if (obj == NULL) return -1;
88 if (obj->asl_type >= ASL_TYPE_COUNT) return -1;
89
90 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
91 if (asl_jump[obj->asl_type]->get_key_val_op_at_index == NULL) return -1;
92 return asl_jump[obj->asl_type]->get_key_val_op_at_index(obj, n, key, val, op);
93 }
94
95 size_t
96 asl_object_count(asl_object_private_t *obj)
97 {
98 if (obj == NULL) return 0;
99 if (obj->asl_type >= ASL_TYPE_COUNT) return 0;
100
101 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
102 if (asl_jump[obj->asl_type]->count == NULL) return 0;
103 return asl_jump[obj->asl_type]->count(obj);
104 }
105
106 asl_object_private_t *
107 asl_object_next(asl_object_private_t *obj)
108 {
109 if (obj == NULL) return NULL;
110 if (obj->asl_type >= ASL_TYPE_COUNT) return NULL;
111
112 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
113 if (asl_jump[obj->asl_type]->next == NULL) return NULL;
114 return asl_jump[obj->asl_type]->next(obj);
115 }
116
117 asl_object_private_t *
118 asl_object_prev(asl_object_private_t *obj)
119 {
120 if (obj == NULL) return NULL;
121 if (obj->asl_type >= ASL_TYPE_COUNT) return NULL;
122
123 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
124 if (asl_jump[obj->asl_type]->prev == NULL) return NULL;
125 return asl_jump[obj->asl_type]->prev(obj);
126 }
127
128 asl_object_private_t *
129 asl_object_get_object_at_index(asl_object_private_t *obj, size_t n)
130 {
131 if (obj == NULL) return NULL;
132 if (obj->asl_type >= ASL_TYPE_COUNT) return NULL;
133
134 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
135 if (asl_jump[obj->asl_type]->get_object_at_index == NULL) return NULL;
136 return asl_jump[obj->asl_type]->get_object_at_index(obj, n);
137 }
138
139 void
140 asl_object_set_iteration_index(asl_object_private_t *obj, size_t n)
141 {
142 if (obj == NULL) return;
143 if (obj->asl_type >= ASL_TYPE_COUNT) return;
144
145 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
146 if (asl_jump[obj->asl_type]->set_iteration_index == NULL) return;
147 return asl_jump[obj->asl_type]->set_iteration_index(obj, n);
148 }
149
150 void
151 asl_object_remove_object_at_index(asl_object_private_t *obj, size_t n)
152 {
153 if (obj == NULL) return;
154 if (obj->asl_type >= ASL_TYPE_COUNT) return;
155
156 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
157 if (asl_jump[obj->asl_type]->remove_object_at_index == NULL) return;
158 return asl_jump[obj->asl_type]->remove_object_at_index(obj, n);
159 }
160
161 void
162 asl_object_append(asl_object_private_t *obj, asl_object_private_t *newobj)
163 {
164 int type = ASL_TYPE_CLIENT;
165
166 if (obj != NULL) type = obj->asl_type;
167 if (type >= ASL_TYPE_COUNT) return;
168
169 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
170 if (asl_jump[type]->append == NULL) return;
171 return asl_jump[type]->append(obj, newobj);
172 }
173
174 void
175 asl_object_prepend(asl_object_private_t *obj, asl_object_private_t *newobj)
176 {
177 if (obj == NULL) return;
178 if (obj->asl_type >= ASL_TYPE_COUNT) return;
179
180 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
181 if (asl_jump[obj->asl_type]->prepend == NULL) return;
182 return asl_jump[obj->asl_type]->prepend(obj, newobj);
183 }
184
185 asl_object_private_t *
186 asl_object_search(asl_object_private_t *obj, asl_object_private_t *query)
187 {
188 /* default to asl_client_search for obj == NULL */
189 if (obj == NULL) return (asl_object_private_t *)asl_client_search(NULL, (asl_msg_t *)query);
190 if (obj->asl_type >= ASL_TYPE_COUNT) return NULL;
191
192 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
193 if (asl_jump[obj->asl_type]->search == NULL) return NULL;
194 return asl_jump[obj->asl_type]->search(obj, query);
195 }
196
197 asl_object_private_t *
198 asl_object_match(asl_object_private_t *obj, asl_object_private_t *qlist, size_t *last, size_t start, size_t count, uint32_t duration, int32_t dir)
199 {
200 /* default to asl_client_match for obj == NULL */
201 if (obj == NULL) return (asl_object_private_t *)asl_client_match(NULL, (asl_msg_list_t *)qlist, last, start, count, duration, dir);
202 if (obj->asl_type >= ASL_TYPE_COUNT) return NULL;
203
204 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
205 if (asl_jump[obj->asl_type]->match == NULL) return NULL;
206 return asl_jump[obj->asl_type]->match(obj, qlist, last, start, count, duration, dir);
207 }
208
209 asl_object_t
210 asl_retain(asl_object_t obj)
211 {
212 asl_object_private_t *oo = (asl_object_private_t *)obj;
213 if (oo == NULL) return NULL;
214
215 OSAtomicIncrement32Barrier(&(oo->refcount));
216 return obj;
217 }
218
219 void
220 asl_release(asl_object_t obj)
221 {
222 asl_object_private_t *oo = (asl_object_private_t *)obj;
223 if (oo == NULL) return;
224 if (oo->asl_type >= ASL_TYPE_COUNT) return;
225
226 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
227 if (OSAtomicDecrement32Barrier(&(oo->refcount)) != 0) return;
228 if (asl_jump[oo->asl_type]->dealloc != NULL) asl_jump[oo->asl_type]->dealloc(oo);
229 }
230
231 asl_object_t
232 asl_new(uint32_t type)
233 {
234 if (type >= ASL_TYPE_COUNT) return NULL;
235
236 dispatch_once(&asl_object_once, ^{ _asl_object_init(); });
237 if (asl_jump[type]->alloc == NULL) return NULL;
238 asl_object_t out = (asl_object_t)asl_jump[type]->alloc(type);
239 return out;
240 }
241
242 #pragma mark -
243 #pragma mark utilities
244
245 uint32_t
246 asl_get_type(asl_object_t obj)
247 {
248 asl_object_private_t *oo = (asl_object_private_t *)obj;
249
250 if (oo == NULL) return ASL_TYPE_UNDEF;
251 return (int)oo->asl_type;
252 }
253
254 const char *
255 asl_get_value_for_key(asl_object_t obj, const char *key)
256 {
257 const char *val = NULL;
258 uint16_t op;
259
260 asl_object_get_val_op_for_key((asl_object_private_t *)obj, key, &val, &op);
261 return val;
262 }
263
264 int
265 asl_set(asl_object_t obj, const char *key, const char *val)
266 {
267 asl_object_private_t *oo = (asl_object_private_t *)obj;
268 uint16_t op = 0;
269
270 if (oo == NULL) return -1;
271 if (oo->asl_type == ASL_TYPE_QUERY) op = (uint32_t)-1;
272
273 return asl_object_set_key_val_op(oo, key, val, op);
274 }
275
276 int
277 asl_unset_key(asl_object_t obj, const char *key)
278 {
279 asl_object_unset_key((asl_object_private_t *)obj, key);
280 return 0;
281 }
282
283 int
284 asl_set_key_val_op(asl_object_t obj, const char *key, const char *val, uint16_t op)
285 {
286 return asl_object_set_key_val_op((asl_object_private_t *)obj, key, val, op);
287 }
288
289 size_t
290 asl_count(asl_object_t obj)
291 {
292 return asl_object_count((asl_object_private_t *)obj);
293 }
294
295 asl_object_t
296 asl_get_index(asl_object_t list, size_t index)
297 {
298 return (asl_object_t)asl_object_get_object_at_index((asl_object_private_t *)list, index);
299 }
300
301 asl_object_t
302 asl_next(asl_object_t obj)
303 {
304 return (asl_object_t)asl_object_next((asl_object_private_t *)obj);
305 }
306
307 asl_object_t
308 asl_prev(asl_object_t obj)
309 {
310 return (asl_object_t)asl_object_prev((asl_object_private_t *)obj);
311 }
312
313 void
314 asl_append(asl_object_t a, asl_object_t b)
315 {
316 asl_object_append((asl_object_private_t *)a, (asl_object_private_t *)b);
317 }
318
319 void
320 asl_prepend(asl_object_t a, asl_object_t b)
321 {
322 asl_object_prepend((asl_object_private_t *)a, (asl_object_private_t *)b);
323 }
324
325 /* asl_send is implemented as asl_append */
326 int
327 asl_send(asl_object_t a, asl_object_t b)
328 {
329 asl_object_append((asl_object_private_t *)a, (asl_object_private_t *)b);
330 return 0;
331 }
332
333 const char *
334 asl_key(asl_object_t obj, uint32_t n)
335 {
336 const char *key = NULL;
337 size_t sn = n;
338
339 if (asl_object_get_key_val_op_at_index((asl_object_private_t *)obj, sn, &key, NULL, NULL) != 0) return NULL;
340 return key;
341 }
342
343 const char *
344 asl_get(asl_object_t obj, const char *key)
345 {
346 const char *val = NULL;
347
348 if (asl_object_get_val_op_for_key((asl_object_private_t *)obj, key, &val, NULL) != 0) return NULL;
349 return val;
350 }
351
352 int
353 asl_fetch_key_val_op(asl_object_t obj, uint32_t n, const char **key, const char **val, uint32_t *op)
354 {
355 uint16_t op16;
356 size_t sn = n;
357 int status = asl_object_get_key_val_op_at_index((asl_object_private_t *)obj, sn, key, val, &op16);
358 if (status != 0) return status;
359 if (op != NULL) *op = op16;
360 return 0;
361 }
362
363 int
364 asl_set_query(asl_object_t obj, const char *key, const char *val, uint32_t op)
365 {
366 uint16_t op16 = op;
367 return asl_object_set_key_val_op((asl_object_private_t *)obj, key, val, op16);
368 }
369
370 int
371 asl_unset(asl_object_t obj, const char *key)
372 {
373 asl_object_unset_key((asl_object_private_t *)obj, key);
374 return 0;
375 }
376
377 void
378 asl_reset_iteration(asl_object_t obj, size_t position)
379 {
380 asl_object_set_iteration_index((asl_object_private_t *)obj, position);
381 }
382
383 asl_object_t
384 asl_search(asl_object_t data, asl_object_t query)
385 {
386 return (asl_object_t)asl_object_search((asl_object_private_t *)data, (asl_object_private_t *)query);
387 }
388
389 asl_object_t
390 asl_match(asl_object_t data, asl_object_t qlist, size_t *last, size_t start, size_t count, uint32_t duration, int32_t direction)
391 {
392 return (asl_object_t)asl_object_match((asl_object_private_t *)data, (asl_object_private_t *)qlist, last, start, count, duration, direction);
393 }
394
395 void
396 asl_free(asl_object_t obj)
397 {
398 asl_release(obj);
399 }
400
401 void
402 aslresponse_free(asl_object_t obj)
403 {
404 asl_release(obj);
405 }
406
407 asl_object_t
408 aslresponse_next(asl_object_t obj)
409 {
410 return (asl_object_t)asl_object_next((asl_object_private_t *)obj);
411 }
412
413 asl_object_t
414 asl_list_from_string(const char *buf)
415 {
416 return (asl_object_t)asl_msg_list_from_string(buf);
417 }
418
419 char *
420 asl_format(asl_object_t obj, const char *msg_fmt, const char *time_fmt, uint32_t text_encoding)
421 {
422 uint32_t len;
423 uint32_t type = asl_get_type(obj);
424 if (type != ASL_TYPE_MSG) return NULL;
425 return asl_format_message((asl_msg_t *)obj, msg_fmt, time_fmt, text_encoding, &len);
426 }