]> git.saurik.com Git - apple/syslog.git/blame - libsystem_asl.tproj/src/asl_object.c
syslog-349.1.1.tar.gz
[apple/syslog.git] / libsystem_asl.tproj / src / asl_object.c
CommitLineData
f3df4c03
A
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
34static const asl_jump_table_t *asl_jump[ASL_TYPE_COUNT];
35static dispatch_once_t asl_object_once;
36
37static 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
51int
52asl_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
62void
63asl_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
73int
74asl_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
84int
85asl_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
95size_t
96asl_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
106asl_object_private_t *
107asl_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
117asl_object_private_t *
118asl_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
128asl_object_private_t *
129asl_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
139void
140asl_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
150void
151asl_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
161void
af7d442c 162asl_object_append(asl_object_private_t *obj, asl_object_private_t *newobj, void *addr)
f3df4c03 163{
5222c21d 164 uint32_t type = ASL_TYPE_CLIENT;
f3df4c03
A
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;
af7d442c 171 return asl_jump[type]->append(obj, newobj, addr);
f3df4c03
A
172}
173
174void
175asl_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
185asl_object_private_t *
186asl_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
197asl_object_private_t *
198asl_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
209asl_object_t
210asl_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
219void
220asl_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
231asl_object_t
232asl_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
245uint32_t
246asl_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
254const char *
255asl_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
264int
265asl_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
276int
277asl_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
283int
284asl_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
289size_t
290asl_count(asl_object_t obj)
291{
292 return asl_object_count((asl_object_private_t *)obj);
293}
294
295asl_object_t
296asl_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
301asl_object_t
302asl_next(asl_object_t obj)
303{
304 return (asl_object_t)asl_object_next((asl_object_private_t *)obj);
305}
306
307asl_object_t
308asl_prev(asl_object_t obj)
309{
310 return (asl_object_t)asl_object_prev((asl_object_private_t *)obj);
311}
312
313void
314asl_append(asl_object_t a, asl_object_t b)
315{
af7d442c 316 asl_object_append((asl_object_private_t *)a, (asl_object_private_t *)b, __builtin_return_address(0));
f3df4c03
A
317}
318
319void
320asl_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 */
326int
327asl_send(asl_object_t a, asl_object_t b)
328{
af7d442c 329 asl_object_append((asl_object_private_t *)a, (asl_object_private_t *)b, __builtin_return_address(0));
f3df4c03
A
330 return 0;
331}
332
333const char *
334asl_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
343const char *
344asl_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
352int
353asl_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
363int
364asl_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
370int
371asl_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
377void
378asl_reset_iteration(asl_object_t obj, size_t position)
379{
380 asl_object_set_iteration_index((asl_object_private_t *)obj, position);
381}
382
383asl_object_t
384asl_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
389asl_object_t
390asl_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
395void
396asl_free(asl_object_t obj)
397{
398 asl_release(obj);
399}
400
401void
402aslresponse_free(asl_object_t obj)
403{
404 asl_release(obj);
405}
406
407asl_object_t
408aslresponse_next(asl_object_t obj)
409{
410 return (asl_object_t)asl_object_next((asl_object_private_t *)obj);
411}
412
413asl_object_t
414asl_list_from_string(const char *buf)
415{
416 return (asl_object_t)asl_msg_list_from_string(buf);
417}
418
419char *
420asl_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}