208 lines
7.4 KiB
C
208 lines
7.4 KiB
C
#ifndef LIBNAGIOS_KVVEC_H_INCLUDED
|
|
#define LIBNAGIOS_KVVEC_H_INCLUDED
|
|
|
|
/**
|
|
* @file kvvec.h
|
|
* @brief Key/value vector library function and type declarations
|
|
*
|
|
* The kvvec library is nifty as either a configuration meta-format
|
|
* or for IPC purposes. Take a look at the buf2kvvec() and kvvec2buf()
|
|
* pair of functions for the latter.
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* key/value pair
|
|
* One of the two major components of the kvvec api
|
|
*/
|
|
struct key_value {
|
|
char *key; /**< The key */
|
|
char *value; /**< The value */
|
|
int key_len; /**< Length of key */
|
|
int value_len; /**< Length of value */
|
|
};
|
|
|
|
/**
|
|
* key/value vector buffer. Actually just a buffer, but one that gets
|
|
* used as return value and internal tracker for kvvec2buf()
|
|
*/
|
|
struct kvvec_buf {
|
|
char *buf; /**< The buffer */
|
|
unsigned long buflen; /**< Length of buffer */
|
|
unsigned long bufsize; /**< Size of buffer (includes overalloc) */
|
|
};
|
|
|
|
/**
|
|
* key/value vector struct
|
|
* This is the main component of the kvvec library
|
|
* @note This should be made opaque, with a kvvec_foreach() using a
|
|
* callback to iterate over key/value pairs.
|
|
*/
|
|
struct kvvec {
|
|
struct key_value *kv; /**< The key/value array */
|
|
int kv_alloc; /**< Allocated size of key/value array */
|
|
int kv_pairs; /**< Number of key/value pairs */
|
|
int kvv_sorted; /**< Determines if this kvvec has been sorted */
|
|
};
|
|
|
|
/** Portable initializer for stack-allocated key/value vectors */
|
|
#define KVVEC_INITIALIZER { NULL, 0, 0, 0 }
|
|
|
|
/** Parameters for kvvec_destroy() */
|
|
#define KVVEC_FREE_KEYS 1 /**< Free keys when destroying a kv vector */
|
|
#define KVVEC_FREE_VALUES 2 /**< Free values when destroying a kv vector */
|
|
/** Free both keys and values when destroying a kv vector */
|
|
#define KVVEC_FREE_ALL (KVVEC_FREE_KEYS | KVVEC_FREE_VALUES)
|
|
|
|
#define KVVEC_ASSIGN 0 /**< Assign from buf in buf2kvvec_prealloc() */
|
|
#define KVVEC_COPY 1 /**< Copy from buf in buf2kvvec_prealloc() */
|
|
#define KVVEC_APPEND 2 /**< Don't reset kvvec in buf2kvvec_prealloc() */
|
|
|
|
/**
|
|
* Initialize a previously allocated key/value vector
|
|
*
|
|
* @param kvv The key/value vector to initialize
|
|
* @param hint Number of key/value pairs we expect to store
|
|
* @return Pointer to a struct kvvec, properly initialized
|
|
*/
|
|
extern struct kvvec *kvvec_init(struct kvvec *kvv, int hint);
|
|
|
|
/**
|
|
* Create a key/value vector
|
|
*
|
|
* @param hint Number of key/value pairs we expect to store
|
|
* @return Pointer to a struct kvvec, properly initialized
|
|
*/
|
|
extern struct kvvec *kvvec_create(int hint);
|
|
|
|
/**
|
|
* Resize a key/value vector
|
|
* Used by kvvec_grow(). If size is smaller than the current number of
|
|
* used key/value slots, -1 is returned.
|
|
*
|
|
* @param[in] kvv The key/value vector to resize
|
|
* @param[in] size The size to grow to
|
|
* @return 0 on success, < 0 on errors
|
|
*/
|
|
extern int kvvec_resize(struct kvvec *kvv, int size);
|
|
|
|
/**
|
|
* Grow a key/value vector.
|
|
* Used internally as needed by the kvvec api. If 'hint' is zero, the
|
|
* key/value capacity is increased by a third of the current capacity
|
|
* plus a small constant number. This uses kvvec_resize() internally.
|
|
*
|
|
* @param kvv The key/value vector to grow
|
|
* @param hint The amount of key/value slots we should grow by
|
|
* @return 0 on success, < 0 on errors
|
|
*/
|
|
extern int kvvec_grow(struct kvvec *kvv, int hint);
|
|
|
|
/**
|
|
* Return remaining storage capacity of key/value vector
|
|
* @param[in] kvv The key/value vector to check
|
|
* @return Number of key/value pairs that can be stored without growing
|
|
*/
|
|
extern unsigned int kvvec_capacity(struct kvvec *kvv);
|
|
|
|
/**
|
|
* Sort a key/value vector alphabetically by key name
|
|
* @param kvv The key/value vector to sort
|
|
* @return 0
|
|
*/
|
|
extern int kvvec_sort(struct kvvec *kvv);
|
|
|
|
/**
|
|
* Add a key/value pair to an existing key/value vector, with
|
|
* lengths of strings already calculated
|
|
* @param kvv The key/value vector to add this key/value pair to
|
|
* @param key The key
|
|
* @param keylen Length of the key
|
|
* @param value The value
|
|
* @param valuelen Length of the value
|
|
* @return 0 on success, < 0 on errors
|
|
*/
|
|
extern int kvvec_addkv_wlen(struct kvvec *kvv, const char *key, int keylen, const char *value, int valuelen);
|
|
|
|
/**
|
|
* Shortcut to kvvec_addkv_wlen() when lengths aren't known
|
|
* @param kvv The key/value vector to add this key/value pair to
|
|
* @param key The key
|
|
* @param value The value
|
|
* @return 0 on success, < 0 on errors
|
|
*/
|
|
#define kvvec_addkv(kvv, key, value) kvvec_addkv_wlen(kvv, key, 0, value, 0)
|
|
|
|
/**
|
|
* Walk each key/value pair in a key/value vector, sending them
|
|
* as arguments to a callback function. The callback function has
|
|
* no control over the iteration process and must not delete or
|
|
* modify the key/value vector it's operating on.
|
|
* @param kvv The key/value vector to walk
|
|
* @param arg Extra argument to the callback function
|
|
* @param callback Callback function
|
|
* @return 0 on success, < 0 on errors
|
|
*/
|
|
extern int kvvec_foreach(struct kvvec *kvv, void *arg, int (*callback)(struct key_value *, void *));
|
|
|
|
/**
|
|
* Destroy a key/value vector
|
|
* @param kvv The key/value vector to destroy
|
|
* @param flags or'ed combination of KVVEC_FREE_{KEYS,VALUES}, or KVVEC_FREE_ALL
|
|
* @return 0 on success, < 0 on errors
|
|
*/
|
|
extern int kvvec_destroy(struct kvvec *kvv, int flags);
|
|
|
|
/**
|
|
* Free key/value pairs associated with a key/value vector
|
|
* @param kvv The key/value vector to operate on
|
|
* @param flags flags or'ed combination of KVVEC_FREE_{KEYS,VALUES}, or KVVEC_FREE_ALL
|
|
*/
|
|
void kvvec_free_kvpairs(struct kvvec *kvv, int flags);
|
|
|
|
/**
|
|
* Create a linear buffer of all the key/value pairs and
|
|
* return it as a kvvec_buf. The caller must free() all
|
|
* pointers in the returned kvvec_buf
|
|
* (FIXME: add kvvec_buf_destroy(), or move this and its counterpart
|
|
* out of the kvvec api into a separate one)
|
|
*
|
|
* @param kvv The key/value vector to convert
|
|
* @param kv_sep Character separating keys and their values
|
|
* @param pair_sep Character separating key/value pairs
|
|
* @param overalloc Integer determining how much extra data we should
|
|
* allocate. The overallocated memory is filled with
|
|
* nul bytes.
|
|
* @return A pointer to a newly created kvvec_buf structure
|
|
*/
|
|
extern struct kvvec_buf *kvvec2buf(struct kvvec *kvv, char kv_sep, char pair_sep, int overalloc);
|
|
|
|
/**
|
|
* Create a key/value vector from a pre-parsed buffer. Immensely
|
|
* useful for ipc in combination with kvvec2buf().
|
|
*
|
|
* @param str The buffer to convert to a key/value vector
|
|
* @param len Length of buffer to convert
|
|
* @param kvsep Character separating key and value
|
|
* @param pair_sep Character separating key/value pairs
|
|
* @param flags bitmask. See KVVEC_{ASSIGN,COPY,APPEND} for values
|
|
* @return The created key/value vector
|
|
*/
|
|
extern struct kvvec *buf2kvvec(char *str, unsigned int len, const char kvsep, const char pair_sep, int flags);
|
|
|
|
/**
|
|
* Parse a buffer into the pre-allocated key/value vector. Immensely
|
|
* useful for ipc in combination with kvvec2buf().
|
|
*
|
|
* @param kvv A pre-allocated key/value vector to populate
|
|
* @param str The buffer to convert to a key/value vector
|
|
* @param len Length of buffer to convert
|
|
* @param kvsep Character separating key and value
|
|
* @param pair_sep Character separating key/value pairs
|
|
* @param flags bitmask. See KVVEC_{ASSIGN,COPY,APPEND} for values
|
|
* @return The number of pairs in the created key/value vector
|
|
*/
|
|
extern int buf2kvvec_prealloc(struct kvvec *kvv, char *str, unsigned int len, const char kvsep, const char pair_sep, int flags);
|
|
/** @} */
|
|
#endif /* INCLUDE_kvvec_h__ */
|