BRL-CAD
avs.h
Go to the documentation of this file.
1/* A V S . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2023 United States Government as represented by
5 * the U.S. Army Research Laboratory.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * version 2.1 as published by the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this file; see the file named COPYING for more
18 * information.
19 */
20
21#ifndef BU_AVS_H
22#define BU_AVS_H
23
24#include "common.h"
25
26#include <stddef.h> /* for size_t */
27
28#if defined(USE_BINARY_ATTRIBUTES)
29# include "bson.h"
30#endif
31
32#include "bu/defines.h"
33#include "bu/magic.h"
34#include "bu/vls.h"
35
36__BEGIN_DECLS
37
38/*----------------------------------------------------------------------*/
39/** @addtogroup bu_avs
40 *
41 * @brief
42 * Routines to manage attribute/value sets.
43 */
44/** @{ */
45/** @file bu/avs.h */
46
47
48/** for attr and avs use.
49 */
50typedef enum {
54
55/**
56 * These strings may or may not be individually allocated, it depends
57 * on usage.
58 */
59/* FIXME: can this be made to include a union (or a struct pointer) to
60 * allow for a binary attr? if so, some (if not all) attr functions
61 * will need to be modified; maybe add an artificial const string
62 * value to indicate the binary attr which will probably never be
63 * allowed to be changed other than programmatically (don't list,
64 * i.e., keep them hidden? no, we will at least want to show a date
65 * and time for the time stamp) */
67 const char *name; /**< attribute name */
68 const char *value; /**< attribute value */
69#if defined(USE_BINARY_ATTRIBUTES)
70 /* trying a solution to include binary attributes */
71 unsigned int binvaluelen;
72 const unsigned char *binvalue;
73#endif
74};
75
76
77/**
78 * A variable-sized attribute-value-pair array.
79 *
80 * avp points to an array of [max] slots. The interface routines will
81 * realloc to extend as needed.
82 *
83 * In general, each of the names and values is a local copy made with
84 * bu_strdup(), and each string needs to be freed individually.
85 * However, if a name or value pointer is between readonly_min and
86 * readonly_max, then it is part of a big malloc block that is being
87 * freed by the caller, and should not be individually freed.
88 */
90 uint32_t magic;
91 size_t count; /**< # valid entries in avp */
92 size_t max; /**< # allocated slots in avp */
95 struct bu_attribute_value_pair *avp; /**< array[max] */
96};
98#define BU_AVS_NULL ((struct bu_attribute_value_set *)0)
99
100/**
101 * assert the integrity of a non-head node bu_attribute_value_set struct.
102 */
103#define BU_CK_AVS(_ap) BU_CKMAG(_ap, BU_AVS_MAGIC, "bu_attribute_value_set")
104
105/**
106 * initialize a bu_attribute_value_set struct without allocating any memory.
107 */
108#define BU_AVS_INIT(_ap) { \
109 (_ap)->magic = BU_AVS_MAGIC; \
110 (_ap)->count = (_ap)->max = 0; \
111 (_ap)->readonly_min = (_ap)->readonly_max = (_ap)->avp = NULL; \
112 }
113
114/**
115 * macro suitable for declaration statement initialization of a
116 * bu_attribute_value_set struct. does not allocate memory.
117 */
118#define BU_AVS_INIT_ZERO { BU_AVS_MAGIC, 0, 0, NULL, NULL, NULL }
119
120/**
121 * returns truthfully whether a bu_attribute_value_set has been initialized via
122 * BU_AVS_INIT() or BU_AVS_INIT_ZERO.
123 */
124#define BU_AVS_IS_INITIALIZED(_ap) (((struct bu_attribute_value_set *)(_ap) != BU_AVS_NULL) && LIKELY((_ap)->magic == BU_AVS_MAGIC))
125
126
127/**
128 * For loop iterator for avs structures.
129 *
130 * Provide an attribute value pair struct pointer and an attribute
131 * value set, and this will iterate over all entries. iteration order
132 * is not defined but should iterate over each AVS entry once.
133 *
134 * Example Use:
135 @code
136 void
137 print_avs(struct bu_attribute_value_set *avs) {
138 struct bu_attribute_value_pair *avpp;
139
140 for (BU_AVS_FOR(avpp, avs)) {
141 bu_log("key=%s, value=%s\n", avpp->name, avpp->value);
142 }
143 }
144 @endcode
145 *
146 */
147#define BU_AVS_FOR(_pp, _avp) \
148 (_pp) = ((const void *)(_avp) != (const void *)NULL) ? ((_avp)->count > 0 ? &(_avp)->avp[(_avp)->count-1] : NULL) : NULL; ((const void *)(_pp) != (const void *)NULL) && ((const void *)(_avp) != (const void *)NULL) && (_avp)->avp && (_pp) >= (_avp)->avp; (_pp)--
149
150/**
151 * Some (but not all) attribute name and value string pointers are
152 * taken from an on-disk format bu_external block, while others have
153 * been bu_strdup()ed and need to be freed. This macro indicates
154 * whether the pointer needs to be freed or not.
155 */
156#define AVS_IS_FREEABLE(_avsp, _p) \
157 ((_avsp)->readonly_max == NULL \
158 || (const void *)(_p) < (_avsp)->readonly_min \
159 || (const void *)(_p) > (_avsp)->readonly_max)
160
161
162/**
163 * Initialize avs with storage for len entries.
164 */
165BU_EXPORT extern void bu_avs_init(struct bu_attribute_value_set *avp,
166 size_t len,
167 const char *str);
168
169/**
170 * Initialize an empty avs.
171 */
172BU_EXPORT extern void bu_avs_init_empty(struct bu_attribute_value_set *avp);
173
174/**
175 * Allocate storage for a new attribute/value set, with at least 'len'
176 * slots pre-allocated.
177 */
178BU_EXPORT extern struct bu_attribute_value_set *bu_avs_new(size_t len,
179 const char *str);
180
181/**
182 * If the given attribute exists it will receive the new value,
183 * otherwise the set will be extended to have a new attribute/value
184 * pair.
185 *
186 * Returns -
187 * 0 some error occurred
188 * 1 existing attribute updated with new value
189 * 2 set extended with new attribute/value pair
190 */
191BU_EXPORT extern int bu_avs_add(struct bu_attribute_value_set *avp,
192 const char *attribute,
193 const char *value);
194
195/**
196 * Add a bu_vls string as an attribute to a given attribute set,
197 * updating the value if it already exists.
198 */
199BU_EXPORT extern int bu_avs_add_vls(struct bu_attribute_value_set *avp,
200 const char *attribute,
201 const struct bu_vls *value_vls);
202
203/**
204 * Add a name/value pair even if the name already exists in the set.
205 */
206BU_EXPORT extern void bu_avs_add_nonunique(struct bu_attribute_value_set *avsp,
207 const char *attribute,
208 const char *value);
209/**
210 * Take all the attributes from 'src' and merge them into 'dest' by
211 * replacing an attribute if it already exists in the set.
212 */
213BU_EXPORT extern void bu_avs_merge(struct bu_attribute_value_set *dest,
214 const struct bu_attribute_value_set *src);
215
216/**
217 * Get the value of a given attribute from an attribute set. The
218 * behavior is not currently well-defined for AVS containing
219 * non-unique attributes, but presently returns the first encountered.
220 * Returns NULL if the requested attribute is not present in the set.
221 */
222BU_EXPORT extern const char *bu_avs_get(const struct bu_attribute_value_set *avp,
223 const char *attribute);
224
225/**
226 * Remove all occurrences of an attribute from the provided attribute
227 * set.
228 *
229 * @return
230 * -1 attribute not found in set
231 * @return
232 * 0 OK
233 */
234BU_EXPORT extern int bu_avs_remove(struct bu_attribute_value_set *avp,
235 const char *attribute);
236
237/**
238 * Release all attributes in the provided attribute set.
239 */
240BU_EXPORT extern void bu_avs_free(struct bu_attribute_value_set *avp);
241
242/**
243 * Print all attributes in an attribute set in "name = value" form,
244 * using the provided title.
245 */
246BU_EXPORT extern void bu_avs_print(const struct bu_attribute_value_set *avp,
247 const char *title);
248
249/** @} */
250
251__END_DECLS
252
253#endif /* BU_AVS_H */
254
255/*
256 * Local Variables:
257 * mode: C
258 * tab-width: 8
259 * indent-tabs-mode: t
260 * c-file-style: "stroustrup"
261 * End:
262 * ex: shiftwidth=4 tabstop=8
263 */
Header file for the BRL-CAD common definitions.
void bu_avs_init(struct bu_attribute_value_set *avp, size_t len, const char *str)
int bu_avs_add_vls(struct bu_attribute_value_set *avp, const char *attribute, const struct bu_vls *value_vls)
struct bu_attribute_value_set * bu_avs_new(size_t len, const char *str)
const char * bu_avs_get(const struct bu_attribute_value_set *avp, const char *attribute)
bu_attr_time_t
Definition: avs.h:50
void bu_avs_add_nonunique(struct bu_attribute_value_set *avsp, const char *attribute, const char *value)
void bu_avs_init_empty(struct bu_attribute_value_set *avp)
void bu_avs_free(struct bu_attribute_value_set *avp)
int bu_avs_remove(struct bu_attribute_value_set *avp, const char *attribute)
void bu_avs_merge(struct bu_attribute_value_set *dest, const struct bu_attribute_value_set *src)
void bu_avs_print(const struct bu_attribute_value_set *avp, const char *title)
int bu_avs_add(struct bu_attribute_value_set *avp, const char *attribute, const char *value)
@ BU_ATTR_CREATED
Definition: avs.h:51
@ BU_ATTR_MODIFIED
Definition: avs.h:52
Global registry of recognized magic numbers.
const char * value
Definition: avs.h:68
const char * name
Definition: avs.h:67
uint32_t magic
Definition: avs.h:90
void * readonly_max
Definition: avs.h:94
void * readonly_min
Definition: avs.h:93
struct bu_attribute_value_pair * avp
Definition: avs.h:95
Definition: vls.h:53