1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
9 * @brief Functions to manipulate named and typed elements of
12 * These functions represent a low-level API for accessing a member of a
13 * structure. They use typedvar.c to work, and they are used in turn by the
14 * configuration system to examine and set fields in configuration objects
15 * used by individual modules.
17 * Almost no code should call these directly.
21 #include "lib/confmgt/structvar.h"
22 #include "lib/cc/compat_compiler.h"
23 #include "lib/conf/conftypes.h"
24 #include "lib/confmgt/type_defs.h"
25 #include "lib/confmgt/typedvar.h"
26 #include "lib/log/util_bug.h"
28 #include "lib/confmgt/var_type_def_st.h"
33 * Return true iff all fields on <b>decl</b> are NULL or 0, indicating that
34 * there is no object or no magic number to check.
37 magic_is_null(const struct_magic_decl_t
*decl
)
39 return decl
->typename
== NULL
&&
40 decl
->magic_offset
== 0 &&
45 * Set the 'magic number' on <b>object</b> to correspond to decl.
48 struct_set_magic(void *object
, const struct_magic_decl_t
*decl
)
51 if (magic_is_null(decl
))
55 uint32_t *ptr
= STRUCT_VAR_P(object
, decl
->magic_offset
);
56 *ptr
= decl
->magic_val
;
60 * Assert that the 'magic number' on <b>object</b> to corresponds to decl.
63 struct_check_magic(const void *object
, const struct_magic_decl_t
*decl
)
66 if (magic_is_null(decl
))
71 const uint32_t *ptr
= STRUCT_VAR_P(object
, decl
->magic_offset
);
72 tor_assertf(*ptr
== decl
->magic_val
,
73 "Bad magic number on purported %s object. "
74 "Expected %"PRIu32
"x but got %"PRIu32
"x.",
75 decl
->typename
, decl
->magic_val
, *ptr
);
79 * Return a mutable pointer to the member of <b>object</b> described
83 struct_get_mptr(void *object
, const struct_member_t
*member
)
86 return STRUCT_VAR_P(object
, member
->offset
);
90 * Return a const pointer to the member of <b>object</b> described
94 struct_get_ptr(const void *object
, const struct_member_t
*member
)
97 return STRUCT_VAR_P(object
, member
->offset
);
101 * Helper: given a struct_member_t, look up the type definition for its
104 static const var_type_def_t
*
105 get_type_def(const struct_member_t
*member
)
107 if (member
->type_def
)
108 return member
->type_def
;
110 return lookup_type_def(member
->type
);
114 * (As typed_var_free, but free and clear the member of <b>object</b> defined
118 struct_var_free(void *object
, const struct_member_t
*member
)
120 void *p
= struct_get_mptr(object
, member
);
121 const var_type_def_t
*def
= get_type_def(member
);
123 typed_var_free(p
, def
);
127 * (As typed_var_copy, but copy from <b>src</b> to <b>dest</b> the member
128 * defined by <b>member</b>.)
131 struct_var_copy(void *dest
, const void *src
, const struct_member_t
*member
)
133 void *p_dest
= struct_get_mptr(dest
, member
);
134 const void *p_src
= struct_get_ptr(src
, member
);
135 const var_type_def_t
*def
= get_type_def(member
);
137 return typed_var_copy(p_dest
, p_src
, def
);
141 * (As typed_var_eq, but compare the members of <b>a</b> and <b>b</b>
142 * defined by <b>member</b>.)
145 struct_var_eq(const void *a
, const void *b
, const struct_member_t
*member
)
147 const void *p_a
= struct_get_ptr(a
, member
);
148 const void *p_b
= struct_get_ptr(b
, member
);
149 const var_type_def_t
*def
= get_type_def(member
);
151 return typed_var_eq(p_a
, p_b
, def
);
155 * (As typed_var_ok, but validate the member of <b>object</b> defined by
159 struct_var_ok(const void *object
, const struct_member_t
*member
)
161 const void *p
= struct_get_ptr(object
, member
);
162 const var_type_def_t
*def
= get_type_def(member
);
164 return typed_var_ok(p
, def
);
168 * (As typed_var_kvassign, but assign a value to the member of <b>object</b>
169 * defined by <b>member</b>.)
172 struct_var_kvassign(void *object
, const struct config_line_t
*line
,
174 const struct_member_t
*member
)
176 void *p
= struct_get_mptr(object
, member
);
177 const var_type_def_t
*def
= get_type_def(member
);
179 return typed_var_kvassign(p
, line
, errmsg
, def
);
183 * (As typed_var_kvencode, but encode the value of the member of <b>object</b>
184 * defined by <b>member</b>.)
186 struct config_line_t
*
187 struct_var_kvencode(const void *object
, const struct_member_t
*member
)
189 const void *p
= struct_get_ptr(object
, member
);
190 const var_type_def_t
*def
= get_type_def(member
);
192 return typed_var_kvencode(member
->name
, p
, def
);
196 * Mark the field in <b>object</b> determined by <b>member</b> -- a variable
197 * that ordinarily would be extended by assignment -- as "fragile", so that it
198 * will get replaced by the next assignment instead.
201 struct_var_mark_fragile(void *object
, const struct_member_t
*member
)
203 void *p
= struct_get_mptr(object
, member
);
204 const var_type_def_t
*def
= get_type_def(member
);
205 return typed_var_mark_fragile(p
, def
);
209 * Return the official name of this struct member.
212 struct_var_get_name(const struct_member_t
*member
)
218 * Return the type name for this struct member.
220 * Do not use the output of this function to inspect a type within Tor. It is
221 * suitable for debugging, informing the controller or user of a variable's
225 struct_var_get_typename(const struct_member_t
*member
)
227 const var_type_def_t
*def
= get_type_def(member
);
229 return def
? def
->name
: NULL
;
232 /** Return all of the flags set for this struct member. */
234 struct_var_get_flags(const struct_member_t
*member
)
236 const var_type_def_t
*def
= get_type_def(member
);
238 return def
? def
->flags
: 0;