1 /*
2 * Copyright (c) 2020 - 2023, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35 /**@file nrf_802154_kvmap.h
36 * @brief Simple key-value map.
37 */
38
39 #ifndef NRF_802154_KVMAP_H_INCLUDED__
40 #define NRF_802154_KVMAP_H_INCLUDED__
41
42 #include <stdbool.h>
43 #include <stddef.h>
44
45 /**@brief Structure representing a key-value map */
46 typedef struct
47 {
48 /**@brief Pointer to a memory used to store items */
49 void * p_memory;
50 /**@brief Maximum number of items the key-value map instance is able to store */
51 size_t capacity;
52 /**@brief Number of currently stored items */
53 size_t count;
54 /**@brief Size of a key in bytes */
55 size_t key_size;
56 /**@brief Size of a value in bytes */
57 size_t val_size;
58 } nrf_802154_kvmap_t;
59
60 /**@brief Calculates capacity of memory required to store a key-value map.
61 *
62 * Example:
63 * @code
64 * static uint8_t m_map_memory[NRF_802154_KVMAP_MEMORY_SIZE(10, 7, 6)];
65 * static nrf_802154_kvmap_t m_map;
66 *
67 * nrf_802154_kvmap_init(&m_map, m_map_memory, sizeof(m_map_memory),
68 * 7, 6);
69 * @endcode
70 */
71 #define NRF_802154_KVMAP_MEMORY_SIZE(capacity, key_size, val_size) \
72 ((capacity) * ((key_size) + (val_size)))
73
74 /**@brief Initializes a key-value map instance.
75 *
76 * @param[out] p_kvmap Pointer to an object to initialize.
77 * The pointed object should persist as long as the map is in use.
78 * Cannot be NULL.
79 * @param[in] p_memory Pointer to a memory to be used as items storage.
80 * Memory pointed by this pointer should persist as long as
81 * the map pointed by @p p_kvmap is in use.
82 * Cannot be NULL (with exception, when memsize is 0)
83 * @param[in] memsize Size of the memory pointed by @p p_memory. When defining
84 * storage you can use @ref NRF_802154_KVMAP_MEMORY_SIZE helper macro.
85 * @param[in] key_size Size of the key in bytes within the map. This must be greater than 0.
86 * Please note that keys are compared by @ref memcmp. If a key is a
87 * struct beware of padding in key structs.
88 * @param[in] val_size Size of the value in bytes within the map. This can be 0 if the map
89 * is used to store keys only.
90 */
91 void nrf_802154_kvmap_init(nrf_802154_kvmap_t * p_kvmap,
92 void * p_memory,
93 size_t memsize,
94 size_t key_size,
95 size_t val_size);
96
97 /**@brief Returns total number of items a key-value map can store
98 *
99 * @param[in] p_kvmap Pointer to a key-value map to examine
100 *
101 * @return Number of items a key-value map can store
102 */
nrf_802154_kvmap_capacity(const nrf_802154_kvmap_t * p_kvmap)103 static inline size_t nrf_802154_kvmap_capacity(const nrf_802154_kvmap_t * p_kvmap)
104 {
105 return p_kvmap->capacity;
106 }
107
108 /**@brief Returns current number of items a key-value actually holds.
109 *
110 * @param[in] p_kvmap Pointer to a key-value map to examine
111 *
112 * @return Number of items a key-value map can store
113 */
nrf_802154_kvmap_count(const nrf_802154_kvmap_t * p_kvmap)114 static inline size_t nrf_802154_kvmap_count(const nrf_802154_kvmap_t * p_kvmap)
115 {
116 return p_kvmap->count;
117 }
118
119 /**@brief Adds a key-value pair to a map.
120 *
121 * @param[in,out] p_kvmap Pointer to a key-value map to modify
122 * @param[in] p_key Pointer to a key to add. Must not be NULL. The size must
123 * correspond to @c key_size passed to recent
124 * @ref nrf_802154_kvmap_init
125 * @param[in] p_value Pointer to a value associated with the key to add. The size must
126 * correspond to @c val_size passed to recent
127 * @ref nrf_802154_kvmap_init. This pointer can be NULL when
128 * the @val_size used to initialize was 0.
129 *
130 * @retval true The key-value pair was successfully added to the map.
131 * This value is returned also when the key was already present in
132 * the map. In this case just the value is updated.
133 * @retval false Maximum capacity of the map has been reached and new item
134 * could not be added.
135 */
136 bool nrf_802154_kvmap_add(nrf_802154_kvmap_t * p_kvmap,
137 const void * p_key,
138 const void * p_value);
139
140 /**@brief Removes a key-value pair from a map.
141 *
142 * @param[in,out] p_kvmap Pointer to a key-value map to modify
143 * @param[in] p_key Pointer to a key to remove. Must not be NULL.
144 * The size of a memory pointed by @p p_key must correspond to
145 * @c key_size passed to recent call to @ref nrf_802154_kvmap_init.
146 *
147 * @retval true The key was present in the map and has been removed.
148 * @retval false The key was not found in the map. The map in unmodified.
149 */
150 bool nrf_802154_kvmap_remove(nrf_802154_kvmap_t * p_kvmap, const void * p_key);
151
152 /**@brief Searches for a key in a key-value map.
153 *
154 * @param[in] p_kvmap Pointer to a key-value map to search.
155 * @param[in] p_key Pointer to a key to search. Must not be NULL.
156 * The size of a memory pointed by @p p_key must correspond to
157 * @c key_size passed to recent call @ref nrf_802154_kvmap_init.
158 * @param[out] p_value If NULL. No value associated with potentially found key is retrieved.
159 * If not NULL the size of a memory pointed by @p p_value must
160 * correspond to @c val_size passed to recent @ref nrf_802154_kvmap_init.
161 * When the key is found, the value associated with the key is stored
162 * behind @p p_value. When the key is not found memory behind this
163 * pointer remains unmodified.
164 *
165 * @retval true The key has been found. Value associated with the key is available
166 * behind @p p_value pointer if @p p_value passed was not NULL.
167 * @retval false The key has not been found. Memory pointed by @p p_value
168 * has been not modified.
169 */
170 bool nrf_802154_kvmap_search(const nrf_802154_kvmap_t * p_kvmap,
171 const void * p_key,
172 void * p_value);
173
174 #endif /* NRF_802154_KVMAP_H_INCLUDED__ */
175