BRL-CAD
avs.h
Go to the documentation of this file.
1 /* A V S . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2024 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  */
50 typedef 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 */
93  void *readonly_min;
94  void *readonly_max;
95  struct bu_attribute_value_pair *avp; /**< array[max] */
96 };
97 typedef struct bu_attribute_value_set bu_avs_t;
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  */
165 BU_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  */
172 BU_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  */
178 BU_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  */
191 BU_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  */
199 BU_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  */
206 BU_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  */
213 BU_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  */
222 BU_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  */
234 BU_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  */
240 BU_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  */
246 BU_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)
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)
struct bu_attribute_value_set * bu_avs_new(size_t len, const char *str)
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:69
const char * name
Definition: avs.h:68
uint32_t magic
Definition: avs.h:91
void * readonly_max
Definition: avs.h:95
void * readonly_min
Definition: avs.h:94
struct bu_attribute_value_pair * avp
Definition: avs.h:96
Definition: vls.h:53