Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_list_wrapper_for_array.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework afw_list interface for array
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 
17 
18 #define impl_afw_list_get_entry_meta afw_list_impl_get_entry_meta
19 #define impl_afw_list_get_next_entry_meta afw_list_impl_get_next_entry_meta
20 
21 /* Declares and rti/inf defines for interface afw_list */
22 #define AFW_IMPLEMENTATION_ID "afw_list_wrapper_for_array"
23 #define AFW_IMPLEMENTATION_INF_SPECIFIER AFW_DEFINE_CONST_DATA
24 #define AFW_IMPLEMENTATION_INF_LABEL afw_list_wrapper_for_array_inf
25 #include "afw_list_impl_declares.h"
26 #undef AFW_IMPLEMENTATION_INF_SPECIFIER
27 #undef AFW_IMPLEMENTATION_INF_LABEL
28 
29 
30 /* Create a immutable list wrapper for a array. */
31 AFW_DEFINE(const afw_list_t *)
33  const void *internal,
34  afw_boolean_t indirect,
35  const afw_data_type_t *data_type,
36  afw_size_t count,
37  const afw_pool_t *p,
38  afw_xctx_t *xctx)
39 {
41  const afw_octet_t *ptr;
42 
44  self->inf = &afw_list_wrapper_for_array_inf;
45  self->p = p;
46  self->internal = internal;
47  self->data_type = data_type;
48  self->count = count;
49  self->indirect = indirect;
50 
51  if (count == -1) {
52  if (indirect) {
53  for (count = 0, ptr = (const afw_octet_t *)internal;
54  *(const void * const *)ptr;
55  count++, ptr += sizeof(void *));
56  }
57  else {
58  if (data_type->c_type_size < sizeof(const void * const *)) {
59  AFW_THROW_ERROR_Z(general,
60  "count -1 is not supported for this data type",
61  xctx);
62  }
63  for (count = 0, ptr = (const afw_octet_t *)internal;
64  *(const void * const *)ptr;
65  count++, ptr += data_type->c_type_size);
66  }
67  self->count = count;
68  }
69 
70  return (const afw_list_t *)self;
71 }
72 
73 
74 
75 /* Convert a list to a list of strings. */
76 AFW_DEFINE(const afw_list_t *)
78  const afw_list_t *list,
79  const afw_pool_t *p,
80  afw_xctx_t *xctx)
81 {
83  afw_size_t count;
84  const afw_data_type_t *data_type;
85  void *internal;
86  const afw_utf8_t *s;
87  const afw_value_t *value;
88  const afw_iterator_t *iterator;
89 
90  /* Return original if already list of string. */
91  if (afw_list_get_data_type(list, xctx) == afw_data_type_string) {
92  return list;
93  }
94 
95  /* Get count. */
96  count = afw_list_get_count(list, xctx);
97 
98  /* If count is 0, return empty list of string. */
99  if (count == 0) {
100  return afw_data_type_string->empty_list;
101  }
102 
103  /* Allocate array for internal values and self for wrapper. */
104  internal = afw_pool_malloc(p, count * sizeof(afw_utf8_t), xctx);
106  self->inf = &afw_list_wrapper_for_array_inf;
107  self->p = p;
108  self->internal = internal;
109  self->data_type = afw_data_type_string;
110  self->count = count;
111  self->indirect = false;
112 
113  /* Convert each value in list to a string. */
114  for (iterator = NULL;;
115  internal = (void *)(((afw_byte_t *)internal) + sizeof(afw_utf8_t)))
116  {
117  value = afw_list_get_next_value(list, &iterator, p, xctx);
118  if (!value) {
119  break;
120  }
121  value = afw_value_evaluate(value, p, xctx);
122  data_type = afw_value_get_data_type(value, xctx);
123  if (!data_type) {
124  AFW_THROW_ERROR_Z(general,
125  "data type needed in afw_list_convert_to_list_of_strings()",
126  xctx);
127  }
129  data_type, &((const afw_value_evaluated_t *)value)->internal,
130  p, xctx);
131  memcpy(internal, s, sizeof(afw_utf8_t));
132  }
133 
134  /* Return list of string. */
135  return (const afw_list_t *)self;
136 }
137 
138 
139 
140 /*
141  * Implementation of method release of interface afw_list.
142  */
143 void
145  const afw_list_t * instance,
146  afw_xctx_t *xctx)
147 {
148  /* Nothing to do. */
149 }
150 
151 
152 
153 /*
154  * Implementation of method get_count for interface afw_list.
155  */
158  const afw_list_t * instance,
159  afw_xctx_t *xctx)
160 {
163 
164  return self->count;
165 }
166 
167 
168 
169 /*
170  * Implementation of method get_data_type for interface afw_list.
171  */
172 const afw_data_type_t *
174  const afw_list_t * instance,
175  afw_xctx_t *xctx)
176 {
179 
180  return self->data_type;
181 }
182 
183 
184 
185 /*
186  * Implementation of method get_entry_internal for interface afw_list.
187  */
190  const afw_list_t * instance,
191  afw_integer_t index,
192  const afw_data_type_t * * data_type,
193  const void * *internal,
194  afw_xctx_t *xctx)
195 {
198  const void *e;
199  afw_size_t count;
200  afw_size_t i;
201 
202  /* e is NULL if negative index or it doesn't fit in afw_size_t. */
203  i = (afw_size_t)index;
204  if (index < 0 || i != index) {
205  e = NULL;
206  }
207 
208  /* NULL terminated list. */
209  else if (self->count == -1) {
210  for (count = 0, e = self->internal;
211  *(void **)e && count < i;
212  count++, e = ((void **)e) + 1);
213  e = *(void **)e;
214  }
215 
216  /* List of internals. */
217  else {
218  if (i > self->count) {
219  e = NULL;
220  }
221  else if (self->indirect) {
222  e = *(((void **)self->internal) + i);
223  }
224  else {
225  e = (void *)
226  (((afw_byte_t *)self->internal) +
227  (i * self->data_type->c_type_size));
228  }
229  }
230 
231  /* Found. */
232  if (e) {
233  *internal = e;
234  if (data_type) {
235  *data_type = self->data_type;
236  }
237  return true;
238  }
239 
240  /* Not found. */
241  else {
242  *internal = NULL;
243  if (data_type) {
244  *data_type = NULL;
245  }
246  return false;
247  }
248 }
249 
250 
251 
252 /*
253  * Implementation of method get_entry_value for interface afw_list.
254  */
255 const afw_value_t *
257  const afw_list_t * instance,
258  afw_integer_t index,
259  const afw_pool_t * p,
260  afw_xctx_t *xctx)
261 {
262  const afw_data_type_t *data_type;
263  const void *internal;
264  const afw_value_t *result;
265 
267  index, &data_type, &internal, xctx))
268  {
270  internal, data_type, p, xctx);
271  }
272 
273  else {
274  result = NULL;
275  }
276 
277  return result;
278 }
279 
280 
281 
282 /*
283  * Implementation of method get_entry_internal for interface afw_list.
284  */
287  const afw_list_t * instance,
288  const afw_iterator_t * * iterator,
289  const afw_data_type_t * * data_type,
290  const void * * internal,
291  afw_xctx_t *xctx)
292 {
295  afw_size_t size;
296 
297  /* If iterator is NULL, point to first value in array. */
298  if (!*iterator) {
299  *iterator = (const afw_iterator_t *)self->internal;
300  }
301 
302  /* Determine size of entry. */
303  size = (self->indirect) ? sizeof(void *) : self->data_type->c_type_size;
304 
305  /* If past end of values, result is NULL. */
306  if (*iterator >= (const afw_iterator_t *)(
307  ((const afw_octet_t *)self->internal) + (size * self->count)))
308  {
309  if (data_type) {
310  *data_type = NULL;
311  }
312  *internal = NULL;
313  *iterator = NULL;
314  }
315 
316  /* If not past end, set return values and increment iterator. */
317  else {
318  if (data_type) {
319  *data_type = self->data_type;
320  }
321  if (self->indirect) {
322  *internal = *(const void **)*iterator;
323  }
324  else {
325  *internal = (const void *)*iterator;
326  }
327  *iterator = (const afw_iterator_t *)
328  (((afw_octet_t *)(*iterator)) + size);
329  }
330 
331  return *internal != NULL;
332 }
333 
334 
335 
336 /*
337  * Implementation of method get_next_value for interface afw_list.
338  */
339 const afw_value_t *
341  const afw_list_t * instance,
342  const afw_iterator_t * * iterator,
343  const afw_pool_t * p,
344  afw_xctx_t *xctx)
345 {
348  const afw_value_t *result;
349  afw_size_t size;
350 
351  /* Require p. */
352  if (!p) {
353  AFW_THROW_ERROR_Z(general,
354  "afw_list_get_next_value() requires p",
355  xctx);
356  }
357 
358  /* If iterator is NULL, point to first value in array. */
359  if (!*iterator) {
360  *iterator = (const afw_iterator_t *)self->internal;
361  }
362 
363  /* Determine size of entry. */
364  size = (self->indirect) ? sizeof(void *) : self->data_type->c_type_size;
365 
366  /* If past end of values, result is NULL. */
367  if (*iterator >= (const afw_iterator_t *)(
368  ((const afw_octet_t *)self->internal) + (size * self->count)))
369  {
370  result = NULL;
371  *iterator = NULL;
372  }
373 
374  /* If not past end, create a single value and increment iterator. */
375  else {
377  (self->indirect) ? *(void **)*iterator: (void *)*iterator,
378  self->data_type,
379  p, xctx);
380  *iterator = (const afw_iterator_t *)
381  (((afw_octet_t *)(*iterator)) + size);
382  }
383 
384  /* Return result. */
385  return result;
386 }
387 
388 
389 
390 /*
391  * Implementation of method get_setter for interface afw_list.
392  */
393 const afw_list_setter_t *
395  const afw_list_t * instance,
396  afw_xctx_t *xctx)
397 {
398  return NULL;
399 }
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
afw_data_type_string
Data type struct for string.
struct afw_iterator_s afw_iterator_t
_Bool afw_boolean_t
Definition: afw_common.h:373
unsigned char afw_byte_t
A byte of memory (unsigned).
Definition: afw_common.h:208
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
unsigned char afw_octet_t
8 bits (unsigned).
Definition: afw_common.h:211
apr_int64_t afw_integer_t
typedef for big signed int.
Definition: afw_common.h:321
#define afw_data_type_internal_to_utf8(instance, from_internal, p, xctx)
Call method internal_to_utf8 of interface afw_data_type.
#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
impl_afw_list_get_next_value(const afw_list_t *instance, const afw_iterator_t **iterator, const afw_pool_t *p, afw_xctx_t *xctx)
impl_afw_list_get_entry_internal(const afw_list_t *instance, afw_integer_t index, const afw_data_type_t **data_type, const void **internal, afw_xctx_t *xctx)
impl_afw_list_get_data_type(const afw_list_t *instance, afw_xctx_t *xctx)
impl_afw_list_release(const afw_list_t *instance, afw_xctx_t *xctx)
impl_afw_list_get_next_internal(const afw_list_t *instance, const afw_iterator_t **iterator, const afw_data_type_t **data_type, const void **internal, afw_xctx_t *xctx)
impl_afw_list_get_setter(const afw_list_t *instance, afw_xctx_t *xctx)
impl_afw_list_get_count(const afw_list_t *instance, afw_xctx_t *xctx)
impl_afw_list_get_entry_value(const afw_list_t *instance, afw_integer_t index, const afw_pool_t *p, afw_xctx_t *xctx)
#define afw_list_get_next_value(instance, iterator, p, xctx)
Call method get_next_value of interface afw_list.
#define afw_list_get_data_type(instance, xctx)
Call method get_data_type of interface afw_list.
#define afw_list_get_count(instance, xctx)
Call method get_count of interface afw_list.
afw_list_create_wrapper_for_array(const void *internal, afw_boolean_t indirect, const afw_data_type_t *data_type, afw_size_t count, const afw_pool_t *p, afw_xctx_t *xctx)
Create a immutable list wrapper for an array.
afw_list_wrapper_for_array_inf
inf for afw_list_wrapper_for_array afw_list implementation.
Definition: afw_list.h:254
afw_list_convert_to_list_of_strings(const afw_list_t *list, const afw_pool_t *p, afw_xctx_t *xctx)
Convert a list to a list of strings.
#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
#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
const afw_value_t * afw_value_evaluated_create(const void *value, const afw_data_type_t *data_type, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for an evaluated data type value.
Interface afw_data_type public struct.
Interface afw_list public struct.
Interface afw_list_setter public struct.
Self for immutable list wrapper for a array.
Definition: afw_list.h:237
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Struct to access internal of all evaluated values.
Definition: afw_value.h:60
Interface afw_value public struct.
Interface afw_xctx public struct.