|
|
|
/* SPDX-License-Identifier: GPL-3.0-or-later */
|
|
|
|
/* Copyright 2022 Ivan Polyakov */
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \file keyval.h
|
|
|
|
* \brief Simple key-value struct based on an array
|
|
|
|
* to store query strings, dynamic parameters, etc.
|
|
|
|
*/
|
|
|
|
#ifndef RAPIDA_KEYVAL_H_ENTRY
|
|
|
|
#define RAPIDA_KEYVAL_H_ENTRY
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Key-value pair.
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
char *key; /**< Key */
|
|
|
|
char *val; /**< Value */
|
|
|
|
} rpd_keyval_item;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Key-value pairs storage.
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
rpd_keyval_item *items; /**< Key-value pairs array. */
|
|
|
|
int size; /**< Number of elements in rpd_keyval::items. */
|
|
|
|
int capacity; /**< Current capacity (allocated memory). */
|
|
|
|
int unique; /**< Unique flag */
|
|
|
|
} rpd_keyval;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Initialize the rpd_keyval instance.
|
|
|
|
*
|
|
|
|
* \param keyval Key-value storage instance.
|
|
|
|
* \param capacity Initial capacity of the keyval storage.
|
|
|
|
* Set it to 0 if you don't need initial allocation.
|
|
|
|
*
|
|
|
|
* \return Status code.
|
|
|
|
*/
|
|
|
|
int rpd_keyval_init(rpd_keyval *keyval, int capacity);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Insert new key-value pair into the storage.
|
|
|
|
*
|
|
|
|
* If size of the storage is equal to it's capacity, this function firstly
|
|
|
|
* will reallocate rpd_keyval::items.
|
|
|
|
*
|
|
|
|
* \param keyval Key-value storage.
|
|
|
|
* \param key New pair key.
|
|
|
|
* \param value New pair value.
|
|
|
|
*
|
|
|
|
* \return Status code.
|
|
|
|
* `0`: Success.
|
|
|
|
* `1`: Out of memory when reallocate rpd_keyval::items to new capacity.
|
|
|
|
* `2`: Failed to duplicate rpd_keyval_insert::key or rpd_keyval_insert::value.
|
|
|
|
*/
|
|
|
|
int rpd_keyval_insert(rpd_keyval *keyval, const char *key, const char *value);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Finds key-value pair by it's key.
|
|
|
|
*
|
|
|
|
* \param keyval Key-value storage instance.
|
|
|
|
* \param key Key to search.
|
|
|
|
*
|
|
|
|
* \return Found item or NULL.
|
|
|
|
*/
|
|
|
|
rpd_keyval_item *rpd_keyval_find(const rpd_keyval *keyval, const char *key);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Finds all key-value pair by key.
|
|
|
|
*
|
|
|
|
* Useful when storage is not unique.
|
|
|
|
* In request header fields, for example.
|
|
|
|
*
|
|
|
|
* Last item will be NULL.
|
|
|
|
*
|
|
|
|
* \param keyval Key-value storage instance.
|
|
|
|
* \param key Key to search.
|
|
|
|
*
|
|
|
|
* \return Found items or NULL.
|
|
|
|
*/
|
|
|
|
rpd_keyval_item **rpd_keyval_findall(const rpd_keyval *keyval, const char *key);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Free key-val pairs and reset.
|
|
|
|
*
|
|
|
|
* This function don't will free rpd_keyval::items memory,
|
|
|
|
* so capacity will be saved.
|
|
|
|
* And also this function doesn't free keyval itself.
|
|
|
|
* You can do it manually.
|
|
|
|
*
|
|
|
|
* :note: This is done so that you can use keyval in stack,
|
|
|
|
* also it minimize system calls to allocate memory.
|
|
|
|
*
|
|
|
|
* \param keyval Key-value storage.
|
|
|
|
*/
|
|
|
|
void rpd_keyval_cleanup(rpd_keyval *keyval);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* RAPIDA_KEYVAL_H_ENTRY */
|