Key-value pairs

Overview

Definition of API for working with key-value pairs

Copyright (C) 2004-2023 OKTET Labs Ltd. More…

// typedefs

typedef struct te_kvpair te_kvpair;

typedef char* te_kvpair_update_fn(
    const te_kvpair_h *head,
    const char *key,
    const char *value,
    void *user
    );

typedef te_errno te_kvpairs_iter_fn(
    const char *key,
    const char *value,
    void *user
    );

// structs

struct te_kvpair;

// global functions

typedef TAILQ_HEAD(te_kvpair_h, te_kvpair);
void te_kvpair_init(te_kvpair_h* head);
void te_kvpair_fini(te_kvpair_h* head);
void te_kvpair_push(te_kvpair_h* head, const char* key, const char* value_fmt, ...);
void void te_kvpair_push_va(te_kvpair_h* head, const char* key, const char* value_fmt, va_list ap);
te_errno te_kvpair_add(te_kvpair_h* head, const char* key, const char* value_fmt, ...);
te_errno te_errno te_kvpair_add_va(te_kvpair_h* head, const char* key, const char* value_fmt, va_list ap);
te_errno te_kvpairs_del(te_kvpair_h* head, const char* key);
te_errno te_kvpairs_del_all(te_kvpair_h* head, const char* key);
void te_kvpair_update(te_kvpair_h* head, const char* key, te_kvpair_update_fn* callback, void* user);
void te_kvpairs_copy(te_kvpair_h* dest, const te_kvpair_h* src);
void te_kvpairs_copy_key(te_kvpair_h* dest, const te_kvpair_h* src, const char* key);
const char* te_kvpairs_get_nth(const te_kvpair_h* head, const char* key, unsigned int index);
static const char* te_kvpairs_get(const te_kvpair_h* head, const char* key);
te_errno te_kvpairs_get_all(const te_kvpair_h* head, const char* key, te_vec* result);
unsigned int te_kvpairs_count(const te_kvpair_h* head, const char* key);
bool te_kvpairs_has_kv(const te_kvpair_h* head, const char* key, const char* value);
bool te_kvpairs_is_submap(const te_kvpair_h* submap, const te_kvpair_h* supermap);
te_errno te_kvpairs_foreach(const te_kvpair_h* head, te_kvpairs_iter_fn* callback, const char* key, void* user);
te_errno te_kvpair_to_str_gen(const te_kvpair_h* head, const char* delim, te_string* str);
te_errno te_kvpair_to_str(const te_kvpair_h* head, te_string* str);
void te_kvpair_keys_to_str(const te_kvpair_h* head, const char* delim, te_string* str);
void te_kvpair_to_uri_query(const te_kvpair_h* head, te_string* str);
te_errno te_kvpair_from_str(const char* str, te_kvpair_h* head);

// macros

#define TE_KVPAIR_STR_DELIMITER

Detailed Documentation

Definition of API for working with key-value pairs

Copyright (C) 2004-2023 OKTET Labs Ltd. All rights reserved.

Typedefs

typedef struct te_kvpair te_kvpair

Element of the list of key-value pair

typedef char* te_kvpair_update_fn(
    const te_kvpair_h *head,
    const char *key,
    const char *value,
    void *user
    )

Update callback function type for te_kvpair_update().

Parameters:

head

Key-value list (should not be modified by the callback).

key

Key being updated.

value

Old value associated with the key or NULL.

user

User data.

Returns:

heap-allocated new value or NULL.

typedef te_errno te_kvpairs_iter_fn(
    const char *key,
    const char *value,
    void *user
    )

Function type of callbacks used by te_kvpairs_foreach().

Parameters:

key

Current key.

value

Current value.

user

User data.

TE_EOK

te_kvpairs_foreach() will stop immediately and return success to the caller.

Returns:

Status code.

Global Functions

typedef TAILQ_HEAD(te_kvpair_h, te_kvpair)

