From 3cdd5409be0960f4460d911685397c1efcf6c846 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 7 Aug 2013 11:27:51 +0200 Subject: [PATCH 1/1] dalloc documentation and small fixes --- libatalk/talloc/dalloc.c | 124 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 9 deletions(-) diff --git a/libatalk/talloc/dalloc.c b/libatalk/talloc/dalloc.c index 4c06f065..99dd7ec0 100644 --- a/libatalk/talloc/dalloc.c +++ b/libatalk/talloc/dalloc.c @@ -12,6 +12,100 @@ GNU General Public License for more details. */ +/*! + @file + Typesafe, dynamic object store based on talloc + + Usage: + + // + // Define some terminal types: + // + + // A key/value store aka dictionary that supports retrieving elements by key + typedef dict_t DALLOC_CTX; + + // An ordered set that can store different objects which can be retrieved by number + typedef set_t DALLOC_CTX; + + // + // Create an dalloc object and add elementes of different type + // + + // Allocate a new talloc context + TALLOC_CTX *mem_ctx = talloc_new(NULL); + // Create a new dalloc object + DALLOC_CTX *d = talloc_zero(mem_ctx, DALLOC_CTX); + + // Store an int value in the object + uint64_t i = 1; + dalloc_add_copy(d, &i, uint64_t); + + // Store a string + char *str = dalloc_strdup(d, "hello world"); + dalloc_add(d, str, char *); + + // Add a nested object, you later can't fetch this directly + DALLOC_CTX *nested = talloc_zero(d, DALLOC_CTX); + dalloc_add(d, nested, DALLOC_CTX); + + // Add an int value to the nested object, this can be fetched + i = 2; + dalloc_add_copy(nested, &i, uint64_t); + + // Add a nested set + set_t *set = talloc_zero(nested, set_t); + dalloc_add(nested, set, set_t); + + // Add an int value to the set + i = 3; + dalloc_add_copy(set, &i, uint64_t); + + // Add a dictionary (key/value store) + dict_t *dict = talloc_zero(nested, dict_t); + dalloc_add(nested, dict, dict_t); + + // Store a string as key in the dict + str = dalloc_strdup(d, "key"); + dalloc_add(dict, str, char *); + + // Add a value for the key + i = 4; + dalloc_add_copy(dict, &i, uint64_t); + + // + // Fetching value references + // You can fetch anything that is not a DALLOC_CTXs, because passing + // "DALLOC_CTXs" as type to the functions dalloc_get() and dalloc_value_for_key() + // tells the function to step into that object and expect more arguments that specify + // which element to fetch. + // + + // Get reference to an objects element by position + uint64_t *p = dalloc_get(d, "uint64_t", 0); + // p now points to the first int with a value of 1 + + // Get reference to the "hello world" string + str = dalloc_get(d, "char *", 1); + + // You can't fetch a pure DALLOC_CTX + nested = dalloc_get(d, "DALLOC_CTX", 2); + // But you can do this + p = dalloc_get(d, "DALLOC_CTX", 2, "uint64_t", 0); + // p now points to the value 2 + + // You can fetch types that are typedefd DALLOC_CTXs + set = dalloc_get(d, "DALLOC_CTX", 2, "set_t", 1); + + // Fetch int from set, note that you must use DALLOC_CTX as type for the set + p = dalloc_get(d, "DALLOC_CTX", 2, "DALLOC_CTX", 1, "uint64_t", 0); + // p points to 3 + + // Fetch value by key from dictionary + p = dalloc_value_for_key(d, "DALLOC_CTX", 2, "DALLOC_CTX", 2, "key"); + // p now point to 4 +*/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ @@ -62,6 +156,13 @@ int dalloc_size(DALLOC_CTX *d) return talloc_array_length(d->dd_talloc_array); } +/* + * Get pointer to value from a DALLOC object + * + * Returns pointer to object from a DALLOC object. Nested object interation + * is supported by using the type string "DALLOC_CTX". Any other type string + * designates the requested objects type. + */ void *dalloc_get(const DALLOC_CTX *d, ...) { EC_INIT; @@ -74,20 +175,28 @@ void *dalloc_get(const DALLOC_CTX *d, ...) va_start(args, d); type = va_arg(args, const char *); - if (STRCMP(type, !=, "DALLOC_CTX")) - EC_FAIL; - while (STRCMP(type, ==, "DALLOC_CTX")) { elem = va_arg(args, int); - AFP_ASSERT(elem < talloc_array_length(d->dd_talloc_array)); + if (elem >= talloc_array_length(d->dd_talloc_array)) { + LOG(log_error, logtype_sl, "dalloc_get(%s): bound check error: %d >= %d", + type, elem >= talloc_array_length(d->dd_talloc_array)); + EC_FAIL; + } d = d->dd_talloc_array[elem]; type = va_arg(args, const char *); } elem = va_arg(args, int); - AFP_ASSERT(elem < talloc_array_length(d->dd_talloc_array)); + if (elem >= talloc_array_length(d->dd_talloc_array)) { + LOG(log_error, logtype_sl, "dalloc_get(%s): bound check error: %d >= %d", + type, elem, talloc_array_length(d->dd_talloc_array)); + EC_FAIL; + } - p = talloc_check_name(d->dd_talloc_array[elem], type); + if (!(p = talloc_check_name(d->dd_talloc_array[elem], type))) { + LOG(log_error, logtype_sl, "dalloc_get(%d/%s): type mismatch: %s", + type, elem, talloc_get_name(d->dd_talloc_array[elem])); + } va_end(args); @@ -110,9 +219,6 @@ void *dalloc_value_for_key(const DALLOC_CTX *d, ...) va_start(args, d); type = va_arg(args, const char *); - if (STRCMP(type, !=, "DALLOC_CTX")) - EC_FAIL; - while (STRCMP(type, ==, "DALLOC_CTX")) { elem = va_arg(args, int); AFP_ASSERT(elem < talloc_array_length(d->dd_talloc_array)); -- 2.39.2