C and C++ web framework.
http://rapida.vilor.one/docs
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.3 KiB
103 lines
2.3 KiB
/* SPDX-License-Identifier: GPL-3.0-or-later */ |
|
/* Copyright 2022 Ivan Polyakov */ |
|
|
|
#include "keyval.h" |
|
#include "utils.h" |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
|
|
/*! |
|
* \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; |
|
}
|
|
|