Mstdlib-1.24.0
m_bitlist.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2021 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_BITLIST_H__
25#define __M_BITLIST_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31#include <mstdlib/base/m_buf.h>
32#include <mstdlib/base/m_hash_u64str.h>
33#include <mstdlib/base/m_hash_stru64.h>
34
35
36/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
37
38__BEGIN_DECLS
39
40/*! \addtogroup m_bitlist Bitwise flags parser and generator
41 * \ingroup mstdlib_base
42 *
43 * Allows for easy creation of a data structure to parse and generate human
44 * readable flags lists made up of bits.
45 *
46 * \code{.c}
47 * static const M_bitlist_t myflags[] = {
48 * { 1 << 0, "flag1" },
49 * { 1 << 1, "flag2" },
50 * { 1 << 2, "flag3" },
51 * { 0, NULL }
52 * };
53 *
54 * M_uint64 initial_flags = (1<<0) | (1<<2);
55 * char *human_flags = NULL;
56 * M_uint64 final_flags = 0;
57 * M_bool rv = M_FALSE;
58 *
59 * if (!M_bitlist_list(&human_flags, M_BITLIST_FLAG_NONE, myflags, initial_flags, '|', error, sizeof(error)))
60 * goto fail;
61 *
62 * if (!M_bitlist_parse(&final_flags, M_BITLIST_FLAG_NONE, myflags, human_flags, '|', error, sizeof(error)))
63 * goto fail;
64 *
65 * if (initial_flags != final_flags) {
66 * M_snprintf(error, sizeof(error), "initial flags don't match converted");
67 * goto fail;
68 * }
69 * rv = M_TRUE;
70 *
71 * fail:
72 * M_free(human_flags);
73 * if (!rv) {
74 * M_printf("FAILURE: %s", error);
75 * }
76 *
77 * \endcode
78 *
79 * @{
80 */
81
82/*! Data structure to be created as an array and filled in by caller. Must be
83 * terminated by an entry where the name parameter is set to NULL */
84typedef struct {
85 M_uint64 id; /*!< The bit to set, usually a power of 2 */
86 const char *name; /*!< Human-readable name associated with the flag/bit */
88
89/*! Flags that may be passed on to the parser or human-readable generator */
90typedef enum {
91 M_BITLIST_FLAG_NONE = 0, /*!< No Flags */
92 M_BITLIST_FLAG_DONT_TRIM_WHITESPACE = 1<<0, /*!< Parse only. Don't trim whitespace that might surround flags. */
93 M_BITLIST_FLAG_CASE_SENSITIVE = 1<<1, /*!< Parse only. Case sensitive flag matching. */
94 M_BITLIST_FLAG_IGNORE_DUPLICATE_ID = 1<<2, /*!< Ignore duplicate ids. May be used for aliases. First value in list with ID will be used */
95 M_BITLIST_FLAG_IGNORE_UNKNOWN = 1<<3, /*!< If a bit is set that is not known, ignore */
96 M_BITLIST_FLAG_DONT_REQUIRE_POWEROF2 = 1<<4 /*!< Don't require a field to be a power of 2. */
98
99
100/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
101
102/*! Generate a human-readable list from the array provided and bits provided,
103 * delimited by the specified delimiter. Note that there is not a 'hash' version
104 * of this function as it would likely be less efficient and would also not
105 * support the ability to handle aggregate entries that might contain more than
106 * 1 bit set.
107 *
108 * \param[out] out Null-terminated string representing the human-readable bit list
109 * \param[in] flags Flags used when generating the list or determining errors
110 * \param[in] list Array passed in defining all bits to human-readable
111 * \param[in] bits Machine-readable bits passed in to be converted
112 * \param[in] delim Delimiter for human-readable list output
113 * \param[in,out] error Buffer to hold error string.
114 * \param[in] error_len Length of error buffer
115 * \return M_TRUE on success, M_FALSE on failure */
116M_API M_bool M_bitlist_list(char **out, M_bitlist_flags_t flags, const M_bitlist_t *list, M_uint64 bits, unsigned char delim, char *error, size_t error_len);
117
118
119/*! Generate an integer after parsing the provided human-readable string of bits/flags.
120 *
121 * \param[out] out 64bit integer of set bits
122 * \param[in] flags Flags used when parsing the provided human-readable string
123 * \param[in] list Array passed in defining all bits to human-readable name
124 * \param[in] data Human-readable bits/flags in null terminated string form
125 * \param[in] delim Delimiter for human-readable list input
126 * \param[in,out] error Buffer to hold error string.
127 * \param[in] error_len Length of error buffer
128 * \return M_TRUE on success, M_FALSE on failure */
129M_API M_bool M_bitlist_parse(M_uint64 *out, M_bitlist_flags_t flags, const M_bitlist_t *list, const char *data, unsigned char delim, char *error, size_t error_len);
130
131
132/*! Convert a bitlist into hash implementations for more efficient lookups.
133 *
134 * \param[out] hash_toint Hashtable for conversion from string to integer.
135 * \param[out] hash_tostr Hashtable for conversion from integer to string.
136 * \param[in] flags Flags used when generating the list or determining errors.
137 * \param[in] list Array passed in defining all bits to human-readable name
138 * \param[in,out] error Buffer to hold error string.
139 * \param[in] error_len Length of error buffer
140 * \return M_TRUE on success, M_FALSE on failure */
141M_API M_bool M_bitlist_tohash(M_hash_stru64_t **hash_toint, M_hash_u64str_t **hash_tostr, M_bitlist_flags_t flags, const M_bitlist_t *list, char *error, size_t error_len);
142
143
144/*! Generate an integer after parsing the provided human-readable string of bits/flags.
145 *
146 * \param[out] out 64bit integer of set bits
147 * \param[in] flags Flags used when parsing the provided human-readable string
148 * \param[in] hash_toint hash_toint returned from M_bitlist_tohash() with appropriate list.
149 * \param[in] data Human-readable bits/flags in null terminated string form
150 * \param[in] delim Delimiter for human-readable list input
151 * \param[in,out] error Buffer to hold error string.
152 * \param[in] error_len Length of error buffer
153 * \return M_TRUE on success, M_FALSE on failure */
154M_API M_bool M_bitlist_hash_parse(M_uint64 *out, M_bitlist_flags_t flags, const M_hash_stru64_t *hash_toint, const char *data, unsigned char delim, char *error, size_t error_len);
155
156/*! Extract a single name from a bitlist that exactly matches the passed in id.
157 *
158 * \param[in] list Array passed in defining all bits to human-readable name
159 * \param[in] id ID to match
160 * \return NULL if not found, otherwise pointer to name in bitlist
161 */
162M_API const char *M_bitlist_single_tostr(const M_bitlist_t *list, M_uint64 id);
163
164/*! Extract a single id from a bitlist that exactly matches the passed in name.
165 *
166 * \param[in] list Array passed in defining all bits to human-readable name
167 * \param[in] name name to match
168 * \return 0 if not found, otherwise id of name in bitlist
169 */
170M_API M_uint64 M_bitlist_single_toint(const M_bitlist_t *list, const char *name);
171
172
173/*! @} */
174
175__END_DECLS
176
177#endif /* __M_BIT_BUF_H__ */
const char * name
Definition: m_bitlist.h:86
M_uint64 id
Definition: m_bitlist.h:85
const char * M_bitlist_single_tostr(const M_bitlist_t *list, M_uint64 id)
M_uint64 M_bitlist_single_toint(const M_bitlist_t *list, const char *name)
M_bool M_bitlist_list(char **out, M_bitlist_flags_t flags, const M_bitlist_t *list, M_uint64 bits, unsigned char delim, char *error, size_t error_len)
M_bool M_bitlist_parse(M_uint64 *out, M_bitlist_flags_t flags, const M_bitlist_t *list, const char *data, unsigned char delim, char *error, size_t error_len)
M_bool M_bitlist_tohash(M_hash_stru64_t **hash_toint, M_hash_u64str_t **hash_tostr, M_bitlist_flags_t flags, const M_bitlist_t *list, char *error, size_t error_len)
M_bitlist_flags_t
Definition: m_bitlist.h:90
M_bool M_bitlist_hash_parse(M_uint64 *out, M_bitlist_flags_t flags, const M_hash_stru64_t *hash_toint, const char *data, unsigned char delim, char *error, size_t error_len)
@ M_BITLIST_FLAG_IGNORE_DUPLICATE_ID
Definition: m_bitlist.h:94
@ M_BITLIST_FLAG_IGNORE_UNKNOWN
Definition: m_bitlist.h:95
@ M_BITLIST_FLAG_CASE_SENSITIVE
Definition: m_bitlist.h:93
@ M_BITLIST_FLAG_DONT_REQUIRE_POWEROF2
Definition: m_bitlist.h:96
@ M_BITLIST_FLAG_DONT_TRIM_WHITESPACE
Definition: m_bitlist.h:92
@ M_BITLIST_FLAG_NONE
Definition: m_bitlist.h:91
Definition: m_bitlist.h:84
struct M_hash_stru64 M_hash_stru64_t
Definition: m_hash_stru64.h:51
struct M_hash_u64str M_hash_u64str_t
Definition: m_hash_u64str.h:52