Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_object_impl_property_meta.c
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Object Implementation Helpers
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 /*
26  * This implementation is a helper to support:
27  * impl_afw_object_get_meta,
28  * impl_afw_object_get_property_meta, and
29  * impl_afw_object_get_next_property_meta.
30  *
31  * See afw_object_impl_internal_get_meta,
32  * afw_object_impl_internal_get_property_meta, and
33  * impl_afw_object_get_next_property_meta.
34  *
35  * The implementation accesses the meta of an object instead of
36  * the just the property values.
37  */
38 /* Declares and rti/inf defines for interface afw_object */
39 #define AFW_IMPLEMENTATION_ID "object_impl_property_meta"
42 
43 
44 
45 static const afw_value_t *
46 impl_get_dataType(
48  const afw_utf8_t *property_name,
49  afw_xctx_t *xctx)
50 {
51  const afw_data_type_t *data_type;
52  const afw_value_t *result;
53 
54  result = NULL;
55 
56  data_type = afw_value_get_data_type(self->property_value, xctx);
57  if (data_type) {
58  result = afw_value_create_string(
59  &data_type->data_type_id, self->pub.p, xctx);
60  }
61 
62  return result;
63 }
64 
65 
66 static void
67 impl_set_dataType(
69  const afw_utf8_t *property_name,
70  const afw_value_t *value,
71  afw_xctx_t *xctx)
72 {
73  AFW_THROW_ERROR_Z(general, "Set dataType not implemented.", xctx);
74 }
75 
76 
77 static const afw_value_t *
78 impl_get_key(
80  const afw_utf8_t *property_name,
81  afw_xctx_t *xctx)
82 {
83  const afw_value_t *result;
84 
85  result = NULL;
86 
87  if (self->property_name) {
88  result = afw_value_create_string(
89  self->property_name, self->pub.p, xctx);
90  }
91 
92  return result;
93 }
94 
95 
96 static const afw_value_t *
97 impl_get_value(
99  const afw_utf8_t *property_name,
100  afw_xctx_t *xctx)
101 {
102  return self->property_value;
103 }
104 
105 
106 static void
107 impl_set_value(
109  const afw_utf8_t *property_name,
110  const afw_value_t *value,
111  afw_xctx_t *xctx)
112 {
113  afw_object_set_property(self->owning_object,
114  self->property_name, value, xctx);
115 }
116 
117 
118 static const afw_value_t *
119 impl_get_valueInfId(
121  const afw_utf8_t *property_name,
122  afw_xctx_t *xctx)
123 {
124  const afw_value_t *result;
125 
126  result = afw_value_create_string(
127  &self->property_value->inf->rti.implementation_id,
128  self->pub.p, xctx);
129 
130  return result;
131 }
132 
133 
134 
135 static void
136 impl_set_error_immutable(
138  const afw_utf8_t *property_name,
139  const afw_value_t *value,
140  afw_xctx_t *xctx)
141 {
142  AFW_THROW_ERROR_FZ(general, xctx,
143  "Property %" AFW_UTF8_FMT " immutable",
144  AFW_UTF8_FMT_ARG(property_name));
145 }
146 
147 
148 
149 static const afw_object_impl_name_handler_t impl_handler[] =
150 {
151  { &afw_s_dataType, impl_get_dataType, impl_set_dataType },
152  { &afw_s_key, impl_get_key, impl_set_error_immutable },
153  { &afw_s_value, impl_get_value, impl_set_value },
154  { &afw_s_valueInfId, impl_get_valueInfId, impl_set_error_immutable }
155 };
156 
157 static const afw_object_impl_name_handler_t *impl_handler_end =
159 (((char *)& impl_handler[0]) + sizeof(impl_handler));
160 
161 
162 
163 /*
164  * Implementation of method release for interface afw_object.
165  */
166 void
168  const afw_object_t *instance,
169  afw_xctx_t *xctx)
170 {
172  AFW_THROW_ERROR_Z(general, "Method not implemented.", xctx);
173 
174 }
175 
176 
177 
178 /*
179  * Implementation of method add_reference for interface afw_object.
180  */
181 void
182 impl_afw_object_add_reference(
183  const afw_object_t *instance,
184  afw_xctx_t *xctx)
185 {
186  /* Nothing to do? */
187 }
188 
189 /*
190  * Implementation of method get_count for interface afw_object.
191  */
194  const afw_object_t * instance,
195  afw_xctx_t * xctx)
196 {
197 // <afwdev {prefixed_interface_name}>_self_t *self =
198 // (<afwdev {prefixed_interface_name}>_self_t *)instance;
199 
201  AFW_THROW_ERROR_Z(general, "Method not implemented.", xctx);
202 
203 }
204 
205 /*
206  * Implementation of method get_property for interface afw_object.
207  */
208 const afw_value_t *
209 impl_afw_object_get_property(
210  const afw_object_t *instance,
211  const afw_utf8_t *property_name,
212  afw_xctx_t *xctx)
213 {
217 
218  /* If get callback for this property, return it's result. */
219  for (h = &impl_handler[0]; h < impl_handler_end; h++) {
220  if (afw_utf8_equal(h->property_name, property_name)) {
221  if (h->get) {
222  return h->get(self, property_name, xctx);
223  }
224  break;
225  }
226  }
227 
228  /* If property_type_object, get property from it. */
229  if (self->property_type_object) {
231  self->property_type_object,
232  property_name, xctx);
233  }
234 
235  /* Return NULL if not found. */
236  return NULL;
237 }
238 
239 
240 
241 /*
242  * Implementation of method get_next_property for interface afw_object.
243  */
244 const afw_value_t *
245 impl_afw_object_get_next_property(
246  const afw_object_t *instance,
247  const afw_iterator_t **iterator,
248  const afw_utf8_t **property_name,
249  afw_xctx_t *xctx)
250 {
254  const afw_value_t *result;
255  const afw_utf8_t *next_property_name;
256 
257  /*
258  * If this is the first time (*iterator is NULL), set iterator to first
259  * impl_handler[] entry.
260  */
261  if (!*iterator) {
262  *iterator = (const afw_iterator_t *)&impl_handler[0];
263  }
264 
265  /*
266  * If *iterator is within bounds for impl_handler array, *iterator points
267  * to the next impl_handler array entry to process. Loop calling the
268  * callback of each entry from this point until a callback returns a
269  * non-NULL result or the end of the array is encountered. Set *iterator
270  * to the next entry to process or the end of the array.
271  *
272  * If a callback returns a non-NULL result, return from this function
273  * with that result.
274  */
275  if (*(void **)iterator >= (void *)&impl_handler[0])
276  {
277  h = (const afw_object_impl_name_handler_t *)*iterator;
278  for (; h < impl_handler_end; h++)
279  {
280  result = h->get(self, h->property_name, xctx);
281  *iterator = (const afw_iterator_t *)(h + 1);
282  if (result) {
283  if (property_name) {
284  *property_name = h->property_name;
285  }
286  return result;
287  }
288  }
289  }
290 
291  /*
292  * If there is an additional object that contains properties to return,
293  * return the result of calling its get_next_property() if it's not for
294  * a property name in impl_handler array. If the previous iterator points
295  * to the end of impl_handler indicating that the impl_handler array has
296  * just been completely processed, set the iterator to NULL before calling
297  * get_next_property().
298  */
299  if (self->property_type_object) {
300  if ((const afw_object_impl_name_handler_t *)*iterator == impl_handler_end)
301  {
302  *iterator = NULL;
303  }
304  for (;;) {
305  result = afw_object_get_next_property(self->property_type_object,
306  iterator, &next_property_name, xctx);
307  if (!result) {
308  break;
309  }
310  for (h = &impl_handler[0];
311  h < impl_handler_end &&
312  !afw_utf8_equal(h->property_name, next_property_name);
313  h++);
314  if (h >= impl_handler_end) {
315  if (property_name) {
316  *property_name = next_property_name;
317  }
318  return result;
319  }
320  }
321  }
322 
323  /* At this point there are no more properties to return. */
324  *iterator = NULL;
325  if (property_name) {
326  *property_name = NULL;
327  }
328  return NULL;
329 }
330 
331 
332 
333 /*
334  * Implementation of method has_property for interface afw_object.
335  */
337 impl_afw_object_has_property(
338  const afw_object_t *instance,
339  const afw_utf8_t *property_name,
340  afw_xctx_t *xctx)
341 {
342  return impl_afw_object_get_property(instance, property_name, xctx) != NULL;
343 }
344 
345 
346 
347 /*
348  * Implementation of method get_setter for interface afw_object.
349  */
350 const afw_object_setter_t *
351 impl_afw_object_get_setter(
352  const afw_object_t *instance,
353  afw_xctx_t *xctx)
354 {
357 
358  return (!self->is_immutable &&
359  afw_object_get_setter(self->owning_object, xctx))
360  ? &self->setter
361  : NULL;
362 }
363 
364 
365 
366 /*
367  * Implementation of method set_immutable for interface afw_object_setter.
368  */
369 void
371  const afw_object_setter_t *instance,
372  afw_xctx_t *xctx)
373 {
376 
377  self->is_immutable = true;
378 }
379 
380 
381 
382 /*
383  * Implementation of method set_property for interface afw_object_setter.
384  */
385 void
387  const afw_object_setter_t *instance,
388  const afw_utf8_t *property_name,
389  const afw_value_t *value,
390  afw_xctx_t *xctx)
391 {
395 
396  for (h = &impl_handler[0]; h < impl_handler_end; h++) {
397  if (afw_utf8_equal(h->property_name, property_name)) {
398  if (h->set) {
399  h->set(self, property_name, value, xctx);
400  return;
401  }
402  break;
403  }
404  }
405 
407  ((const afw_value_object_t *)&self->meta_object_value)->internal,
408  self->property_name,
409  property_name, value, xctx);
410 }
411 
412 
413 
414 /*
415  * A general impl of method get_property_meta for interface afw_object
416  * that can be accessed externally.
417  */
418 AFW_DECLARE(const afw_value_t *)
420  const afw_object_t *instance,
421  const afw_utf8_t *property_name,
422  const afw_pool_t *p,
423  afw_xctx_t *xctx)
424 {
426  instance, property_name, p, xctx);
427 }
428 
429 
430 
431 /*
432  * A general impl of method get_next_property_meta for interface
433  * afw_object that can be accessed externally.
434  */
435 AFW_DECLARE(const afw_value_t *)
437  const afw_object_t *instance,
438  const afw_iterator_t **iterator,
439  const afw_utf8_t **property_name,
440  const afw_pool_t *p,
441  afw_xctx_t *xctx)
442 {
444  instance, iterator, property_name, p, xctx);
445 }
446 
447 
448 
449 /*
450  * Implementation of method get_property_meta for interface afw_object.
451  */
454  const afw_object_t *instance,
455  const afw_utf8_t *property_name,
456  const afw_pool_t *p,
457  afw_xctx_t *xctx)
458 {
460  const afw_value_t *property_value;
461 
462  property_value = afw_object_get_property(instance,
463  property_name, xctx);
464  if (!property_value) {
465  /* Possibly have a future option to get meta with no value??? */
466  return NULL;
467  }
468 
470  self->pub.inf = &impl_afw_object_inf;
471  self->pub.p = p;
472  self->owning_object = instance;
473  self->setter.inf = &impl_afw_object_setter_inf;
474  self->setter.object = (const afw_object_t *)self;
475  self->meta_object_value.inf = &afw_value_evaluated_object_inf;
476  self->meta_object_value.internal = (const afw_object_t *)self;
477  self->property_value = property_value;
478  self->property_value = afw_value_evaluate(property_value, p, xctx);
479  self->property_name = property_name;
480  self->property_type_object =
481  afw_object_meta_get_property_type(instance, property_name, xctx);
482 
483  return (const afw_value_t *)& self->meta_object_value;
484 }
485 
486 
487 
488 /*
489  * Implementation of method get_next_property_meta for interface afw_object.
490  */
493  const afw_object_t *instance,
494  const afw_iterator_t **iterator,
495  const afw_utf8_t **property_name,
496  const afw_pool_t *p,
497  afw_xctx_t *xctx)
498 {
499  const afw_value_t *property_value;
500  const afw_value_t *result;
501  const afw_utf8_t *next_property_name;
502 
503  result = NULL;
504  property_value = afw_object_get_next_property(instance,
505  iterator, &next_property_name, xctx);
506 
507  if (property_value) {
508  if (property_name) {
509  *property_name = next_property_name;
510  }
511  result = afw_object_get_property_meta(instance,
512  next_property_name, p, xctx);
513  }
514 
515  return result;
516 }
#define AFW_DEFINE_INTERNAL(type)
Define an internal function for /src/afw/ source*.c files.
#define AFW_DECLARE(type)
Declare a public afw function.
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
Interface afw_interface implementation declares.
afw_value_evaluated_object_inf
Unmanaged evaluated value inf for data type object.
afw_value_create_string(const afw_utf8_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type string value.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
struct afw_iterator_s afw_iterator_t
_Bool afw_boolean_t
Definition: afw_common.h:373
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:319
#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)
afw_size_t impl_afw_object_get_count(const afw_object_t *instance, afw_xctx_t *xctx)
const afw_value_t * afw_object_impl_get_property_meta(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_pool_t *p, afw_xctx_t *xctx)
A general impl of method get_property_meta for interface afw_object that can be accessed externally.
afw_object_impl_internal_get_property_meta(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_pool_t *p, afw_xctx_t *xctx)
A general impl of method get_property_meta for interface afw_object.
const afw_value_t * afw_object_impl_get_next_property_meta(const afw_object_t *instance, const afw_iterator_t **iterator, const afw_utf8_t **property_name, const afw_pool_t *p, afw_xctx_t *xctx)
A general impl of method get_next_property_meta for interface afw_object that can be accessed externa...
afw_object_impl_internal_get_next_property_meta(const afw_object_t *instance, const afw_iterator_t **iterator, const afw_utf8_t **property_name, const afw_pool_t *p, afw_xctx_t *xctx)
A general impl of method get_next_property_meta for interface afw_object.
#define afw_object_get_property(instance, property_name, xctx)
Call method get_property of interface afw_object.
#define afw_object_get_property_meta(instance, property_name, p, xctx)
Call method get_property_meta of interface afw_object.
#define afw_object_get_next_property(instance, iterator, property_name, xctx)
Call method get_next_property of interface afw_object.
#define afw_object_get_setter(instance, xctx)
Call method get_setter of interface afw_object.
afw_object_meta_get_property_type(const afw_object_t *instance, const afw_utf8_t *property_name, afw_xctx_t *xctx)
Get the property type object for an object's property from the meta of an object, creating it if need...
#define afw_object_meta_set_property_type_property(instance, property_name, property_type_property_name, value, xctx)
Set a property type property for a property in the meta of an object.
impl_afw_object_setter_set_immutable(const afw_object_setter_t *instance, afw_xctx_t *xctx)
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)
afw_object_set_property(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_value_t *value, afw_xctx_t *xctx)
Set the value of an object's property.
Definition: afw_object.c:46
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
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.
#define afw_value_get_data_type(instance, xctx)
Call method get_data_type of interface afw_value.
#define afw_value_evaluate(value, p, xctx)
Evaluate value if needed using specific pool.
Definition: afw_value.h:841
Interface afw_data_type public struct.
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
struct for data type object values.
Interface afw_value public struct.
Interface afw_xctx public struct.