1 /* $NetBSD: heimbase.h,v 1.3 2019/12/15 22:50:47 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