diff --git a/object/dict.c b/object/dict.c index d4b1ff0..8e98b83 100644 --- a/object/dict.c +++ b/object/dict.c @@ -105,7 +105,35 @@ b_status b_dict_put(struct b_dict *dict, const char *key, b_object *value) return B_ERR_NO_MEMORY; } - item->bi_str = b_strdup(key); + item->bi_str = b_string_create_from_cstr(key); + item->bi_value = b_retain(value); + + b_queue_push_back(&bucket->bk_items, &item->bi_entry); + + return B_SUCCESS; +} + +b_status b_dict_put_sk( + struct b_dict *dict, const struct b_string *key, b_object *value) +{ + uint64_t hash = b_string_hash(key); + struct b_dict_bucket *bucket = get_bucket(&dict->d_buckets, hash); + if (!bucket) { + bucket = create_bucket(); + if (!bucket) { + return B_ERR_NO_MEMORY; + } + + bucket->bk_hash = hash; + put_bucket(&dict->d_buckets, bucket); + } + + struct b_dict_bucket_item *item = create_bucket_item(); + if (!item) { + return B_ERR_NO_MEMORY; + } + + item->bi_str = b_string_duplicate(key); item->bi_value = b_retain(value); b_queue_push_back(&bucket->bk_items, &item->bi_entry); @@ -126,7 +154,28 @@ b_object *b_dict_at(const struct b_dict *dict, const char *key) struct b_dict_bucket_item *item = b_unbox(struct b_dict_bucket_item, it.entry, bi_entry); - if (!strcmp(item->bi_str, key)) { + if (!strcmp(b_string_ptr(item->bi_str), key)) { + return item->bi_value; + } + } + + return NULL; +} + +b_object *b_dict_at_sk(const struct b_dict *dict, const struct b_string *key) +{ + uint64_t hash = b_string_hash(key); + struct b_dict_bucket *bucket = get_bucket(&dict->d_buckets, hash); + if (!bucket) { + return NULL; + } + + b_queue_iterator it; + b_queue_foreach (&it, &bucket->bk_items) { + struct b_dict_bucket_item *item + = b_unbox(struct b_dict_bucket_item, it.entry, bi_entry); + + if (b_string_compare(item->bi_str, key)) { return item->bi_value; } } @@ -144,11 +193,26 @@ b_object *b_dict_get(struct b_dict *dict, const char *key) return value; } +b_object *b_dict_get_sk(struct b_dict *dict, const struct b_string *key) +{ + b_object *value = b_dict_at_sk(dict, key); + if (value) { + b_retain(value); + } + + return value; +} + bool b_dict_has_key(const struct b_dict *dict, const char *key) { return b_dict_at(dict, key) != NULL; } +bool b_dict_has_skey(const struct b_dict *dict, const struct b_string *key) +{ + return b_dict_at_sk(dict, key) != NULL; +} + size_t b_dict_get_size(const struct b_dict *dict) { size_t count = 0; @@ -203,7 +267,8 @@ static void dict_to_string(const struct b_object *obj, struct b_stream *out) b_dict_iterator it; b_dict_foreach(&it, dict) { - b_stream_write_fmt(out, NULL, "%s: ", it.key); + b_to_string(B_OBJECT(it.key), out); + b_stream_write_string(out, ": ", NULL); bool is_string = b_typeid(it.value) == B_OBJECT_TYPE_STRING; @@ -243,11 +308,12 @@ static bool dict_iterator_is_valid(const struct b_iterator *it) return b_dict_iterator_is_valid((struct b_dict_iterator *)it); } -static struct b_iterator_ops it_ops - = {.it_next = dict_iterator_next, - .it_close = NULL, - .it_erase = dict_iterator_erase, - .it_is_valid = dict_iterator_is_valid}; +static struct b_iterator_ops it_ops = { + .it_next = dict_iterator_next, + .it_close = NULL, + .it_erase = dict_iterator_erase, + .it_is_valid = dict_iterator_is_valid, +}; int b_dict_iterator_begin(struct b_dict *dict, b_dict_iterator *it) { diff --git a/object/dict.h b/object/dict.h index e0bc013..3f8eb94 100644 --- a/object/dict.h +++ b/object/dict.h @@ -6,9 +6,11 @@ #include #include +struct b_string; + struct b_dict_bucket_item { b_queue_entry bi_entry; - char *bi_str; + struct b_string *bi_str; struct b_object *bi_value; }; diff --git a/object/include/blue/object/dict.h b/object/include/blue/object/dict.h index 531e069..7ba5604 100644 --- a/object/include/blue/object/dict.h +++ b/object/include/blue/object/dict.h @@ -8,6 +8,8 @@ #include #include +struct b_string; + #define B_DICT(p) ((b_dict *)(p)) #define B_DICT_ITEM(k, v) \ @@ -28,7 +30,7 @@ typedef struct b_dict b_dict; typedef struct b_dict_iterator { b_iterator _base; size_t i; - const char *key; + const struct b_string *key; b_object *value; b_dict *_d; @@ -54,10 +56,15 @@ static inline void b_dict_release(b_dict *dict) } BLUE_API b_status b_dict_put(b_dict *dict, const char *key, b_object *value); +BLUE_API b_status b_dict_put_sk( + b_dict *dict, const struct b_string *key, b_object *value); BLUE_API b_object *b_dict_at(const b_dict *dict, const char *key); +BLUE_API b_object *b_dict_at_sk(const b_dict *dict, const struct b_string *key); BLUE_API b_object *b_dict_get(b_dict *dict, const char *key); +BLUE_API b_object *b_dict_get_sk(b_dict *dict, const struct b_string *key); BLUE_API bool b_dict_has_key(const b_dict *dict, const char *key); +BLUE_API bool b_dict_has_skey(const b_dict *dict, const struct b_string *key); BLUE_API size_t b_dict_get_size(const b_dict *dict); BLUE_API bool b_dict_is_empty(const b_dict *dict);