Head of the list of key-value pair

void te_kvpair_init(te_kvpair_h* head)

Initializes empty key-value pairs list.

Parameters:

head

Head of the list.

void te_kvpair_fini(te_kvpair_h* head)

Free resources allocated for key-value pairs list.

Parameters:

head

Head of the list.

void te_kvpair_push(te_kvpair_h* head, const char* key, const char* value_fmt, ...)

Add a key-value pair.

If there are values bound to key, they are shadowed.

Parameters:

head

Head of the list.

key

Key of value.

value_fmt

Format (*printf-like) string for value string.

Respective parameters for format string.

void void te_kvpair_push_va(te_kvpair_h* head, const char* key, const char* value_fmt, va_list ap)

Add key-value pair using variadic list.

If there are values bound to key, they are shadowed.

Parameters:

head

Head of the list.

key

Key of value.

value_fmt

Format (*printf-like) string for value string.

ap

List of arguments.

te_errno te_kvpair_add(te_kvpair_h* head, const char* key, const char* value_fmt, ...)

Add a key-value pair.

Unlike te_kvpair_push(), the function will fail if there are existing bindings for key.

Parameters:

head

Head of the list.

key

Key of value.

value_fmt

Format (*printf-like) string for value string.

Respective parameters for format string.

TE_EEXIST

The key already exists

Returns:

Status code

te_errno te_errno te_kvpair_add_va(te_kvpair_h* head, const char* key, const char* value_fmt, va_list ap)

Add key-value pair using variadic list.

Unlike te_kvpair_push_va(), the function will fail if there are existing bindings for key.

Parameters:

head

Head of the list.

key

Key of value.

value_fmt

Format (*printf-like) string for value string.

ap

List of arguments.

TE_EEXIST

The key already exists

Returns:

Status code.

te_errno te_kvpairs_del(te_kvpair_h* head, const char* key)

Remove the most recently added key-value pair with a given key.

Parameters:

head

Head of the list.

key

Key of value.

TE_ENOENT

No entry with such key.

0

Pair removed successfully.

Returns:

Status code.

te_errno te_kvpairs_del_all(te_kvpair_h* head, const char* key)

Remove all key-value pairs with a given key.

Parameters:

head

Head of the list.

key

Key to delete (may be NULL in which case all pairs are deleted).

TE_ENOENT

No entries with a given key.

0

Pair removed successfully.

Returns:

Status code.

void te_kvpair_update(te_kvpair_h* head, const char* key, te_kvpair_update_fn* callback, void* user)

Updates a value associated with the key in the key-value list.

If there were no value associated with the key, the callback is called with NULL for its value argument. Otherwise, only the latest binding is updated.

If the callback returns NULL, the binding is deleted.

Parameters:

head

Head of the list.

key

Key to update (may not be NULL).

callback

Updating callback.

user

Callback data.

void te_kvpairs_copy(te_kvpair_h* dest, const te_kvpair_h* src)

Copy all key-values pairs from src to dest.

All existing key-value pairs in dest are retained, so there are overlapping keys, the bindings from dest will be shadowed by the bindings from src.

Parameters:

dest

Destination key-value pairs.

src

Source key-value pairs.

void te_kvpairs_copy_key(te_kvpair_h* dest, const te_kvpair_h* src, const char* key)

Copy all values bound to key in src to dest.

If key is NULL, the function behaves as te_kvpairs_copy(), i.e. all keys are copied.

If there are bindings in dest for key, they will be shadowed.

If there are no bindings for key in src, dest is unchanged.

Parameters:

dest

Destination key-value pairs.

src

Source key-value pairs.

key

Key to copy.

const char* te_kvpairs_get_nth(const te_kvpair_h* head, const char* key, unsigned int index)

Get the index'th value associated with the key.

The most recently added value has the index 0.

Parameters:

head

Head of the list.

key

Key of required value.

index

Ordinal index of a value to fetch.

Returns:

