1 | /* $NetBSD: heimbase.h,v 1.2 2017/01/28 21:31:45 christos Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 2010 Kungliga Tekniska Högskolan |
5 | * (Royal Institute of Technology, Stockholm, Sweden). |
6 | * All rights reserved. |
7 | * |
8 | * Portions Copyright (c) 2010 Apple Inc. All rights reserved. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * |
14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions and the following disclaimer. |
16 | * |
17 | * 2. Redistributions in binary form must reproduce the above copyright |
18 | * notice, this list of conditions and the following disclaimer in the |
19 | * documentation and/or other materials provided with the distribution. |
20 | * |
21 | * 3. Neither the name of the Institute nor the names of its contributors |
22 | * may be used to endorse or promote products derived from this software |
23 | * without specific prior written permission. |
24 | * |
25 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |
26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |
29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
35 | * SUCH DAMAGE. |
36 | */ |
37 | |
38 | #ifndef HEIM_BASE_H |
39 | #define HEIM_BASE_H 1 |
40 | |
41 | #include <sys/types.h> |
42 | #if !defined(WIN32) && !defined(HAVE_DISPATCH_DISPATCH_H) && defined(ENABLE_PTHREAD_SUPPORT) |
43 | #include <pthread.h> |
44 | #endif |
45 | #include <krb5/krb5-types.h> |
46 | #include <stdarg.h> |
47 | #ifdef HAVE_STDBOOL_H |
48 | #include <stdbool.h> |
49 | #else |
50 | #ifndef false |
51 | #define false 0 |
52 | #endif |
53 | #ifndef true |
54 | #define true 1 |
55 | #endif |
56 | #endif |
57 | |
58 | #define HEIM_BASE_API_VERSION 20130210 |
59 | |
60 | typedef void * heim_object_t; |
61 | typedef unsigned int heim_tid_t; |
62 | typedef heim_object_t heim_bool_t; |
63 | typedef heim_object_t heim_null_t; |
64 | #ifdef WIN32 |
65 | typedef LONG heim_base_once_t; |
66 | #define HEIM_BASE_ONCE_INIT 0 |
67 | #elif defined(HAVE_DISPATCH_DISPATCH_H) |
68 | typedef long heim_base_once_t; /* XXX arch dependant */ |
69 | #define HEIM_BASE_ONCE_INIT 0 |
70 | #elif defined(ENABLE_PTHREAD_SUPPORT) |
71 | typedef pthread_once_t heim_base_once_t; |
72 | #define HEIM_BASE_ONCE_INIT PTHREAD_ONCE_INIT |
73 | #else |
74 | typedef long heim_base_once_t; /* XXX arch dependant */ |
75 | #define HEIM_BASE_ONCE_INIT 0 |
76 | #endif |
77 | |
78 | #if !defined(__has_extension) |
79 | #define __has_extension(x) 0 |
80 | #endif |
81 | |
82 | #define HEIM_REQUIRE_GNUC(m,n,p) \ |
83 | (((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + __GNUC_PATCHLEVEL__) >= \ |
84 | (((m) * 10000) + ((n) * 100) + (p))) |
85 | |
86 | |
87 | #if __has_extension(__builtin_expect) || HEIM_REQUIRE_GNUC(3,0,0) |
88 | #define heim_builtin_expect(_op,_res) __builtin_expect(_op,_res) |
89 | #else |
90 | #define heim_builtin_expect(_op,_res) (_op) |
91 | #endif |
92 | |
93 | |
94 | void * heim_retain(heim_object_t); |
95 | void heim_release(heim_object_t); |
96 | |
97 | void heim_show(heim_object_t); |
98 | |
99 | typedef void (*heim_type_dealloc)(void *); |
100 | |
101 | void * |
102 | heim_alloc(size_t size, const char *name, heim_type_dealloc dealloc); |
103 | |
104 | heim_tid_t |
105 | heim_get_tid(heim_object_t object); |
106 | |
107 | int |
108 | heim_cmp(heim_object_t a, heim_object_t b); |
109 | |
110 | unsigned long |
111 | heim_get_hash(heim_object_t ptr); |
112 | |
113 | void |
114 | heim_base_once_f(heim_base_once_t *, void *, void (*)(void *)); |
115 | |
116 | void |
117 | heim_abort(const char *fmt, ...) |
118 | HEIMDAL_NORETURN_ATTRIBUTE |
119 | HEIMDAL_PRINTF_ATTRIBUTE((__printf__, 1, 2)); |
120 | |
121 | void |
122 | heim_abortv(const char *fmt, va_list ap) |
123 | HEIMDAL_NORETURN_ATTRIBUTE |
124 | HEIMDAL_PRINTF_ATTRIBUTE((__printf__, 1, 0)); |
125 | |
126 | #define heim_assert(e,t) \ |
127 | (heim_builtin_expect(!(e), 0) ? heim_abort(t ":" #e) : (void)0) |
128 | |
129 | /* |
130 | * |
131 | */ |
132 | |
133 | heim_null_t |
134 | heim_null_create(void); |
135 | |
136 | heim_bool_t |
137 | heim_bool_create(int); |
138 | |
139 | int |
140 | heim_bool_val(heim_bool_t); |
141 | |
142 | /* |
143 | * Array |
144 | */ |
145 | |
146 | typedef struct heim_array_data *heim_array_t; |
147 | |
148 | heim_array_t heim_array_create(void); |
149 | heim_tid_t heim_array_get_type_id(void); |
150 | |
151 | typedef void (*heim_array_iterator_f_t)(heim_object_t, void *, int *); |
152 | typedef int (*heim_array_filter_f_t)(heim_object_t, void *); |
153 | |
154 | int heim_array_append_value(heim_array_t, heim_object_t); |
155 | int heim_array_insert_value(heim_array_t, size_t idx, heim_object_t); |
156 | void heim_array_iterate_f(heim_array_t, void *, heim_array_iterator_f_t); |
157 | void heim_array_iterate_reverse_f(heim_array_t, void *, heim_array_iterator_f_t); |
158 | #ifdef __BLOCKS__ |
159 | void heim_array_iterate(heim_array_t, void (^)(heim_object_t, int *)); |
160 | void heim_array_iterate_reverse(heim_array_t, void (^)(heim_object_t, int *)); |
161 | #endif |
162 | size_t heim_array_get_length(heim_array_t); |
163 | heim_object_t |
164 | heim_array_get_value(heim_array_t, size_t); |
165 | heim_object_t |
166 | heim_array_copy_value(heim_array_t, size_t); |
167 | void heim_array_set_value(heim_array_t, size_t, heim_object_t); |
168 | void heim_array_delete_value(heim_array_t, size_t); |
169 | void heim_array_filter_f(heim_array_t, void *, heim_array_filter_f_t); |
170 | #ifdef __BLOCKS__ |
171 | void heim_array_filter(heim_array_t, int (^)(heim_object_t)); |
172 | #endif |
173 | |
174 | /* |
175 | * Dict |
176 | */ |
177 | |
178 | typedef struct heim_dict_data *heim_dict_t; |
179 | |
180 | heim_dict_t heim_dict_create(size_t size); |
181 | heim_tid_t heim_dict_get_type_id(void); |
182 | |
183 | typedef void (*heim_dict_iterator_f_t)(heim_object_t, heim_object_t, void *); |
184 | |
185 | int heim_dict_set_value(heim_dict_t, heim_object_t, heim_object_t); |
186 | void heim_dict_iterate_f(heim_dict_t, void *, heim_dict_iterator_f_t); |
187 | #ifdef __BLOCKS__ |
188 | void heim_dict_iterate(heim_dict_t, void (^)(heim_object_t, heim_object_t)); |
189 | #endif |
190 | |
191 | heim_object_t |
192 | heim_dict_get_value(heim_dict_t, heim_object_t); |
193 | heim_object_t |
194 | heim_dict_copy_value(heim_dict_t, heim_object_t); |
195 | void heim_dict_delete_key(heim_dict_t, heim_object_t); |
196 | |
197 | /* |
198 | * String |
199 | */ |
200 | |
201 | typedef struct heim_string_data *heim_string_t; |
202 | typedef void (*heim_string_free_f_t)(void *); |
203 | |
204 | heim_string_t heim_string_create(const char *); |
205 | heim_string_t heim_string_ref_create(const char *, heim_string_free_f_t); |
206 | heim_string_t heim_string_create_with_bytes(const void *, size_t); |
207 | heim_string_t heim_string_ref_create_with_bytes(const void *, size_t, |
208 | heim_string_free_f_t); |
209 | heim_string_t heim_string_create_with_format(const char *, ...); |
210 | heim_tid_t heim_string_get_type_id(void); |
211 | const char * heim_string_get_utf8(heim_string_t); |
212 | |
213 | #define HSTR(_str) (__heim_string_constant("" _str "")) |
214 | heim_string_t __heim_string_constant(const char *); |
215 | |
216 | /* |
217 | * Errors |
218 | */ |
219 | |
220 | typedef struct heim_error * heim_error_t; |
221 | |
222 | heim_error_t heim_error_create_enomem(void); |
223 | |
224 | heim_error_t heim_error_create(int, const char *, ...) |
225 | HEIMDAL_PRINTF_ATTRIBUTE((__printf__, 2, 3)); |
226 | |
227 | void heim_error_create_opt(heim_error_t *error, int error_code, const char *fmt, ...) |
228 | HEIMDAL_PRINTF_ATTRIBUTE((__printf__, 3, 4)); |
229 | |
230 | heim_error_t heim_error_createv(int, const char *, va_list) |
231 | HEIMDAL_PRINTF_ATTRIBUTE((__printf__, 2, 0)); |
232 | |
233 | heim_string_t heim_error_copy_string(heim_error_t); |
234 | int heim_error_get_code(heim_error_t); |
235 | |
236 | heim_error_t heim_error_append(heim_error_t, heim_error_t); |
237 | |
238 | /* |
239 | * Path |
240 | */ |
241 | |
242 | heim_object_t heim_path_get(heim_object_t ptr, heim_error_t *error, ...); |
243 | heim_object_t heim_path_copy(heim_object_t ptr, heim_error_t *error, ...); |
244 | heim_object_t heim_path_vget(heim_object_t ptr, heim_error_t *error, |
245 | va_list ap); |
246 | heim_object_t heim_path_vcopy(heim_object_t ptr, heim_error_t *error, |
247 | va_list ap); |
248 | |
249 | int heim_path_vcreate(heim_object_t ptr, size_t size, heim_object_t leaf, |
250 | heim_error_t *error, va_list ap); |
251 | int heim_path_create(heim_object_t ptr, size_t size, heim_object_t leaf, |
252 | heim_error_t *error, ...); |
253 | |
254 | void heim_path_vdelete(heim_object_t ptr, heim_error_t *error, va_list ap); |
255 | void heim_path_delete(heim_object_t ptr, heim_error_t *error, ...); |
256 | |
257 | /* |
258 | * Data (octet strings) |
259 | */ |
260 | |
261 | #ifndef __HEIM_BASE_DATA__ |
262 | #define __HEIM_BASE_DATA__ |
263 | struct heim_base_data { |
264 | size_t length; |
265 | void *data; |
266 | }; |
267 | typedef struct heim_base_data heim_octet_string; |
268 | #endif |
269 | |
270 | typedef struct heim_base_data * heim_data_t; |
271 | typedef void (*heim_data_free_f_t)(void *); |
272 | |
273 | heim_data_t heim_data_create(const void *, size_t); |
274 | heim_data_t heim_data_ref_create(const void *, size_t, heim_data_free_f_t); |
275 | heim_tid_t heim_data_get_type_id(void); |
276 | const heim_octet_string * |
277 | heim_data_get_data(heim_data_t); |
278 | const void * heim_data_get_ptr(heim_data_t); |
279 | size_t heim_data_get_length(heim_data_t); |
280 | |
281 | /* |
282 | * DB |
283 | */ |
284 | |
285 | typedef struct heim_db_data *heim_db_t; |
286 | |
287 | typedef void (*heim_db_iterator_f_t)(heim_data_t, heim_data_t, void *); |
288 | |
289 | typedef int (*heim_db_plug_open_f_t)(void *, const char *, const char *, |
290 | heim_dict_t, void **, heim_error_t *); |
291 | typedef int (*heim_db_plug_clone_f_t)(void *, void **, heim_error_t *); |
292 | typedef int (*heim_db_plug_close_f_t)(void *, heim_error_t *); |
293 | typedef int (*heim_db_plug_lock_f_t)(void *, int, heim_error_t *); |
294 | typedef int (*heim_db_plug_unlock_f_t)(void *, heim_error_t *); |
295 | typedef int (*heim_db_plug_sync_f_t)(void *, heim_error_t *); |
296 | typedef int (*heim_db_plug_begin_f_t)(void *, int, heim_error_t *); |
297 | typedef int (*heim_db_plug_commit_f_t)(void *, heim_error_t *); |
298 | typedef int (*heim_db_plug_rollback_f_t)(void *, heim_error_t *); |
299 | typedef heim_data_t (*heim_db_plug_copy_value_f_t)(void *, heim_string_t, |
300 | heim_data_t, |
301 | heim_error_t *); |
302 | typedef int (*heim_db_plug_set_value_f_t)(void *, heim_string_t, heim_data_t, |
303 | heim_data_t, heim_error_t *); |
304 | typedef int (*heim_db_plug_del_key_f_t)(void *, heim_string_t, heim_data_t, |
305 | heim_error_t *); |
306 | typedef void (*heim_db_plug_iter_f_t)(void *, heim_string_t, void *, |
307 | heim_db_iterator_f_t, heim_error_t *); |
308 | |
309 | struct heim_db_type { |
310 | int version; |
311 | heim_db_plug_open_f_t openf; |
312 | heim_db_plug_clone_f_t clonef; |
313 | heim_db_plug_close_f_t closef; |
314 | heim_db_plug_lock_f_t lockf; |
315 | heim_db_plug_unlock_f_t unlockf; |
316 | heim_db_plug_sync_f_t syncf; |
317 | heim_db_plug_begin_f_t beginf; |
318 | heim_db_plug_commit_f_t commitf; |
319 | heim_db_plug_rollback_f_t rollbackf; |
320 | heim_db_plug_copy_value_f_t copyf; |
321 | heim_db_plug_set_value_f_t setf; |
322 | heim_db_plug_del_key_f_t delf; |
323 | heim_db_plug_iter_f_t iterf; |
324 | }; |
325 | |
326 | extern struct heim_db_type heim_sorted_text_file_dbtype; |
327 | |
328 | #define HEIM_DB_TYPE_VERSION_01 1 |
329 | |
330 | int heim_db_register(const char *dbtype, |
331 | void *data, |
332 | struct heim_db_type *plugin); |
333 | |
334 | heim_db_t heim_db_create(const char *dbtype, const char *dbname, |
335 | heim_dict_t options, heim_error_t *error); |
336 | heim_db_t heim_db_clone(heim_db_t, heim_error_t *); |
337 | int heim_db_begin(heim_db_t, int, heim_error_t *); |
338 | int heim_db_commit(heim_db_t, heim_error_t *); |
339 | int heim_db_rollback(heim_db_t, heim_error_t *); |
340 | heim_tid_t heim_db_get_type_id(void); |
341 | |
342 | int heim_db_set_value(heim_db_t, heim_string_t, heim_data_t, heim_data_t, |
343 | heim_error_t *); |
344 | heim_data_t heim_db_copy_value(heim_db_t, heim_string_t, heim_data_t, |
345 | heim_error_t *); |
346 | int heim_db_delete_key(heim_db_t, heim_string_t, heim_data_t, |
347 | heim_error_t *); |
348 | void heim_db_iterate_f(heim_db_t, heim_string_t, void *, |
349 | heim_db_iterator_f_t, heim_error_t *); |
350 | #ifdef __BLOCKS__ |
351 | void heim_db_iterate(heim_db_t, heim_string_t, |
352 | void (^)(heim_data_t, heim_data_t), heim_error_t *); |
353 | #endif |
354 | |
355 | |
356 | /* |
357 | * Number |
358 | */ |
359 | |
360 | typedef struct heim_number_data *heim_number_t; |
361 | |
362 | heim_number_t heim_number_create(int); |
363 | heim_tid_t heim_number_get_type_id(void); |
364 | int heim_number_get_int(heim_number_t); |
365 | |
366 | /* |
367 | * |
368 | */ |
369 | |
370 | typedef struct heim_auto_release * heim_auto_release_t; |
371 | |
372 | heim_auto_release_t heim_auto_release_create(void); |
373 | void heim_auto_release_drain(heim_auto_release_t); |
374 | heim_object_t heim_auto_release(heim_object_t); |
375 | |
376 | /* |
377 | * JSON |
378 | */ |
379 | typedef enum heim_json_flags { |
380 | HEIM_JSON_F_NO_C_NULL = 1, |
381 | HEIM_JSON_F_STRICT_STRINGS = 2, |
382 | HEIM_JSON_F_NO_DATA = 4, |
383 | HEIM_JSON_F_NO_DATA_DICT = 8, |
384 | HEIM_JSON_F_STRICT_DICT = 16, |
385 | HEIM_JSON_F_STRICT = 31, |
386 | HEIM_JSON_F_CNULL2JSNULL = 32, |
387 | HEIM_JSON_F_TRY_DECODE_DATA = 64, |
388 | HEIM_JSON_F_ONE_LINE = 128 |
389 | } heim_json_flags_t; |
390 | |
391 | heim_object_t heim_json_create(const char *, size_t, heim_json_flags_t, |
392 | heim_error_t *); |
393 | heim_object_t heim_json_create_with_bytes(const void *, size_t, size_t, |
394 | heim_json_flags_t, |
395 | heim_error_t *); |
396 | heim_string_t heim_json_copy_serialize(heim_object_t, heim_json_flags_t, |
397 | heim_error_t *); |
398 | |
399 | |
400 | /* |
401 | * Debug |
402 | */ |
403 | |
404 | heim_string_t |
405 | heim_description(heim_object_t ptr); |
406 | |
407 | /* |
408 | * Binary search. |
409 | * |
410 | * Note: these are private until integrated into the heimbase object system. |
411 | */ |
412 | typedef struct bsearch_file_handle *bsearch_file_handle; |
413 | int _bsearch_text(const char *buf, size_t buf_sz, const char *key, |
414 | char **value, size_t *location, size_t *loops); |
415 | int _bsearch_file_open(const char *fname, size_t max_sz, size_t page_sz, |
416 | bsearch_file_handle *bfh, size_t *reads); |
417 | int _bsearch_file(bsearch_file_handle bfh, const char *key, char **value, |
418 | size_t *location, size_t *loops, size_t *reads); |
419 | void _bsearch_file_info(bsearch_file_handle bfh, size_t *page_sz, |
420 | size_t *max_sz, int *blockwise); |
421 | void _bsearch_file_close(bsearch_file_handle *bfh); |
422 | |
423 | /* |
424 | * Thread-specific keys |
425 | */ |
426 | |
427 | int heim_w32_key_create(unsigned long *, void (*)(void *)); |
428 | int heim_w32_delete_key(unsigned long); |
429 | int heim_w32_setspecific(unsigned long, void *); |
430 | void *heim_w32_getspecific(unsigned long); |
431 | void heim_w32_service_thread_detach(void *); |
432 | |
433 | #endif /* HEIM_BASE_H */ |
434 | |