/* SPDX-License-Identifier: GPL-3.0-or-later */ /* Copyright 2022 Ivan Polyakov */ #include "keyval.h" #include "utils.h" #include #include /*! * \brief Reallocate key-value storage with new capacity. * * \param keyval Key-value storage. * \param capacity New capacity. * * \return Status code. */ static int rpd_keyval_realloc(rpd_keyval *keyval, int capacity); int rpd_keyval_init(rpd_keyval *keyval, int capacity) { keyval->size = keyval->capacity = 0; if (capacity == 0) { keyval->items = NULL; return 0; } keyval->items = (rpd_keyval_item *) malloc(sizeof(rpd_keyval_item) * capacity); if (!keyval->items) { return 1; } keyval->capacity = capacity; return 0; } int rpd_keyval_insert(rpd_keyval *keyval, const char *key, const char *value) { if (!key || !value) return 1; if (keyval->size == keyval->capacity) { int tmp = keyval->capacity == 0 ? 10 : keyval->capacity * 2; if ((tmp = rpd_keyval_realloc(keyval, tmp))) return tmp; } rpd_keyval_item *item = rpd_keyval_find(keyval, key); if (item) { free(item->key); item->key = NULL; if (item->val) { free(item->val); item->val = NULL; } } else { item = &keyval->items[keyval->size]; keyval->size++; } item->key = rpd_strdup(key); item->val = rpd_strdup(value); return item->key && item->val ? 0 : 2; } rpd_keyval_item *rpd_keyval_find(const rpd_keyval *keyval, const char *key) { int i = 0; while (i < keyval->size) { if (!strcmp(keyval->items[i].key, key)) { return keyval->items + i; } i++; } return NULL; } void rpd_keyval_cleanup(rpd_keyval *keyval) { if (keyval->items) { int i = 0; while (i < keyval->size) { rpd_keyval_item *item = keyval->items + i; free(item->key); if (item->val) { free(item->val); } i++; } } keyval->size = 0; } static int rpd_keyval_realloc(rpd_keyval *keyval, int capacity) { keyval->items = realloc(keyval->items, sizeof(rpd_keyval_item) * capacity); if (!keyval->items) { return 1; } keyval->capacity = capacity; return 0; }