From afec949efd586427ff2e926b7d555aa665624a6b Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 24 Jan 2024 16:55:27 +0100 Subject: [PATCH] feat: added dictionary_try_get and _has_key renamed get to get_raw and fixed a NULLreferenceexception --- core/src/dictionary.c | 20 +++++++++++++++++--- core/src/dictionary.h | 33 ++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/core/src/dictionary.c b/core/src/dictionary.c index ed8f6fb..61af8f2 100644 --- a/core/src/dictionary.c +++ b/core/src/dictionary.c @@ -17,7 +17,7 @@ Dictionary dictionary_new(size_t element_size) { Key* internal_dictionary_get(Dictionary* self, uintptr_t keyhash, size_t* out_index) { if(self->list.len == 0) { - *out_index = 0; + if(out_index) *out_index = 0; return NULL; } Key* element; @@ -37,10 +37,12 @@ Key* internal_dictionary_get(Dictionary* self, uintptr_t keyhash, size_t* out_in return list_at_as(Key, &self->list, m); } -void* dictionary_get(Dictionary* self, const char* key) { +void* dictionary_get_raw(Dictionary* self, const char* key) { uintptr_t hash = strhash(key); Key* keyblock = internal_dictionary_get(self, hash, NULL); - return strcmp(key, keyblock->key) != 0 ? NULL : ((char*)keyblock) + sizeof(Key); + return keyblock == NULL || strcmp(key, keyblock->key) != 0 + ? NULL + : ((char*)keyblock) + sizeof(Key); } static inline @@ -98,3 +100,15 @@ int dictionary_erase(Dictionary* self, const char* key) { void dictionary_empty(Dictionary* self) { list_empty(&self->list); } + +int dictionary_has_key(Dictionary* self, const char* key) { + return dictionary_get_raw(self, key) != NULL; +} + +int dictionary_try_get(Dictionary* self, const char* key, void* out) { + void* found = dictionary_get_raw(self, key); + if(found == NULL) + return 0; + memmove(out, found, self->element_size); + return 1; +} diff --git a/core/src/dictionary.h b/core/src/dictionary.h index 1a5361d..367c682 100644 --- a/core/src/dictionary.h +++ b/core/src/dictionary.h @@ -9,28 +9,39 @@ typedef struct Dictionary { size_t element_size; } Dictionary; +// returns a newly initialized dictionary extern Dictionary dictionary_new(size_t element_size); -extern void* dictionary_get(Dictionary* self, const char* key); +// gets a voidptr to the value identified by key +extern void* dictionary_get_raw(Dictionary* self, const char* key); +// inserts or overwrites a new entry identified by key extern int dictionary_set_raw(Dictionary* self, const char* key, void* data); +// remove entry identified by key from dictionary extern int dictionary_erase(Dictionary* self, const char* key); +// clear the contents of the dictionary +// erases all heap-allocated memory, the dictionary can be safely freed after extern void dictionary_empty(Dictionary* self); +// find out if the dictionary contains a value identified by this key +// returns 1 if the key was found +// returns 0 if the key was not found +extern int dictionary_has_key(Dictionary* self, const char* key); +// try to find value identified as key in the dictionary. +// return 1 if the value was found, 0 if not. +// if dictionary_try_get returns 0, memory at out will be unchanged, +// if dictionary_try_get returns 1, found value will be copied into out +extern int dictionary_try_get(Dictionary* self, const char* key, void* out); -static inline int dictionary_set_int(Dictionary* self, const char* key, int data) { - return dictionary_set_raw(self, key, &data); -} -static inline int dictionary_set_unintptr(Dictionary* self, const char* key, uintptr_t data) { - return dictionary_set_raw(self, key, &data); -} +// insert or override value identified by key from a value type (supports rvalues) #define dictionary_set_value(Type_, Dict_, Key_, Value_)\ { Type_ __value = (Type_)Value_; dictionary_set_raw(Dict_, Key_, &__value); } -#define dictionary_check_size(Type_, Dict_)\ -(Dict_)->element_size == sizeof(Type_) +// initialize dictionary to fit values of Type_ #define dictionary_from_type(Type_)\ dictionary_new(sizeof(Type_)) +// get a pointer to value identified by Key_ #define dictionary_get_as(Type_, Dict_, Key_)\ -(Type_*)dictionary_get(Dict_, Key_) +(Type_*)dictionary_get_raw(Dict_, Key_) +// get dereferenced value identified by Key_ #define dictionary_get_value(Type_, Dict_, Key_)\ -*((Type_*)dictionary_get(Dict_, Key_)) +*((Type_*)dictionary_get_raw(Dict_, Key_)) #endif // !_fencer_hash_map_h