1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
|
// Copyright 2017 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// \file
#ifndef RCUTILS__TYPES__STRING_MAP_H_
#define RCUTILS__TYPES__STRING_MAP_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <string.h>
#include "rcutils/allocator.h"
#include "rcutils/types/rcutils_ret.h"
#include "rcutils/macros.h"
#include "rcutils/visibility_control.h"
struct rcutils_string_map_impl_s;
/// The structure holding the metadata for a string map.
typedef struct RCUTILS_PUBLIC_TYPE rcutils_string_map_s
{
/// A pointer to the PIMPL implementation type.
struct rcutils_string_map_impl_s * impl;
} rcutils_string_map_t;
/// Return an empty string map struct.
/**
* This function returns an empty and zero initialized string map struct.
*
* Example:
*
* ```c
* // Do not do this:
* // rcutils_string_map_t foo;
* // rcutils_string_map_fini(&foo); // undefined behavior!
*
* // Do this instead:
* rcutils_string_map_t bar = rcutils_get_zero_initialized_string_map();
* rcutils_string_map_fini(&bar); // ok
* ```
* */
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_string_map_t
rcutils_get_zero_initialized_string_map(void);
/// Initialize a rcutils_string_map_t, allocating space for given capacity.
/**
* This function initializes the rcutils_string_map_t with a given initial
* capacity for entries.
* Note this does not allocate space for keys or values in the map, just the
* arrays of pointers to the keys and values.
* rcutils_string_map_set() should still be used when assigning values.
*
* The string_map argument should point to allocated memory and should have
* been zero initialized with rcutils_get_zero_initialized_string_map().
* For example:
*
* ```c
* rcutils_string_map_t string_map = rcutils_get_zero_initialized_string_map();
* rcutils_ret_t ret =
* rcutils_string_map_init(&string_map, 10, rcutils_get_default_allocator());
* if (ret != RCUTILS_RET_OK) {
* // ... do error handling
* }
* // ... use the string map and when done:
* ret = rcutils_string_map_fini(&string_map);
* if (ret != RCUTILS_RET_OK) {
* // ... do error handling
* }
* ```
*
* \param[inout] string_map rcutils_string_map_t to be initialized
* \param[in] initial_capacity the amount of initial capacity for the string map
* \param[in] allocator the allocator to use through out the lifetime of the map
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_BAD_ALLOC if memory allocation fails, or
* \return #RCUTILS_RET_STRING_MAP_ALREADY_INIT if already initialized, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_init(
rcutils_string_map_t * string_map,
size_t initial_capacity,
rcutils_allocator_t allocator);
/// Finalize the previously initialized string map struct.
/**
* This function will free any resources which were created when initializing
* or when calling rcutils_string_map_set().
*
* \param[inout] string_map rcutils_string_map_t to be finalized
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_fini(rcutils_string_map_t * string_map);
/// Get the current capacity of the string map.
/**
* This function will return the internal capacity of the map, which is the
* maximum number of key value pairs the map could hold.
* The capacity can be set initially with rcutils_string_map_init() or
* with rcutils_string_map_reserve().
* The capacity does not indicate how many key value paris are stored in the
* map, the rcutils_string_map_get_size() function can provide that.
*
* \param[in] string_map rcutils_string_map_t to be queried
* \param[out] capacity capacity of the string map
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_STRING_MAP_INVALID if the string map is invalid, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_get_capacity(const rcutils_string_map_t * string_map, size_t * capacity);
/// Get the current size of the string map.
/**
* This function will return the internal size of the map, which is the
* current number of key value pairs in the map.
* The size is changed when calling rcutils_string_map_set_no_resize(),
* rcutils_string_map_set(), or rcutils_string_map_unset().
*
* \param[in] string_map rcutils_string_map_t to be queried
* \param[out] size size of the string map
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_STRING_MAP_INVALID if the string map is invalid, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_get_size(const rcutils_string_map_t * string_map, size_t * size);
/// Reserve a given amount of capacity in the map.
/**
* Increases the capacity of the map to at least the given size.
*
* If the current capacity is less than requested capacity then the capacity
* is increased using the allocator given during initialization of the map in
* rcutils_string_map_init().
* If the requested capacity is less than the current capacity, the capacity
* may be reduced, but no existing key value pairs will be truncated to do so.
* In effect, the capacity will be shrunk to fit the number of items in map or
* the requested capacity, which ever is larger.
*
* If recovering all resources is desired first call rcutils_string_map_clear()
* and then this function with a capacity of 0.
*
* \param[inout] string_map rcutils_string_map_t to have space reserved in
* \param[in] capacity requested size to reserve in the map
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_BAD_ALLOC if memory allocation fails, or
* \return #RCUTILS_RET_STRING_MAP_INVALID if the string map is invalid, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_reserve(rcutils_string_map_t * string_map, size_t capacity);
/// Remove all key value pairs from the map.
/**
* This function will remove all key value pairs from the map, and it will
* reclaim all resources allocated as a result of setting key value pairs.
* rcutils_string_map_fini() should still be called after this.
*
* \param[inout] string_map rcutils_string_map_t to be cleared
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_STRING_MAP_INVALID if the string map is invalid, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_clear(rcutils_string_map_t * string_map);
/// Set a key value pair in the map, increasing capacity if necessary.
/**
* The capacity will be increased if needed using rcutils_string_map_reserve().
* Otherwise it is the same as rcutils_string_map_set_no_resize().
*
* \see rcutils_string_map_set_no_resize()
*
* \param[inout] string_map rcutils_string_map_t to be updated
* \param[in] key map key, must be null terminated c string
* \param[in] value value for given map key, must be null terminated c string
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_BAD_ALLOC if memory allocation fails, or
* \return #RCUTILS_RET_STRING_MAP_INVALID if the string map is invalid, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_set(rcutils_string_map_t * string_map, const char * key, const char * value);
/// Set a key value pair in the map but only if the map has enough capacity.
/**
* If the map already contains the given key, the existing value will be
* replaced with the given value.
* If the map does not contain the given key, and the map has additional
* unused capacity, then it will store the given key and value in the map.
* If there is no unused capacity in the map, then RCUTILS_RET_NOT_ENOUGH_SPACE
* is returned.
*
* The given key and value c strings are copied into the map, and so storage is
* allocated for them in the map when this function is called if necessary.
* The storage allocated for this purpose is reclaimed either when
* rcutils_string_map_fini() is called on this map or when using this function
* or rcutils_string_map_unset().
*
* Any allocation that occurs in this functions uses the allocator of the map,
* which is given when the map is initialized in rcutils_string_map_init().
*
* \param[inout] string_map rcutils_string_map_t to be updated
* \param[in] key map key, must be null terminated c string
* \param[in] value value for given map key, must be null terminated c string
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_BAD_ALLOC if memory allocation fails, or
* \return #RCUTILS_RET_STRING_MAP_INVALID if the string map is invalid, or
* \return #RCUTILS_RET_NOT_ENOUGH_SPACE if map is full, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_set_no_resize(
rcutils_string_map_t * string_map,
const char * key,
const char * value);
/// Unset a key value pair in the map.
/**
* The key needs to be a null terminated c string.
* If the given key is not found, RCUTILS_RET_STRING_KEY_NOT_FOUND is returned.
*
* \param[inout] string_map rcutils_string_map_t to be updated
* \param[in] key map key, must be null terminated c string
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_STRING_MAP_INVALID if the string map is invalid, or
* \return #RCUTILS_RET_STRING_KEY_NOT_FOUND if key not found, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_unset(rcutils_string_map_t * string_map, const char * key);
/// Get whether or not a key exists.
/**
* The key needs to be a null terminated c string.
*
* This function can fail and return false if the key is not found,
* or the string_map is NULL or invalid, or if the key is NULL.
* In all cases no error message is set.
*
* \param[in] string_map rcutils_string_map_t to be searched
* \param[in] key map key, must be null terminated c string
* \return `true` if key is in the map, or
* \return `false` if key is not in the map, or
* \return `false` for invalid arguments, or
* \return `false` if the string map is invalid.
*/
RCUTILS_PUBLIC
bool
rcutils_string_map_key_exists(const rcutils_string_map_t * string_map, const char * key);
/// Get whether or not a key of known length exists.
/**
* Identical to rcutils_string_map_key_exists() but without relying on key to be
* a null terminated c string.
*
* \param[in] string_map rcutils_string_map_t to be searched
* \param[in] key map key
* \param[in] key_length map key length
* \return `true` if key is in the map, or
* \return `false` if key is not in the map, or
* \return `false` for invalid arguments, or
* \return `false` if the string map is invalid.
*/
RCUTILS_PUBLIC
bool
rcutils_string_map_key_existsn(
const rcutils_string_map_t * string_map,
const char * key,
size_t key_length);
/// Get value given a key.
/**
* The key needs to be a null terminated c string.
*
* This function can fail, and therefore return NULL, if the key is not found,
* or the string_map is NULL or invalid, or if the key is NULL.
* In all cases no error message is set.
*
* The returned value string is still owned by the map, and it should not be
* modified or free'd.
* This also means that the value pointer becomes invalid if either
* rcutils_string_map_clear() or rcutils_string_map_fini() are called or if
* the key value pair is updated or removed with one of rcutils_string_map_set()
* or rcutils_string_map_set_no_resize() or rcutils_string_map_unset().
*
* \param[in] string_map rcutils_string_map_t to be searched
* \param[in] key map key, must be null terminated c string
* \return value for the given key if successful, or
* \return `NULL` for invalid arguments, or
* \return `NULL` if the string map is invalid, or
* \return `NULL` if key not found, or
* \return `NULL` if an unknown error occurs.
*/
RCUTILS_PUBLIC
const char *
rcutils_string_map_get(const rcutils_string_map_t * string_map, const char * key);
/// Get value given a key and key length.
/**
* Identical to rcutils_string_map_get() but without relying on key to be a
* null terminated c string.
*
* \param[in] string_map rcutils_string_map_t to be searched
* \param[in] key map key
* \param[in] key_length map key length
* \return value for the given key if successful, or
* \return `NULL` for invalid arguments, or
* \return `NULL` if the string map is invalid, or
* \return `NULL` if key not found, or
* \return `NULL` if an unknown error occurs.
*/
RCUTILS_PUBLIC
const char *
rcutils_string_map_getn(
const rcutils_string_map_t * string_map,
const char * key,
size_t key_length);
/// Get the next key in the map, unless NULL is given, then get the first key.
/**
* This function allows you iteratively get each key in the map.
*
* If NULL is given for the key, then the first key in the map is returned.
* If that returned key if given to the this function, then the next key in the
* map is returned.
* If there are no more keys in the map or if the given key is not in the map,
* NULL is returned.
*
* The order of the keys in the map is arbitrary and if the map is modified
* between calls to this function the behavior is undefined.
* If the map is modifeid then iteration should begin again by passing NULL to
* get the first key again.
*
* This function operates based on the address of the pointer, you cannot pass
* a copy of a key to get the next key.
*
* Example:
*
* ```c
* printf("keys in the map:\n");
* const char * current_key = rcutils_string_map_get_next_key(&map, NULL);
* while (current_key) {
* printf(" - %s\n", current_key);
* current_key = rcutils_string_map_get_next_key(&map, current_key);
* }
* ```
*
* NULL can also be returned if NULL is given for the string_map or if the
* string_map is invalid.
*
* \param[in] string_map rcutils_string_map_t to be queried
* \param[in] key NULL to get the first key or the previous key to get the next
* \return value for the given key if successful, or
* \return `NULL` for invalid arguments, or
* \return `NULL` if the string map is invalid, or
* \return `NULL` if key not found, or
* \return `NULL` if there are no more keys in the map, or
* \return `NULL` if an unknown error occurs.
*/
RCUTILS_PUBLIC
const char *
rcutils_string_map_get_next_key(
const rcutils_string_map_t * string_map,
const char * key);
/// Copy all the key value pairs from one map into another, overwritting and resizing if needed.
/**
* If the destination string map does not have enough storage, then it is will
* be resized.
* If a key value pair exists in the destination map, its value will be
* replaced with the source map's value.
*
* It is possible for only some of the values to be copied if an error happens
* during the copying process, e.g. if memory allocation fails.
*
* \param[in] src_string_map rcutils_string_map_t to be copied from
* \param[inout] dst_string_map rcutils_string_map_t to be copied to
* \return #RCUTILS_RET_OK if successful, or
* \return #RCUTILS_RET_INVALID_ARGUMENT for invalid arguments, or
* \return #RCUTILS_RET_BAD_ALLOC if memory allocation fails, or
* \return #RCUTILS_RET_STRING_MAP_INVALID if the string map is invalid, or
* \return #RCUTILS_RET_ERROR if an unknown error occurs.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
rcutils_ret_t
rcutils_string_map_copy(
const rcutils_string_map_t * src_string_map,
rcutils_string_map_t * dst_string_map);
#ifdef __cplusplus
}
#endif
#endif // RCUTILS__TYPES__STRING_MAP_H_
|