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