Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_value_meta.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Object Implementation for an Adaptive Value's Meta
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 
17 #define impl_afw_object_get_meta \
18  afw_object_impl_internal_get_meta
19 
20 #define impl_afw_object_get_property_meta \
21  afw_object_impl_internal_get_property_meta
22 
23 #define impl_afw_object_get_next_property_meta \
24  afw_object_impl_internal_get_next_property_meta
25 
26 
27 /* Declares and rti/inf defines for interface afw_object */
28 #define AFW_IMPLEMENTATION_ID "value_meta"
31 
32 static const afw_value_t *
33 impl_get_dataType(
35  const afw_utf8_t *property_name,
36  afw_xctx_t *xctx)
37 {
38  const afw_data_type_t *data_type;
39  const afw_value_t *result;
40 
41  result = NULL;
42 
43  data_type = afw_value_get_data_type(self->evaluated_value, xctx);
44  if (data_type) {
45  result = afw_value_create_string(
46  &data_type->data_type_id, self->pub.p, xctx);
47  }
48 
49  return result;
50 }
51 
52 
53 static const afw_value_t *
54 impl_get_key(
56  const afw_utf8_t *property_name,
57  afw_xctx_t *xctx)
58 {
59  const afw_value_t *result;
60 
61  result = NULL;
62 
63  if (self->key) {
64  result = afw_value_create_string(
65  self->key, self->pub.p, xctx);
66  }
67 
68  return result;
69 }
70 
71 
72 static const afw_value_t *
73 impl_get_value(
75  const afw_utf8_t *property_name,
76  afw_xctx_t *xctx)
77 {
78  return self->evaluated_value;
79 }
80 
81 
82 static const afw_value_t *
83 impl_get_valueInfId(
85  const afw_utf8_t *property_name,
86  afw_xctx_t *xctx)
87 {
88  const afw_value_t *result;
89 
90  result = afw_value_create_string(
91  &self->value->inf->rti.implementation_id,
92  self->pub.p, xctx);
93 
94  return result;
95 }
96 
97 
99 impl_handler[] =
100 {
101  { &afw_s_dataType, impl_get_dataType, NULL },
102  { &afw_s_key, impl_get_key, NULL },
103  { &afw_s_value, impl_get_value, NULL },
104  { &afw_s_valueInfId, impl_get_valueInfId, NULL }
105 };
106 
107 static const afw_value_meta_name_handler_t *impl_handler_end =
109  ((char *)&impl_handler[0] + sizeof(impl_handler));
110 
111 
112 
113 /*
114  * Implementation of method release for interface afw_object.
115  */
116 void
118  const afw_object_t *instance,
119  afw_xctx_t *xctx)
120 {
122  AFW_THROW_ERROR_Z(general, "Method not implemented.", xctx);
123 
124 }
125 
126 
127 
128 /*
129  * Implementation of method add_reference for interface afw_object.
130  */
131 void
133  const afw_object_t *instance,
134  afw_xctx_t *xctx)
135 {
136  /* Nothing to do? */
137 }
138 
139 /*
140  * Implementation of method get_count for interface afw_object.
141  */
144  const afw_object_t * instance,
145  afw_xctx_t * xctx)
146 {
147 // <afwdev {prefixed_interface_name}>_self_t *self =
148 // (<afwdev {prefixed_interface_name}>_self_t *)instance;
149 
151  AFW_THROW_ERROR_Z(general, "Method not implemented.", xctx);
152 
153 }
154 
155 /*
156  * Implementation of method get_property for interface afw_object.
157  */
158 const afw_value_t *
160  const afw_object_t *instance,
161  const afw_utf8_t *property_name,
162  afw_xctx_t *xctx)
163 {
165  (afw_value_meta_object_self_t *)instance;
167 
168  /* If get callback for this property, return it's result. */
169  for (h = &impl_handler[0]; h < impl_handler_end; h++) {
170  if (afw_utf8_equal(h->property_name, property_name)) {
171  if (h->get) {
172  return h->get(self, property_name, xctx);
173  }
174  break;
175  }
176  }
177 
178  /* If additional, get property from it. */
179  if (self->additional) {
180  return afw_object_get_property(self->additional,
181  property_name, xctx);
182  }
183 
184  /* Return NULL if not found. */
185  return NULL;
186 }
187 
188 
189 
190 /*
191  * Implementation of method get_next_property for interface afw_object.
192  */
193 const afw_value_t *
195  const afw_object_t *instance,
196  const afw_iterator_t **iterator,
197  const afw_utf8_t **property_name,
198  afw_xctx_t *xctx)
199 {
201  (afw_value_meta_object_self_t *)instance;
203  const afw_value_t *result;
204  const afw_utf8_t *next_property_name;
205 
206  /*
207  * If this is the first time (*iterator is NULL), set iterator to first
208  * impl_handler[] entry.
209  */
210  if (!*iterator) {
211  *iterator = (const afw_iterator_t *)&impl_handler[0];
212  }
213 
214  /*
215  * If *iterator is within bounds for impl_handler array, *iterator points
216  * to the next impl_handler array entry to process. Loop calling the
217  * callback of each entry from this point until a callback returns a
218  * non-NULL result or the end of the array is encountered. Set *iterator
219  * to the next entry to process or the end of the array.
220  *
221  * If a callback returns a non-NULL result, return from this function
222  * with that result.
223  */
224  if (*(void **)iterator >= (void *)&impl_handler[0])
225  {
226  h = (const afw_value_meta_name_handler_t *)*iterator;
227  for (; h < impl_handler_end; h++)
228  {
229  result = h->get(self, h->property_name, xctx);
230  *iterator = (const afw_iterator_t *)(h + 1);
231  if (result) {
232  if (property_name) {
233  *property_name = h->property_name;
234  }
235  return result;
236  }
237  }
238  }
239 
240  /*
241  * If there is an additional object that contains properties to return,
242  * return the result of calling its get_next_property() if it's not for
243  * a property name in impl_handler array. If the previous iterator points
244  * to the end of impl_handler indicating that the impl_handler array has
245  * just been completely processed, set the iterator to NULL before calling
246  * get_next_property().
247  */
248  if (self->additional) {
249  if ((const afw_value_meta_name_handler_t *)*iterator ==
250  impl_handler_end)
251  {
252  *iterator = NULL;
253  }
254  for (;;) {
255  result = afw_object_get_next_property(self->additional,
256  iterator, &next_property_name, xctx);
257  if (!result) {
258  break;
259  }
260  for (h = &impl_handler[0];
261  h < impl_handler_end &&
262  !afw_utf8_equal(h->property_name, next_property_name);
263  h++);
264  if (h >= impl_handler_end) {
265  if (property_name) {
266  *property_name = next_property_name;
267  }
268  return result;
269  }
270  }
271  }
272 
273  /* At this point there are no more properties to return. */
274  *iterator = NULL;
275  if (property_name) {
276  *property_name = NULL;
277  }
278  return NULL;
279 }
280 
281 
282 
283 /*
284  * Implementation of method has_property for interface afw_object.
285  */
288  const afw_object_t *instance,
289  const afw_utf8_t *property_name,
290  afw_xctx_t *xctx)
291 {
292  return
293  (impl_afw_object_get_property(instance, property_name, xctx) != NULL);
294 }
295 
296 
297 
298 /*
299  * Implementation of method get_setter for interface afw_object.
300  */
301 const afw_object_setter_t *
303  const afw_object_t *instance,
304  afw_xctx_t *xctx)
305 {
307  (afw_value_meta_object_self_t *)instance;
308 
309  return (self->immutable) ? NULL : &self->setter;
310 }
311 
312 
313 
314 /*
315  * Implementation of method set_immutable for interface afw_object_setter.
316  */
317 void
319  const afw_object_setter_t *instance,
320  afw_xctx_t *xctx)
321 {
323  (afw_value_meta_object_self_t *)instance->object;
324 
325  /* Set object to immutable. */
326  self->immutable = true;
327 }
328 
329 /*
330  * Implementation of method set_property for interface afw_object_setter.
331  */
332 void
334  const afw_object_setter_t *instance,
335  const afw_utf8_t *property_name,
336  const afw_value_t *value,
337  afw_xctx_t *xctx)
338 {
340  (afw_value_meta_object_self_t *)instance->object;
342 
343  AFW_OBJECT_IMPL_ASSERT_SELF_MUTABLE;
344 
345  /* If get callback for this property, return it's result. */
346  for (h = &impl_handler[0]; h < impl_handler_end; h++) {
347  if (afw_utf8_equal(h->property_name, property_name)) {
348  if (h->set) {
349  h->set(self, property_name, value, xctx);
350  return;
351  }
352  break;
353  }
354  }
355 
356  if (!self->additional) {
357  self->additional = afw_object_create(self->pub.p, xctx);
358  }
359 
360  afw_object_set_property(self->additional, property_name, value, xctx);
361 }
362 
363 
364 
366 afw_value_internal_create_meta_object_self(
367  const afw_value_t *value,
368  const afw_pool_t *p,
369  afw_xctx_t *xctx)
370 {
372 
374 
375  self->pub.inf = &impl_afw_object_inf;
376  self->pub.p = p;
377  self->value = value;
378  self->evaluated_value = afw_value_evaluate(value, p, xctx);
379  self->meta_object_value.inf = &afw_value_evaluated_object_inf;
380  self->meta_object_value.internal = (const afw_object_t *)self;
381  self->setter.inf = &impl_afw_object_setter_inf;
382  self->setter.object = (const afw_object_t *)self;
383 
384  /*? self->pub.meta */
385 
386  return self;
387 }
388 
389 
390 
392 afw_value_internal_get_evaluated_meta_default(
393  const afw_value_t *value,
394  const afw_pool_t *p,
395  afw_xctx_t *xctx)
396 {
398 
399  self = afw_value_internal_create_meta_object_self(
400  value, p, xctx);
401  return (const afw_value_t *)&self->meta_object_value;
402 }
403 
404 
405 
407 afw_value_internal_get_evaluated_metas_default(
408  const afw_value_t *value,
409  const afw_pool_t *p,
410  afw_xctx_t *xctx)
411 {
412  const afw_value_t **metas;
413  const afw_list_t *list;
414 
415  metas = afw_pool_malloc(p, sizeof(afw_value_t *) * 2, xctx);
416  metas[0] = afw_value_get_evaluated_meta(value, p, xctx);
417  metas[1] = NULL;
419 
420  return afw_value_create_list(list, p, xctx);
421 }
422 
423 
424 
426 afw_value_internal_get_evaluated_meta_for_list(
427  const afw_value_t *value,
428  const afw_pool_t *p,
429  afw_xctx_t *xctx)
430 {
432 
433  /*FIXME Meta should include extra list meta. */
434 
435  self = afw_value_internal_create_meta_object_self(
436  value, p, xctx);
437  return (const afw_value_t *)& self->meta_object_value;
438 }
439 
440 
441 
443 afw_value_internal_get_evaluated_metas_for_list(
444  const afw_value_t *value,
445  const afw_pool_t *p,
446  afw_xctx_t *xctx)
447 {
448  const afw_list_t *passed_list;
449  const afw_list_t *list;
450  const afw_iterator_t *iterator;
451  const afw_value_t *entry_meta;
452 
453  passed_list = afw_value_as_list(value, xctx);
454  list = afw_list_create_generic(p, xctx);
455 
456  for (iterator = NULL;;) {
457  entry_meta = afw_list_get_next_entry_meta(passed_list,
458  &iterator, p, xctx);
459  if (!entry_meta) {
460  break;
461  }
462  afw_list_add_value(list, entry_meta, xctx);
463  }
464 
465  return afw_value_create_list(list, p, xctx);
466 }
467 
468 
469 
471 afw_value_internal_get_evaluated_meta_for_object(
472  const afw_value_t *value,
473  const afw_pool_t *p,
474  afw_xctx_t *xctx)
475 {
476  //return afw_object_get_meta(
477  // ((const afw_value_object_t *)value)->internal,
478  // p, xctx);
479  /*FIXME Meta should include extra object meta. */
480 
482 
483  self = afw_value_internal_create_meta_object_self(
484  value, p, xctx);
485  self->additional = (((afw_value_object_t *)value)->internal)->
486  meta.meta_object;
487  return (const afw_value_t *)& self->meta_object_value;
488 }
489 
490 
491 
493 afw_value_internal_get_evaluated_metas_for_object(
494  const afw_value_t *value,
495  const afw_pool_t *p,
496  afw_xctx_t *xctx)
497 {
498  const afw_object_t *object;
499  const afw_list_t *list;
500  const afw_iterator_t *iterator;
501  const afw_value_t *property_meta;
502  const afw_utf8_t *property_name;
503 
504  object = afw_value_as_object(value, xctx);
505  list = afw_list_create_generic(p, xctx);
506 
507  for (iterator = NULL;;) {
508  property_meta = afw_object_get_next_property_meta(object,
509  &iterator, &property_name, p, xctx);
510  if (!property_meta) {
511  break;
512  }
513  afw_list_add_value(list, property_meta, xctx);
514  }
515 
516  return afw_value_create_list(list, p, xctx);
517 }
#define AFW_DEFINE_INTERNAL(type)
Define an internal function for /src/afw/ source*.c files.
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
Interface afw_interface implementation declares.
afw_value_create_list(const afw_list_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type list value.
afw_value_as_list(const afw_value_t *value, afw_xctx_t *xctx)
Typesafe cast of data type list.
afw_value_as_object(const afw_value_t *value, afw_xctx_t *xctx)
Typesafe cast of data type object.
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.
struct afw_iterator_s afw_iterator_t
_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
#define afw_list_get_next_entry_meta(instance, iterator, p, xctx)
Call method get_next_entry_meta of interface afw_list.
const afw_list_t * afw_list_const_create_null_terminated_array_of_values(const afw_value_t *const *values, const afw_pool_t *p, afw_xctx_t *xctx)
Create an immutable list from NULL terminated array of values.
#define afw_list_create_generic(p, xctx)
Create an value list in memory.
Definition: afw_list.h:81
afw_list_add_value(const afw_list_t *instance, const afw_value_t *value, afw_xctx_t *xctx)
Call method add_value of interface afw_list_setter.
Definition: afw_list.c:104
const afw_object_setter_t * impl_afw_object_get_setter(const afw_object_t *instance, afw_xctx_t *xctx)
void impl_afw_object_add_reference(const afw_object_t *instance, afw_xctx_t *xctx)
const afw_value_t * impl_afw_object_get_next_property(const afw_object_t *instance, const afw_iterator_t **iterator, const afw_utf8_t **property_name, afw_xctx_t *xctx)
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_boolean_t impl_afw_object_has_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_get_property(instance, property_name, xctx)
Call method get_property 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_next_property_meta(instance, iterator, property_name, p, xctx)
Call method get_next_property_meta of interface afw_object.
void 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_create(p, xctx)
Create an empty unmanaged object in memory.
Definition: afw_object.h:948
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_malloc(instance, size, xctx)
Call method malloc 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
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_evaluated_meta(instance, p, xctx)
Call method get_evaluated_meta of interface afw_value.
#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_list 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.