Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_object_memory.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Implementation of afw_object interface
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 #define impl_afw_object_get_meta \
17  afw_object_impl_internal_get_meta
18 
19 #define impl_afw_object_get_property_meta \
20  afw_object_impl_internal_get_property_meta
21 
22 #define impl_afw_object_get_next_property_meta \
23  afw_object_impl_internal_get_next_property_meta
24 
25 /* Declares and rti/inf defines for interface afw_object */
26 #define AFW_IMPLEMENTATION_ID "memory"
29 
30 
31 AFW_DEFINE(const afw_object_t *)
33  int options, const afw_pool_t *p, afw_xctx_t *xctx)
34 {
36 
37  /* If neither unmanaged or cede_p, create subpool for object. */
38  if (options &
40  {
41  p = afw_pool_create(p, xctx);
42  }
43 
44  /* Allocate memory for self and initialize. */
46  self->pub.inf = &impl_afw_object_inf;
47  self->pub.p = p;
48  self->unmanaged = AFW_OBJECT_MEMORY_OPTION_IS(options, unmanaged);
49  self->clone_on_set = AFW_OBJECT_MEMORY_OPTION_IS(options, clone_on_set);
50  self->reference_count = (self->unmanaged) ? 0 : 1;
51  self->setter.inf = &impl_afw_object_setter_inf;
52  self->setter.object = (const afw_object_t *)self;
53 
54  /* Return new object. */
55  return (const afw_object_t *)self;
56 }
57 
58 
59 AFW_DEFINE(const afw_object_t *)
61  const afw_object_t *embedding_object,
62  const afw_utf8_t *property_name,
63  afw_xctx_t *xctx)
64 {
65  const afw_pool_t *p;
68 
69  /* Embedding object must be this implementation. */
70  if (embedding_object->inf != &impl_afw_object_inf) {
71  AFW_THROW_ERROR_Z(general,
72  "Embedding object is not afw_memory object", xctx);
73  }
74  embedder = (afw_object_internal_memory_object_t *)embedding_object;
75 
76  /* Use pool of embedder. */
77  p = embedder->pub.p;
78 
79  /* Allocate memory for self and initialize. */
81  self->pub.inf = &impl_afw_object_inf;
82  self->pub.p = p;
83  self->pub.meta.embedding_object = embedding_object;
84  self->pub.meta.id = property_name;
85  self->managed_by_entity = true;
86  self->reference_count = 1;
87  self->setter.inf = &impl_afw_object_setter_inf;
88  self->setter.object = (const afw_object_t *)self;
89  self->clone_on_set = embedder->clone_on_set;
90 
91  /* Set embedded object as property of embedding object. */
93  embedding_object, property_name, (const afw_object_t *)self, xctx);
94 
95  /* Return new object. */
96  return (const afw_object_t *)self;
97 }
98 
99 
100 
101 /* Insure embedded object exists creating if necessary. */
102 AFW_DEFINE(const afw_object_t *)
104  const afw_object_t *embedding_object,
105  const afw_utf8_t *property_name,
106  afw_xctx_t *xctx)
107 {
108  const afw_object_t *result;
109 
110  result = afw_object_old_get_property_as_object(embedding_object,
111  property_name, xctx);
112 
113  if (!result) {
114  result = afw_object_create_embedded(embedding_object,
115  property_name, xctx);
116  }
117 
118  return result;
119 }
120 
121 
122 
123 /*
124  * Implementation of method release of interface afw_object.
125  */
126 void
128  const afw_object_t * instance,
129  afw_xctx_t *xctx)
130 {
133  const afw_object_t *entity;
134 
135  /* If unmanaged, just return. */
136  if (self->unmanaged) return;
137 
138  /*
139  * If embedded object managed by parent, call parent's release and
140  * return.
141  */
142  if (self->managed_by_entity) {
143  AFW_OBJECT_GET_ENTITY(entity, instance);
144  afw_object_release(entity, xctx);
145  return;
146  }
147 
148  /*
149  * If managing self, decrement reference count. If count is zero, release
150  * pool.
151  */
152  if (afw_atomic_integer_decrement(&self->reference_count) == 0) {
153  afw_pool_release(instance->p, xctx);
154  }
155 }
156 
157 
158 /*
159  * Implementation of method add_reference of interface afw_object.
160  */
161 void
162 impl_afw_object_add_reference(
163  const afw_object_t * instance,
164  afw_xctx_t *xctx)
165 {
168  const afw_object_t *entity;
169 
170  /* If unmanaged, just return. */
171  if (self->unmanaged) return;
172 
173  /*
174  * If embedded object managed by parent, call parent's add_reference
175  * and return.
176  */
177  if (self->managed_by_entity) {
178  AFW_OBJECT_GET_ENTITY(entity, instance);
179  afw_object_add_reference(entity, xctx);
180  return;
181  }
182 
183  /* If managing self, increment reference count. */
184  afw_atomic_integer_increment(&self->reference_count);
185 }
186 
187 /*
188  * Implementation of method get_count for interface afw_object.
189  */
192  const afw_object_t * instance,
193  afw_xctx_t * xctx)
194 {
195 // <afwdev {prefixed_interface_name}>_self_t *self =
196 // (<afwdev {prefixed_interface_name}>_self_t *)instance;
197 
199  AFW_THROW_ERROR_Z(general, "Method not implemented.", xctx);
200 
201 }
202 
203 
204 /*
205  * Implementation of method get_property of interface afw_object.
206  */
207 const afw_value_t *
209  const afw_object_t * instance,
210  const afw_utf8_t * property_name,
211  afw_xctx_t *xctx)
212 {
217  const afw_value_t *value;
219 
220  value = NULL;
221 
222  /* Search property list. */
223  for (value = NULL, e = self->first_property; e; e = e->next) {
224  if (afw_utf8_equal(e->name, property_name)) {
225  value = e->value;
226  break;
227  }
228  }
229 
230  /* Return value. */
231  return value;
232 }
233 
234 
235 
236 /*
237  * Implementation of method get_next_property of interface afw_object.
238  */
239 const afw_value_t *
240 impl_afw_object_get_next_property(
241  const afw_object_t * instance,
242  const afw_iterator_t * * iterator,
243  const afw_utf8_t * * property_name,
244  afw_xctx_t *xctx)
245 {
249 
250  /* If iterator is NULL, get first. */
251  if (!*iterator) {
252  e = self->first_property;
253  }
254 
255  /* If iterator is not NULL, get next. */
256  else {
258  e = e->next;
259  }
260 
261  /* Skip any deleted properties. */
262  for (; e && !e->value; e = e->next);
263 
264  /* Set iterator to entry. */
265  *iterator = (afw_iterator_t *)e;
266 
267  /* If e NULL, return not found. */
268  if (!e)
269  {
270  if (property_name) {
271  *property_name = NULL;
272  }
273  return NULL;
274  }
275 
276  /* Return entries property name and value. */
277  if (property_name) {
278  *property_name = e->name;
279  }
280  return e->value;
281 }
282 
283 
284 
285 /*
286  * Implementation of method has_property of interface afw_object.
287  */
289 impl_afw_object_has_property(
290  const afw_object_t * instance,
291  const afw_utf8_t * property_name,
292  afw_xctx_t *xctx)
293 {
294  const afw_value_t *value;
295 
296  /* Search for property. If found, set exists to true. */
297  value = impl_afw_object_get_property(instance, property_name, xctx);
298 
299  /* Return true or false. */
300  return (value) ? AFW_TRUE : AFW_FALSE;
301 }
302 
303 
304 
305 /*
306  * Implementation of method get_setter of interface afw_object.
307  */
308 const afw_object_setter_t *
309 impl_afw_object_get_setter (
310  const afw_object_t * instance,
311  afw_xctx_t *xctx)
312 {
313  /* Assign instance pointer to self. */
316 
317  return (self->immutable) ? NULL : &self->setter;
318 }
319 
320 
321 
322 /*
323  * Implementation of method set_immutable of interface afw_object_setter.
324  */
325 void
327  const afw_object_setter_t * instance,
328  afw_xctx_t *xctx)
329 {
330  /* Set self to object associated with setter. */
332  (afw_object_internal_memory_object_t *)instance->object;
333 
334  /* Set object to immutable. */
335  self->immutable = true;
336 }
337 
338 
339 /*
340  * Implementation of method set_property of interface afw_object_setter.
341  */
342 void
344  const afw_object_setter_t * instance,
345  const afw_utf8_t * property_name,
346  const afw_value_t * value,
347  afw_xctx_t *xctx)
348 {
349  /* Set self to object associated with setter. */
351  (afw_object_internal_memory_object_t *)instance->object;
354 
355  AFW_OBJECT_IMPL_ASSERT_SELF_MUTABLE;
356 
357  for (e = self->first_property,final_e = NULL; e; e = e->next) {
358  final_e = e;
359  if (afw_utf8_equal(e->name, property_name)) {
360  e->value = value;
361  return;
362  }
363  }
364  if (!value) return; /* Delete property just return. */
365  e = afw_pool_calloc_type(instance->object->p,
367  e->name = (property_name) ? property_name : &afw_s_a_empty_string;
368 
378  e->value = (self->clone_on_set)
379  ? afw_value_clone(value, self->pub.p, xctx)
380  : value;
381  if (final_e) {
382  final_e->next = e;
383  }
384  else {
385  self->first_property = e;
386  }
387 }
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
Interface afw_interface implementation declares.
afw_integer_t afw_atomic_integer_decrement(AFW_ATOMIC afw_integer_t *mem)
Integer atomic decrement.
Definition: afw_atomic.h:96
afw_integer_t afw_atomic_integer_increment(AFW_ATOMIC afw_integer_t *mem)
Integer atomic increment.
Definition: afw_atomic.h:127
afw_object_set_property_as_object(const afw_object_t *object, const afw_utf8_t *property_name, const afw_object_t *internal, afw_xctx_t *xctx)
Set property function for data type object values.
#define afw_object_old_get_property_as_object(object, property_name, xctx)
Get property function for data type object value.
#define AFW_FALSE
Definition: afw_common.h:392
struct afw_iterator_s afw_iterator_t
#define AFW_TRUE
Definition: afw_common.h:383
_Bool afw_boolean_t
Definition: afw_common.h:373
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
void impl_afw_object_release(const afw_object_t *instance, afw_xctx_t *xctx)
const afw_value_t * impl_afw_object_get_property(const afw_object_t *instance, const afw_utf8_t *property_name, afw_xctx_t *xctx)
afw_size_t impl_afw_object_get_count(const afw_object_t *instance, afw_xctx_t *xctx)
#define afw_object_add_reference(instance, xctx)
Call method add_reference of interface afw_object.
#define afw_object_release(instance, xctx)
Call method release of interface afw_object.
impl_afw_object_setter_set_immutable(const afw_object_setter_t *instance, afw_xctx_t *xctx)
void impl_afw_object_setter_set_property(const afw_object_setter_t *instance, const afw_utf8_t *property_name, const afw_value_t *value, afw_xctx_t *xctx)
#define AFW_OBJECT_MEMORY_OPTION_unmanaged
Object should be unmanaged.
Definition: afw_object.h:733
#define AFW_OBJECT_GET_ENTITY(entity, object)
Macro to get entity for object.
Definition: afw_object.h:406
afw_object_insure_embedded_exists(const afw_object_t *embedding_object, const afw_utf8_t *property_name, afw_xctx_t *xctx)
Insure embedded object exists creating if necessary.
afw_object_create_with_options(int options, const afw_pool_t *p, afw_xctx_t *xctx)
Create an empty entity object with options.
#define AFW_OBJECT_MEMORY_OPTION_IS(options_mask, option)
Test memory object option mask option.
Definition: afw_object.h:769
#define AFW_OBJECT_MEMORY_OPTION_cede_p
Object cedes control of the specified pool.
Definition: afw_object.h:743
afw_object_create_embedded(const afw_object_t *embedding_object, const afw_utf8_t *property_name, afw_xctx_t *xctx)
Create an empty embedded object in a memory object.
#define afw_pool_release(instance, xctx)
Call method release of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
afw_boolean_t afw_utf8_equal(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string equals another string.
afw_value_clone(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Clone a value to specified pool.
Definition: afw_value.c:282
Struct for name/value list entry.
Interface afw_object public struct.
Interface afw_object_setter public struct.
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Interface afw_value public struct.
Interface afw_xctx public struct.