From 8ddc462ec199335fc4b2f8ac91584bc6e2a29d4c Mon Sep 17 00:00:00 2001 From: Love Hornquist Astrand Date: Mon, 18 Oct 2010 15:00:34 -0700 Subject: [PATCH] Add heimbase --- Makefile.am | 2 +- base/Makefile.am | 26 ++++ base/array.c | 186 ++++++++++++++++++++++++++ base/baselocl.h | 81 +++++++++++ base/bool.c | 58 ++++++++ base/dict.c | 283 +++++++++++++++++++++++++++++++++++++++ base/heimbase.c | 302 ++++++++++++++++++++++++++++++++++++++++++ base/heimbase.h | 139 +++++++++++++++++++ base/heimbasepriv.h | 95 +++++++++++++ base/json.c | 147 ++++++++++++++++++++ base/null.c | 52 ++++++++ base/number.c | 127 ++++++++++++++++++ base/string.c | 140 ++++++++++++++++++++ base/test_base.c | 103 ++++++++++++++ cf/Makefile.am.common | 3 +- configure.ac | 1 + 16 files changed, 1743 insertions(+), 2 deletions(-) create mode 100644 base/Makefile.am create mode 100644 base/array.c create mode 100644 base/baselocl.h create mode 100644 base/bool.c create mode 100644 base/dict.c create mode 100644 base/heimbase.c create mode 100644 base/heimbase.h create mode 100644 base/heimbasepriv.h create mode 100644 base/json.c create mode 100644 base/null.c create mode 100644 base/number.c create mode 100644 base/string.c create mode 100644 base/test_base.c diff --git a/Makefile.am b/Makefile.am index 26de7bc65..238f1022b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ if KCM kcm_dir = kcm endif -SUBDIRS= include lib kuser kdc admin kadmin kpasswd +SUBDIRS= include base lib kuser kdc admin kadmin kpasswd SUBDIRS+= $(kcm_dir) appl doc tools tests packages etc po ## ACLOCAL = @ACLOCAL@ -I cf diff --git a/base/Makefile.am b/base/Makefile.am new file mode 100644 index 000000000..c4d524c45 --- /dev/null +++ b/base/Makefile.am @@ -0,0 +1,26 @@ + +include $(top_srcdir)/Makefile.am.common + +lib_LTLIBRARIES = libheimbase.la +check_PROGRAMS = test_base + +libheimbase_la_LDFLAGS = -version-info 1:0:0 + +if versionscript +libheimbase_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map +endif + +include_HEADERS = heimbase.h + +libheimbase_la_SOURCES = \ + array.c \ + baselocl.h \ + bool.c \ + dict.c \ + heimbase.c \ + heimbasepriv.h \ + null.c \ + number.c \ + string.c + +test_base_LDADD = $(LIB_heimbase) diff --git a/base/array.c b/base/array.c new file mode 100644 index 000000000..0a2d8b857 --- /dev/null +++ b/base/array.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "baselocl.h" + +/* + * + */ + +struct heim_array_data { + size_t len; + heim_object_t *val; +}; + +static void +array_dealloc(heim_object_t ptr) +{ + heim_array_t array = ptr; + size_t n; + for (n = 0; n < array->len; n++) + heim_release(array->val[n]); + free(array->val); +} + +struct heim_type_data array_object = { + HEIM_TID_ARRAY, + "dict-object", + NULL, + array_dealloc, + NULL, + NULL, + NULL +}; + +/** + * Allocate an array + * + * @return A new allocated array, free with heim_release() + */ + +heim_array_t +heim_array_create(void) +{ + heim_array_t array; + + array = _heim_alloc_object(&array_object, sizeof(*array)); + if (array == NULL) + return NULL; + + array->val = NULL; + array->len = 0; + + return array; +} + +/** + * Get type id of an dict + * + * @return the type id + */ + +heim_tid_t +heim_array_get_type_id(void) +{ + return HEIM_TID_ARRAY; +} + +/** + * Append object to array + * + * @param array array to add too + * @param object the object to add + * + * @return zero if added, errno otherwise + */ + +int +heim_array_append_value(heim_array_t array, heim_object_t object) +{ + heim_object_t *ptr; + + ptr = realloc(array->val, (array->len + 1) * sizeof(array->val[0])); + if (ptr == NULL) + return ENOMEM; + array->val = ptr; + array->val[array->len++] = heim_retain(object); + + return 0; +} + +/** + * Iterate over all objects in array + * + * @param array array to iterate over + * @param fn function to call on each object + * @param ctx context passed to fn + */ + +void +heim_array_iterate_f(heim_array_t array, heim_array_iterator_f_t fn, void *ctx) +{ + size_t n; + for (n = 0; n < array->len; n++) + fn(array->val[n], ctx); +} + +#ifdef __BLOCKS__ +/** + * Iterate over all objects in array + * + * @param array array to iterate over + * @param fn block to call on each object + */ + +void +heim_array_iterate(heim_array_t array, void (^fn)(heim_object_t)) +{ + size_t n; + for (n = 0; n < array->len; n++) + fn(array->val[n]); +} +#endif + +/** + * Get length of array + * + * @param array array to get length of + * + * @return length of array + */ + +size_t +heim_array_get_length(heim_array_t array) +{ + return array->len; +} + +/** + * Copy value of array + * + * @param array array copy object from + * @param idx index of object, 0 based, must be smaller then + * heim_array_get_length() + * + * @return a retained copy of the object + */ + +heim_object_t +heim_array_copy_value(heim_array_t array, size_t idx) +{ + if (idx >= array->len) + HEIM_BASE_ABORT("index too large"); + return heim_retain(array->val[idx]); +} diff --git a/base/baselocl.h b/base/baselocl.h new file mode 100644 index 000000000..6767a060e --- /dev/null +++ b/base/baselocl.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "config.h" + +#include "heimbase.h" +#include "heimbasepriv.h" + +#ifdef HAVE_DISPATCH_DISPATCH_H +#include +#endif + +#define HEIM_BASE_ABORT(x) abort() + +#ifdef __GNUC__ +#define heim_base_atomic_inc(x) __sync_add_and_fetch((x), 1) +#define heim_base_atomic_dec(x) __sync_sub_and_fetch((x), 1) +#define heim_base_atomic_type unsigned int +#define heim_base_atomic_max UINT_MAX + +#define heim_base_exchange_pointer(t,v) __sync_lock_test_and_set((t), (v)) + +#elif 0 /* windows */ + +#define heim_base_exchange_pointer(t,v) InterlockedExchangePointer((t),(v)) + +#else +#error "provide atomic integer operations for your compiler" +#endif + +/* tagged strings/object/XXX */ +#define heim_base_is_tagged(x) (((uintptr_t)(x)) & 0x3) + +#define heim_base_is_tagged_string(x) ((((uintptr_t)(x)) & 0x3) == 2) +#define heim_base_make_tagged_string_ptr(x) ((heim_object_t)(((uintptr_t)(x)) | 2)) +#define heim_base_tagged_string_ptr(x) ((char *)(((uintptr_t)(x)) & (~3))) + + +#define heim_base_is_tagged_object(x) ((((uintptr_t)(x)) & 0x3) == 1) +#define heim_base_make_tagged_object(x, tid) \ + ((heim_object_t)((((uintptr_t)(x)) << 5) | ((tid) << 2) | 0x1)) +#define heim_base_tagged_object_tid(x) ((((uintptr_t)(x)) & 0x1f) >> 2) +#define heim_base_tagged_object_value(x) (((uintptr_t)(x)) >> 5) diff --git a/base/bool.c b/base/bool.c new file mode 100644 index 000000000..72edcc71e --- /dev/null +++ b/base/bool.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "baselocl.h" + +struct heim_type_data _heim_bool_object = { + HEIM_TID_BOOL, + "bool-object", + NULL, + NULL, + NULL, + NULL, + NULL +}; + +heim_bool_t +heim_bool_create(int val) +{ + return heim_base_make_tagged_object(!!val, HEIM_TID_BOOL); +} + +int +heim_bool_val(heim_bool_t ptr) +{ + return heim_base_tagged_object_value(ptr); +} diff --git a/base/dict.c b/base/dict.c new file mode 100644 index 000000000..dda77cc5f --- /dev/null +++ b/base/dict.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2002, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "baselocl.h" + +struct hashentry { + struct hashentry **prev; + struct hashentry *next; + heim_object_t key; + heim_object_t value; +}; + +struct heim_dict_data { + size_t size; + struct hashentry **tab; +}; + +static void +dict_dealloc(void *ptr) +{ + heim_dict_t dict = ptr; + struct hashentry **h, *g, *i; + + for (h = dict->tab; h < &dict->tab[dict->size]; ++h) { + for (g = h[0]; g; g = i) { + i = g->next; + heim_release(g->key); + heim_release(g->value); + free(g); + } + } + free(dict->tab); +} + +struct heim_type_data dict_object = { + HEIM_TID_DICT, + "dict-object", + NULL, + dict_dealloc, + NULL, + NULL, + NULL +}; + +static size_t +isprime(size_t p) +{ + int q, i; + + for(i = 2 ; i < p; i++) { + q = p / i; + + if (i * q == p) + return 0; + if (i * i > p) + return 1; + } + return 1; +} + +static size_t +findprime(size_t p) +{ + if (p % 2 == 0) + p++; + + while (isprime(p) == 0) + p += 2; + + return p; +} + +/** + * Allocate an array + * + * @return A new allocated array, free with heim_release() + */ + +heim_dict_t +heim_dict_create(size_t size) +{ + heim_dict_t dict; + int i; + + dict = _heim_alloc_object(&dict_object, sizeof(*dict)); + + dict->size = findprime(size); + if (dict->size == 0) { + heim_release(dict); + return NULL; + } + + dict->tab = calloc(dict->size, sizeof(dict->tab[0])); + if (dict->tab == NULL) { + dict->size = 0; + heim_release(dict); + return NULL; + } + + return dict; +} + +/** + * Get type id of an dict + * + * @return the type id + */ + +heim_tid_t +heim_dict_get_type_id(void) +{ + return HEIM_TID_DICT; +} + +/* Intern search function */ + +static struct hashentry * +_search(heim_dict_t dict, heim_object_t ptr) +{ + unsigned long v = heim_get_hash(ptr); + struct hashentry *p; + + for (p = dict->tab[v % dict->size]; p != NULL; p = p->next) + if (heim_cmp(ptr, p->key) == 0) + return p; + + return NULL; +} + +/** + * Search for element in hash table + * + * @value dict the dict to search in + * @value key the key to search for + * + * @return a retained copy of the value for key or NULL if not found + */ + +heim_object_t +heim_dict_copy_value(heim_dict_t dict, heim_object_t key) +{ + struct hashentry *p; + p = _search(dict, key); + if (p == NULL) + return NULL; + + return heim_retain(p->value); +} + +/** + * Add key and value to dict + * + * @value dict the dict to add too + * @value key the key to add + * @value value the value to add + * + * @return 0 if added, errno if not + */ + +int +heim_dict_add_value(heim_dict_t dict, heim_object_t key, heim_object_t value) +{ + struct hashentry **tabptr, *h; + + h = _search(dict, key); + if (h) { + heim_release(h->value); + } else { + unsigned long v; + + h = malloc(sizeof(*h)); + if (h == NULL) + return ENOMEM; + + h->key = heim_retain(key); + h->value = heim_retain(value); + + v = heim_get_hash(key); + + tabptr = &dict->tab[v % dict->size]; + h->next = *tabptr; + *tabptr = h; + h->prev = tabptr; + if (h->next) + h->next->prev = &h->next; + } + h->value = heim_retain(value); + + return 0; +} + +/** + * Delete element with key key + * + * @value dict the dict to delete from + * @value key the key to delete + */ + +void +heim_dict_delete_key(heim_dict_t dict, heim_object_t key) +{ + struct hashentry *h = _search(dict, key); + + if (h == NULL) + return; + + heim_release(h->key); + heim_release(h->value); + + if ((*(h->prev) = h->next) != NULL) + h->next->prev = h->prev; + + free(h); +} + +/** + * Do something for each element + * + * @value dict the dict to interate over + * @value func the function to search for + * @value arg argument to func + */ + +void +heim_dict_iterate_f(heim_dict_t dict, heim_dict_iterator_f_t func, void *arg) +{ + struct hashentry **h, *g; + + for (h = dict->tab; h < &dict->tab[dict->size]; ++h) + for (g = *h; g; g = g->next) + func(dict, g->key, g->value, arg); +} + +#ifdef __BLOCKS__ +/** + * Do something for each element + * + * @value dict the dict to interate over + * @value func the function to search for + */ + +void +heim_dict_iterate(heim_dict_t dict, void (^func)(heim_object_t, heim_object_t)) +{ + struct hashentry **h, *g; + + for (h = dict->tab; h < &dict->tab[dict->size]; ++h) + for (g = *h; g; g = g->next) + func(g->key, g->value); +} +#endif diff --git a/base/heimbase.c b/base/heimbase.c new file mode 100644 index 000000000..10c0d3788 --- /dev/null +++ b/base/heimbase.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "baselocl.h" + +static heim_base_atomic_type tidglobal = HEIM_TID_USER; + +struct heim_base { + heim_type_t isa; + heim_base_atomic_type ref_cnt; + uintptr_t isaextra[3]; +}; + +/* specialized version of base */ +struct heim_base_mem { + heim_type_t isa; + heim_base_atomic_type ref_cnt; + const char *name; + void (*dealloc)(void *); + uintptr_t isaextra[1]; +}; + +#define PTR2BASE(ptr) (((struct heim_base *)ptr) - 1) +#define BASE2PTR(ptr) ((void *)(((struct heim_base *)ptr) + 1)) + +/** + * Retain object + * + * @param object to be released, NULL is ok + * + * @return the same object as passed in + */ + +void * +heim_retain(void *ptr) +{ + struct heim_base *p = PTR2BASE(ptr); + + if (ptr == NULL || heim_base_is_tagged(ptr)) + return ptr; + + if (p->ref_cnt == heim_base_atomic_max) + return ptr; + + if ((heim_base_atomic_inc(&p->ref_cnt) - 1) == 0) + HEIM_BASE_ABORT("resurection"); + return ptr; +} + +/** + * Release object, free is reference count reaches zero + * + * @param object to be released + */ + +void +heim_release(void *ptr) +{ + heim_base_atomic_type old; + struct heim_base *p = PTR2BASE(ptr); + + if (ptr == NULL || heim_base_is_tagged(ptr)) + return; + + if (p->ref_cnt == heim_base_atomic_max) + return; + + old = heim_base_atomic_dec(&p->ref_cnt) + 1; + + if (old > 1) + return; + + if (old == 1) { + if (p->isa->dealloc) + p->isa->dealloc(ptr); + free(p); + } else + HEIM_BASE_ABORT("over release"); +} + +static heim_type_t tagged_isa[9] = { + &_heim_number_object, + &_heim_null_object, + &_heim_bool_object, + + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL +}; + +heim_type_t +_heim_get_isa(heim_object_t ptr) +{ + struct heim_base *p; + if (heim_base_is_tagged(ptr)) { + if (heim_base_is_tagged_object(ptr)) + return tagged_isa[heim_base_tagged_object_tid(ptr)]; + if (heim_base_is_tagged_string(ptr)) + return &_heim_string_object; + abort(); + } + p = PTR2BASE(ptr); + return p->isa; +} + +/** + * Get type ID of object + * + * @param object object to get type id of + * + * @return type id of object + */ + +heim_tid_t +heim_get_tid(heim_object_t ptr) +{ + heim_type_t isa = _heim_get_isa(ptr); + return isa->tid; +} + +/** + * Get hash value of object + * + * @param object object to get hash value for + * + * @return a hash value + */ + +unsigned long +heim_get_hash(heim_object_t ptr) +{ + heim_type_t isa = _heim_get_isa(ptr); + if (isa->hash) + return isa->hash(ptr); + return (unsigned long)ptr; +} + +/** + * Compare two objects, returns 0 if equal, can use used for qsort() + * and friends. + * + * @param a first object to compare + * @param b first object to compare + * + * @return 0 if objects are equal + */ + +int +heim_cmp(heim_object_t a, heim_object_t b) +{ + heim_tid_t ta, tb; + heim_type_t isa; + + ta = heim_get_tid(a); + tb = heim_get_tid(b); + + if (ta != tb) + return ta - tb; + + isa = _heim_get_isa(a); + + if (isa->cmp) + return isa->cmp(a, b); + + return (uintptr_t)a - (uintptr_t)b; +} + +/* + * Private - allocates an memory object + */ + +static void +memory_dealloc(void *ptr) +{ + struct heim_base_mem *p = (struct heim_base_mem *)PTR2BASE(ptr); + if (p->dealloc) + p->dealloc(ptr); +} + +struct heim_type_data memory_object = { + HEIM_TID_MEMORY, + "memory-object", + NULL, + memory_dealloc, + NULL, + NULL, + NULL +}; + +void * +heim_alloc(size_t size, const char *name, heim_type_dealloc dealloc) +{ + /* XXX use posix_memalign */ + + struct heim_base_mem *p = calloc(1, size + sizeof(*p)); + if (p == NULL) + return NULL; + p->isa = &memory_object; + p->ref_cnt = 1; + p->name = name; + p->dealloc = dealloc; + return BASE2PTR(p); +} + +heim_type_t +_heim_create_type(const char *name, + heim_type_init init, + heim_type_dealloc dealloc, + heim_type_copy copy, + heim_type_cmp cmp, + heim_type_hash hash) +{ + heim_type_t type; + + /* XXX posix_memalign */ + + type = calloc(1, sizeof(*type)); + if (type == NULL) + return NULL; + + type->tid = heim_base_atomic_inc(&tidglobal); + type->name = name; + type->init = init; + type->dealloc = dealloc; + type->copy = copy; + type->cmp = cmp; + type->hash = hash; + + return type; +} + +heim_object_t +_heim_alloc_object(heim_type_t type, size_t size) +{ + struct heim_base *p = calloc(1, size + sizeof(*p)); + if (p == NULL) + return NULL; + p->isa = type; + p->ref_cnt = 1; + + return BASE2PTR(p); +} + +heim_tid_t +_heim_type_get_tid(heim_type_t type) +{ + return type->tid; +} + +/** + * Call func once and only once + * + * @param once pointer to a heim_base_once_t + * @param ctx context passed to func + * @param func function to be called + */ + +void +heim_base_once_f(heim_base_once_t *once, void *ctx, void (*func)(void *)) +{ +#ifdef HAVE_DISPATCH_DISPATCH_H + dispatch_once_f(once, ctx, func); +#else + #error "write heim_base_once_t" +#endif +} diff --git a/base/heimbase.h b/base/heimbase.h new file mode 100644 index 000000000..ca1afbc24 --- /dev/null +++ b/base/heimbase.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HEIM_BASE_H +#define HEIM_BASE_H 1 + +#include + +typedef void * heim_object_t; +typedef unsigned int heim_tid_t; +typedef heim_object_t heim_bool_t; +typedef heim_object_t heim_null_t; +#define HEIM_BASE_ONCE_INIT 0 +typedef long heim_base_once_t; /* XXX arch dependant */ + + +void * heim_retain(heim_object_t); +void heim_release(heim_object_t); + +heim_tid_t +heim_get_tid(heim_object_t object); + +int +heim_cmp(heim_object_t a, heim_object_t b); + +unsigned long +heim_get_hash(heim_object_t ptr); + +void +heim_base_once_f(heim_base_once_t *, void *, void (*)(void *)); + +/* + * + */ + +heim_null_t +heim_null_create(void); + +heim_bool_t +heim_bool_create(int); + +int +heim_bool_val(heim_bool_t); + +/* + * Array + */ + +typedef struct heim_array_data *heim_array_t; + +heim_array_t heim_array_create(void); +heim_tid_t heim_array_get_type_id(void); + +typedef void (*heim_array_iterator_f_t)(heim_object_t, void *); + +int heim_array_append_value(heim_array_t, heim_object_t); +void heim_array_iterate_f(heim_array_t, heim_array_iterator_f_t, void *); +#ifdef __BLOCKS__ +void heim_array_iterate(heim_array_t, void (^)(heim_object_t)); +#endif +size_t heim_array_get_length(heim_array_t); +heim_object_t + heim_array_copy_value(heim_array_t, size_t); + +/* + * Dict + */ + +typedef struct heim_dict_data *heim_dict_t; + +heim_dict_t heim_dict_create(size_t size); +heim_tid_t heim_dict_get_type_id(void); + +typedef void (*heim_dict_iterator_f_t)(heim_object_t, heim_object_t, heim_object_t, void *); + +int heim_dict_add_value(heim_dict_t, heim_object_t, heim_object_t); +void heim_dict_iterate_f(heim_dict_t, heim_dict_iterator_f_t, void *); +#ifdef __BLOCKS__ +void heim_dict_iterate(heim_dict_t, void (^)(heim_object_t, heim_object_t)); +#endif + +heim_object_t + heim_dict_copy_value(heim_dict_t, heim_object_t); +void heim_dict_delete_key(heim_dict_t, heim_object_t); + +/* + * String + */ + +typedef struct heim_string_data *heim_string_t; + +heim_string_t heim_string_create(const char *); +heim_string_t heim_string_create_with_static(const char *); +heim_tid_t heim_string_get_type_id(void); +const char * heim_string_get_utf8(heim_string_t); + +/* + * Number + */ + +typedef struct heim_number_data *heim_number_t; + +heim_number_t heim_number_create(int); +heim_tid_t heim_number_get_type_id(void); +int heim_number_get_int(heim_number_t); + +#endif /* HEIM_BASE_H */ diff --git a/base/heimbasepriv.h b/base/heimbasepriv.h new file mode 100644 index 000000000..7535759a6 --- /dev/null +++ b/base/heimbasepriv.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +typedef void (*heim_type_init)(void *); +typedef void (*heim_type_dealloc)(void *); +typedef heim_object_t (*heim_type_copy)(void *); +typedef int (*heim_type_cmp)(void *, void *); +typedef unsigned long (*heim_type_hash)(void *); + +typedef struct heim_type_data *heim_type_t; + +enum { + HEIM_TID_NUMBER = 0, + HEIM_TID_NULL = 1, + HEIM_TID_BOOL = 2, + HEIM_TID_TAGGED_UNUSED2 = 3, + HEIM_TID_TAGGED_UNUSED3 = 4, + HEIM_TID_TAGGED_UNUSED4 = 5, + HEIM_TID_TAGGED_UNUSED5 = 6, + HEIM_TID_TAGGED_UNUSED6 = 7, + HEIM_TID_MEMORY = 128, + HEIM_TID_ARRAY = 129, + HEIM_TID_DICT = 130, + HEIM_TID_STRING = 131, + HEIM_TID_USER = 255 + +}; + +struct heim_type_data { + heim_tid_t tid; + const char *name; + heim_type_init init; + heim_type_dealloc dealloc; + heim_type_copy copy; + heim_type_cmp cmp; + heim_type_hash hash; +}; + +heim_type_t _heim_get_isa(heim_object_t); + +/* alloc allocates a plain memory object */ +void * +heim_alloc(size_t size, const char *name, heim_type_dealloc dealloc); + +heim_type_t +_heim_create_type(const char *name, + heim_type_init init, + heim_type_dealloc dealloc, + heim_type_copy copy, + heim_type_cmp cmp, + heim_type_hash hash); + +heim_object_t +_heim_alloc_object(heim_type_t type, size_t size); + +heim_tid_t +_heim_type_get_tid(heim_type_t type); + +/* tagged tid */ +extern struct heim_type_data _heim_null_object; +extern struct heim_type_data _heim_bool_object; +extern struct heim_type_data _heim_number_object; +extern struct heim_type_data _heim_string_object; diff --git a/base/json.c b/base/json.c new file mode 100644 index 000000000..e2f750196 --- /dev/null +++ b/base/json.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "baselocl.h" + + +int +heim_base2json(heim_object_t obj, + void (*out)(char *, void *), void *ctx) +{ + heim_tid_t type = heim_get_tid(obj); + __block int fail = 0, needcomma = 0; + + switch (type) { + case HEIM_TID_ARRAY: + out("[ ", ctx); + heim_array_iterate(obj, ^(heim_object_t sub) { + if (needcomma) + out(", ", ctx); + fail |= heim_base2json(sub, out, ctx); + needcomma = 1; + }); + out("]", ctx); + break; + + case HEIM_TID_DICT: + out("{ ", ctx); + heim_dict_iterate(obj, ^(heim_object_t key, heim_object_t value) { + if (needcomma) + out(", ", ctx); + fail |= heim_base2json(key, out, ctx); + out(" = ", ctx); + fail |= heim_base2json(value, out, ctx); + needcomma = 1; + }); + out("}", ctx); + break; + + case HEIM_TID_STRING: + out("\"", ctx); + out(heim_string_get_utf8(obj), ctx); + out("\"", ctx); + break; + + case HEIM_TID_NUMBER: { + char num[16]; + snprintf(num, sizeof(num), "%d", heim_number_get_int(obj)); + out(num, ctx); + break; + } + case HEIM_TID_NULL: + out("null", ctx); + break; + case HEIM_TID_BOOL: + out(heim_bool_val(obj) ? "true" : "false", ctx); + break; + default: + return 1; + } + return fail; +} + +static int +parse_dict(heim_dict_t dict, char * const *pp, size_t *len) +{ + const char *p = *pp; + while (*len) { + (*len)--; + + if (*p == '\n') { + p += 1; + } else if (isspace(*p)) { + p += 1; + } else if (*p == '}') { + *pp = p + 1; + return 0; + } else { + } + } + return ENOENT; +} + + +heim_object_t +heim_json2base(const void *data, size_t length) +{ + heim_array_t stack; + heim_object_t o = NULL; + const char *p = data; + unsigned long lineno = 1; + + while (length) { + length--; + + if (*p == '\n') { + lineno++; + } else if (isspace((int)*p)) { + ; + } else if (*p == '{') { + o = heim_dict_create(); + + if ((ret = parse_dict(&p, &length)) != 0) + goto out; + } else + abort(); + } + + out: + if (ret && o) { + heim_release(o); + o = NULL; + } + + return o; +} diff --git a/base/null.c b/base/null.c new file mode 100644 index 000000000..66731aad2 --- /dev/null +++ b/base/null.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "baselocl.h" + +struct heim_type_data _heim_null_object = { + HEIM_TID_NULL, + "null-object", + NULL, + NULL, + NULL, + NULL, + NULL +}; + +heim_null_t +heim_null_create(void) +{ + return heim_base_make_tagged_object(0, HEIM_TID_NULL); +} diff --git a/base/number.c b/base/number.c new file mode 100644 index 000000000..72631a531 --- /dev/null +++ b/base/number.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "baselocl.h" + +static void +number_dealloc(void *ptr) +{ +} + +static int +number_cmp(void *a, void *b) +{ + int na, nb; + + if (heim_base_is_tagged_object(a)) + na = heim_base_tagged_object_value(a); + else + na = *(int *)a; + + if (heim_base_is_tagged_object(b)) + nb = heim_base_tagged_object_value(b); + else + nb = *(int *)b; + + return na - nb; +} + +static unsigned long +number_hash(void *ptr) +{ + if (heim_base_is_tagged_object(ptr)) + return heim_base_tagged_object_value(ptr); + return (unsigned long)*(int *)ptr; +} + +struct heim_type_data _heim_number_object = { + HEIM_TID_NUMBER, + "number-object", + NULL, + number_dealloc, + NULL, + number_cmp, + number_hash +}; + +/** + * Create a number object + * + * @param the number to contain in the object + * + * @return a number object + */ + +heim_number_t +heim_number_create(int number) +{ + heim_number_t n; + + if (number < 0xffffff && number >= 0) + return heim_base_make_tagged_object(number, HEIM_TID_NUMBER); + + n = _heim_alloc_object(&_heim_number_object, sizeof(int)); + if (n) + *((int *)n) = number; + return n; +} + +/** + * Return the type ID of number objects + * + * @return type id of number objects + */ + +heim_tid_t +heim_number_get_type_id(void) +{ + return HEIM_TID_NUMBER; +} + +/** + * Get the int value of the content + * + * @param number the number object to get the value from + * + * @return an int + */ + +int +heim_number_get_int(heim_number_t number) +{ + if (heim_base_is_tagged_object(number)) + return heim_base_tagged_object_value(number); + return *(int *)number; +} diff --git a/base/string.c b/base/string.c new file mode 100644 index 000000000..fa93d9216 --- /dev/null +++ b/base/string.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "baselocl.h" +#include + +static void +string_dealloc(void *ptr) +{ +} + +static int +string_cmp(void *a, void *b) +{ + if (heim_base_is_tagged_string(a)) + a = heim_base_tagged_string_ptr(a); + if (heim_base_is_tagged_string(b)) + b = heim_base_tagged_string_ptr(b); + + return strcmp(a, b); +} + +static unsigned long +string_hash(void *ptr) +{ + const char *s; + unsigned long n; + + if (heim_base_is_tagged_string(ptr)) + s = heim_base_tagged_string_ptr(ptr); + else + s = ptr; + + for (n = 0; *s; ++s) + n += *s; + return n; +} + + +struct heim_type_data _heim_string_object = { + HEIM_TID_STRING, + "string-object", + NULL, + string_dealloc, + NULL, + string_cmp, + string_hash +}; + +/** + * Create a string object + * + * @param string the string to create, must be an utf8 string + * + * @return string object + */ + +heim_string_t +heim_string_create(const char *string) +{ + size_t len = strlen(string); + heim_string_t s; + + s = _heim_alloc_object(&_heim_string_object, len + 1); + if (s) + memcpy(s, string, len + 1); + return s; +} + +/** + * Create a string object from a strings allocated in the text segment + * + * @param string the string to create, must be an utf8 string + * + * @return string object + */ + +heim_string_t +heim_string_create_with_static(const char *string) +{ + return heim_base_make_tagged_string_ptr(string); +} + +/** + * Return the type ID of string objects + * + * @return type id of string objects + */ + +heim_tid_t +heim_string_get_type_id(void) +{ + return HEIM_TID_STRING; +} + +/** + * Get the string value of the content + * + * @param string the string object to get the value from + * + * @return a utf8 string + */ + +const char * +heim_string_get_utf8(heim_string_t string) +{ + return (const char *)string; +} diff --git a/base/test_base.c b/base/test_base.c new file mode 100644 index 000000000..ad850575d --- /dev/null +++ b/base/test_base.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2010 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "heimbase.h" +#include "heimbasepriv.h" + +static void +memory_free(heim_object_t obj) +{ +} + +static int +test_memory(void) +{ + void *ptr; + + ptr = heim_alloc(10, "memory", memory_free); + + heim_retain(ptr); + heim_release(ptr); + + heim_retain(ptr); + heim_release(ptr); + + heim_release(ptr); + + ptr = heim_alloc(10, "memory", NULL); + heim_release(ptr); + + return 0; +} + +static int +test_dict(void) +{ + heim_dict_t dict; + heim_number_t a1 = heim_number_create(1); + heim_string_t a2 = heim_string_create("hejsan"); + heim_number_t a3 = heim_number_create(3); + heim_string_t a4 = heim_string_create("foosan"); + + dict = heim_dict_create(10); + + heim_dict_add_value(dict, a1, a2); + heim_dict_add_value(dict, a3, a4); + + heim_dict_delete_key(dict, a3); + heim_dict_delete_key(dict, a1); + + heim_release(a1); + heim_release(a2); + heim_release(a3); + heim_release(a4); + + heim_release(dict); + + return 0; +} + +int +main(int argc, char **argv) +{ + int res = 0; + + res += test_memory(); + res += test_dict(); + + return 0; +} diff --git a/cf/Makefile.am.common b/cf/Makefile.am.common index c3262237f..1470fe0d5 100644 --- a/cf/Makefile.am.common +++ b/cf/Makefile.am.common @@ -227,9 +227,10 @@ if KRB5 LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la \ $(top_builddir)/lib/asn1/libasn1.la LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la -LIB_tsasl = $(top_builddir)/lib/tsasl/libtsasl.la endif +LIB_heimbase = $(top_builddir)/base/libheimbase.la + if DCE LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la endif diff --git a/configure.ac b/configure.ac index df3e4ad15..70597c472 100644 --- a/configure.ac +++ b/configure.ac @@ -576,6 +576,7 @@ AC_CONFIG_FILES(Makefile \ include/hcrypto/Makefile \ include/kadm5/Makefile \ lib/Makefile \ + base/Makefile \ lib/auth/Makefile \ lib/auth/afskauthlib/Makefile \ lib/auth/pam/Makefile \