Requested key value or NULL if there is no such key.

static const char* te_kvpairs_get(const te_kvpair_h* head, const char* key)

Get the most recent value associated with the key.

Parameters:

head

Head of the list.

key

Key of required value.

Returns:

Requested key value or NULL if there is no such key.

te_errno te_kvpairs_get_all(const te_kvpair_h* head, const char* key, te_vec* result)

Get all the values associated with key.

The values are appended to the vector result.

The values are not strduped, so result must not be freed with te_vec_deep_free().

Parameters:

head

Head of the list.

key

Key (may be NULL, in which case all values are returned).

result

The output vector.

TE_ENOENT

No value with a given key exists in head.

Returns:

Status code.

unsigned int te_kvpairs_count(const te_kvpair_h* head, const char* key)

Count the number of values associated with key.

Parameters:

head

Head of the list.

key

Key (may be NULL in which case all values are counted).

Returns:

The number of values associated with key.

bool te_kvpairs_has_kv(const te_kvpair_h* head, const char* key, const char* value)

Test whether heads contains a pair of key and value.

Parameters:

head

Head of the list.

key

Key to check (if NULL, any key will suit).

value

Value to check (if NULL, any value will suit).

Returns:

true if the kvpairs contain a given key-value pair.

bool te_kvpairs_is_submap(const te_kvpair_h* submap, const te_kvpair_h* supermap)

Test whether submap is a submap of supermap.

A supermap contains all the key-value pairs of the submap. Order and cardinality are not checked, so if supermap contains less identical key-value pairs as submap, it is still considered a supermap.

Parameters:

submap

Submap.

supermap

Supermap.

Returns:

true if submap is a submap of supermap.

te_errno te_kvpairs_foreach(const te_kvpair_h* head, te_kvpairs_iter_fn* callback, const char* key, void* user)

Call callback for all values bound to key.

If callback returns non-zero status, the function returns immediately, but TE_EOK status is treated as success.

Parameters:

head

Head of the list.

callback

Callback function.

key

Key to scan (may be NULL, in which case all key-value pairs are scanned).

user

User data for callback.

TE_ENOENT

No values have been processed.

Returns:

Status code.

te_errno te_kvpair_to_str_gen(const te_kvpair_h* head, const char* delim, te_string* str)

Convert list of kv_pairs to string representation with delimiter (i.e. key1=val1<delim>key2=val2).

If there are multiple values for the same key, they all be represented as separate key=value pairs.

Parameters:

head

head of the list

delim

delimiter to use

str

pointer to string

Returns:

status code

te_errno te_kvpair_to_str(const te_kvpair_h* head, te_string* str)

Convert list of kv_pairs to string representation (i.e. key1=val1:key2=val2).

If there are multiple values for the same key, they all be represented as separate key=value pairs.

Parameters:

head

Head of the list.

str

Pointer to string.

Returns:

Status code.

See also:

TE_KVPAIR_STR_DELIMITER

void te_kvpair_keys_to_str(const te_kvpair_h* head, const char* delim, te_string* str)

Convert a list of keys from kv_pairs to a string (i.e. key1<delim>key2).

If there are multiple values for the same key, they all be represented as separate key.

Parameters:

head

head of the list

delim

delimiter to use (maybe NULL)

str

pointer to string

Returns:

Status code.

void te_kvpair_to_uri_query(const te_kvpair_h* head, te_string* str)

Convert a list of kv pairs to a valid URI query string.

If str is not empty, & separator is added, so that a query string may be assembled incrementally from several kvpairs.

Parameters:

head

Head of the list

str

TE string

See also:

TE_STRING_URI_ESCAPE_QUERY_VALUE

te_errno te_kvpair_from_str(const char* str, te_kvpair_h* head)

Convert string to list of kv_pairs,

Parameters:

str

Pointer to string

head

Head of the kv_pair list

Status

code

See also:

TE_KVPAIR_STR_DELIMITER