Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_xctx.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_xctx interface
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 
17 /* Declares and rti/inf defines for interface afw_xctx */
18 #define AFW_IMPLEMENTATION_ID "core"
19 #include "afw_xctx_impl_declares.h"
20 #include <libxml/xmlregexp.h>
21 
22 
23 static void XMLCDECL
24 impl_suppress_libxml2_message(
25  void *ctx,
26  const char *msg,
27  ...)
28 {
29  /* Do nothing just suppress print. */
30 }
31 
32 
33 
36  afw_try_t *unhandled_error,
37  afw_error_t *error,
39  const afw_pool_t *p)
40 {
41  afw_xctx_t *self;
42 
43  if (!error) {
44  /* Allocate cleared afw_error_t. */
45  error = apr_pcalloc(afw_pool_get_apr_pool(p), sizeof(afw_error_t));
46  }
47 
48  /* Initialize self. */
49  self = apr_pcalloc(afw_pool_get_apr_pool(p), sizeof(afw_xctx_t));
50  if (!self) {
51  AFW_THROW_UNHANDLED_ERROR(unhandled_error, error, general,
52  na, 0, "apr_pcalloc() failed");
53  }
54  self->inf = &impl_afw_xctx_inf;
55  self->p = p;
57  self->current_try = unhandled_error;
58  self->error = error;
59  self->env = (const afw_environment_t *)env;
60  error->xctx = self;
61  self->flags_count = env->pub.flags_count_allocated;
62  self->flags = (afw_boolean_t *)env->pub.default_flags;
64  self->stream_anchor = afw_stream_internal_stream_anchor_create(self);
65 
66  self->stack = apr_array_make(afw_pool_get_apr_pool(p),
67  10, sizeof(afw_name_value_t));
68  if (!self->stack) {
69  AFW_THROW_UNHANDLED_ERROR(unhandled_error, error, general, na, 0,
70  "apr_array_make() failed");
71  }
72 
73  /*
74  * Set libxml2 error func to suppress error print. Use
75  * xmlGetLastError() instead.
76  */
77  self->libxml2_error_func = (void *)impl_suppress_libxml2_message;
78  initGenericErrorDefaultFunc((xmlGenericErrorFunc *)&self->libxml2_error_func);
79 
80  /* Make qualifier and evaluation stack. */
82  afw_stack_internal_set_evaluation_stack(self);
83 
84  /* Return new xctx. */
85  return self;
86 }
87 
88 
89 AFW_DEFINE(void)
90 afw_xctx_internal_create_finishup(afw_xctx_t *xctx)
91 {
92  /*
93  * Finish setting up new xctx.
94  *
95  * Warning: Make sure functions called can deal with partially set up
96  * xctx. We need to call these with new xctx so the
97  * resources will be associated with the new xctx.
98  *
99  */
100 
101  /* Get xctx's UUID. */
102  xctx->uuid = afw_uuid_create_utf8(xctx->p, xctx);
103 
104  /* Create a properties object. */
105  xctx->properties = afw_object_create(
106  xctx->p, xctx);
107 
108  /* Set times. */
109  afw_dateTime_set_now(&xctx->local_dateTime_when_created,
110  &xctx->utc_dateTime_when_created, xctx);
111 
112  /* Push application qualifiers if appropriate. */
114 }
115 
116 
118 afw_xctx_internal_create_thread_xctx(
119  const afw_thread_t *thread, afw_xctx_t *xctx)
120 {
121  afw_xctx_t *self;
122 
123  self = afw_xctx_internal_create_initialize(xctx->current_try,
124  NULL, (afw_environment_internal_t *)xctx->env, thread->p);
125  if (!self) {
126  AFW_THROW_ERROR_Z(general, "Error creating xctx", xctx);
127  }
128 
129  /* Set thread, name and number in xctx. */
130  self->thread = thread;
131  self->name = thread->name;
132  self->parent = xctx;
133 
134  xctx = (afw_xctx_t *)self;
135 
136  /* Finish xctx creation. */
137  afw_xctx_internal_create_finishup(xctx);
138 
139  /* Return self. */
140  return self;
141 }
142 
143 
146  const afw_utf8_t *name, afw_integer_t number, afw_xctx_t *xctx)
147 {
148  const afw_pool_t *p;
149  afw_xctx_t *self;
150 
151  /* Create a new pool for xctx and initialize. */
152  p = afw_pool_create(xctx->p, xctx);
153  self = afw_xctx_internal_create_initialize(xctx->current_try,
154  NULL, (afw_environment_internal_t *)xctx->env, p);
155  if (!self) {
156  AFW_THROW_ERROR_Z(general, "Error creating xctx", xctx);
157  }
158 
159  /* Set thread, name and number in xctx. */
160  self->thread = xctx->thread;
161  self->name = name;
162  self->parent = xctx;
163 
164  xctx = (afw_xctx_t *)self;
165 
166  /* Finish xctx creation. */
167  afw_xctx_internal_create_finishup(xctx);
168 
169  /* Return self. */
170  return self;
171 }
172 
173 
174 /* Get a variable from xctx stack. */
175 AFW_DEFINE(const afw_value_t *)
177  const afw_utf8_t *qualifier,
178  const afw_utf8_t *name,
179  afw_xctx_t *xctx)
180 {
181  afw_name_value_t * cur;
182  afw_name_value_t * bottom;
183  const afw_value_t * result;
184  const afw_xctx_qualifier_stack_entry_t * e_cur;
185  afw_boolean_t qualifier_passed;
186 
187  result = NULL;
188  qualifier_passed = qualifier && qualifier->len != 0;
189 
190  /* If no qualifier, check variable stack for variable. */
191  if (!qualifier_passed) {
192  for (
193  bottom = (afw_name_value_t *)xctx->stack->elts,
194  cur = bottom + ((afw_size_t)xctx->stack->nelts - 1);
195  cur >= bottom;
196  cur--)
197  {
198  if (afw_utf8_equal(name, cur->name)) {
199  return cur->value;
200  }
201  }
202  }
203 
204  /* Else if there is a qualifier, ...*/
205  else for (
206  e_cur = xctx->qualifier_stack->top;
207  e_cur >= xctx->qualifier_stack->first;
208  e_cur--)
209  {
210  if (!e_cur->get) {
211  continue;
212  }
213 
214  if (qualifier_passed) {
215  if (!afw_utf8_equal(qualifier, &e_cur->qualifier)) {
216  continue;
217  }
218  }
219 
220  if (!e_cur->secure && xctx->secure) {
221  continue;
222  }
223 
224  result = e_cur->get(e_cur, name, xctx);
225  break;
226  }
227 
228  /* Return result. */
229  return result;
230 }
231 
232 
233 /* Set a variable in current xctx frame. */
234 AFW_DEFINE(void)
236  const afw_value_t *value, afw_xctx_t *xctx)
237 {
238  afw_name_value_t *cur;
239  afw_name_value_t *bottom;
240  afw_name_value_t *stopat;
241 
242  for (bottom = (afw_name_value_t *)xctx->stack->elts,
243  stopat = bottom + xctx->current_frame_index,
244  cur = bottom + ((afw_size_t)xctx->stack->nelts - 1);
245  cur >= stopat;
246  cur--)
247  {
248  if (afw_utf8_equal(name, cur->name)) {
249  AFW_THROW_ERROR_FZ(general, xctx,
250  "Variable %" AFW_UTF8_FMT " is already defined",
251  AFW_UTF8_FMT_ARG(name));
252  }
253  };
254 
255  cur = (afw_name_value_t *)apr_array_push(xctx->stack);
256  cur->name = name;
257  cur->value = value;
258 }
259 
260 
261 /* Set most recent defined variable in xctx. */
262 AFW_DEFINE(void)
264  const afw_utf8_t *name,
265  const afw_value_t *value,
266  afw_xctx_t *xctx)
267 {
268  afw_name_value_t *cur;
269 
270  for (cur = (afw_name_value_t *)xctx->stack->elts +
271  ((afw_size_t)xctx->stack->nelts - 1);
272  cur >= (afw_name_value_t *)xctx->stack->elts;
273  cur--)
274  {
275  if (afw_utf8_equal(name, cur->name)) {
276  cur->value = value;
277  return;
278  }
279  };
280 
281  AFW_THROW_ERROR_FZ(general, xctx,
282  "Variable %" AFW_UTF8_FMT " is not defined",
283  AFW_UTF8_FMT_ARG(name));
284 }
285 
286 
287 /* Set a variable in current xctx frame. */
288 AFW_DEFINE(void)
290  const afw_value_t *value, afw_xctx_t *xctx)
291 {
292  afw_name_value_t * cur;
293  afw_name_value_t * bottom;
294  afw_name_value_t * stopat;
295 
296  for (bottom = (afw_name_value_t *)xctx->stack->elts,
297  stopat = bottom + xctx->current_frame_index,
298  cur = bottom + ((afw_size_t)xctx->stack->nelts - 1);
299  cur >= stopat;
300  cur--)
301  {
302  if (afw_utf8_equal(name, cur->name)) {
303  cur->value = value;
304  return;
305  }
306  };
307 
308  cur = (afw_name_value_t *)apr_array_push(xctx->stack);
309  cur->name = name;
310  cur->value = value;
311 }
312 
313 
314 /* Get stack top. */
315 AFW_DEFINE(int)
317  afw_xctx_t *xctx)
318 {
319  return (int)(xctx->qualifier_stack->top - xctx->qualifier_stack->first);
320 }
321 
322 
323 /* Set qualifier stack top. */
324 AFW_DEFINE(void)
326  int top, afw_xctx_t *xctx)
327 {
328  ((afw_xctx_qualifier_stack_t *)xctx->qualifier_stack)->top =
329  xctx->qualifier_stack->first + top;
330 }
331 
332 
333 
334 /* Push qualifiers object on to stack. */
335 AFW_DEFINE(void)
337  const afw_object_t *context_object,
338  afw_boolean_t secure,
339  const afw_pool_t *p,
340  afw_xctx_t *xctx)
341 {
342  const afw_iterator_t *iterator;
343  const afw_utf8_t *qualifier_name;
344  const afw_object_t *qualifier_object;
345 
346  for (iterator = NULL;
347  (qualifier_object = afw_object_old_get_next_property_as_object(
348  context_object, &iterator, &qualifier_name, xctx)); )
349  {
350  afw_xctx_push_qualifier_object(qualifier_name, qualifier_object,
351  secure, p, xctx);
352  }
353 }
354 
355 
356 
357 /* Push qualifier on to stack. */
360  const afw_utf8_t *qualifier,
361  const afw_object_t *qualifier_object,
362  afw_boolean_t secure,
364  void * data,
365  const afw_pool_t *p,
366  afw_xctx_t *xctx)
367 {
370 
371  if (!qualifier || qualifier->len == 0) {
372  AFW_THROW_ERROR_Z(general, "Qualifier required", xctx);
373  }
374 
376  (afw_xctx_qualifier_stack_t *)xctx->qualifier_stack, entry, xctx);
377 
378  memset(entry, 0, sizeof(afw_xctx_qualifier_stack_entry_t));
379  entry->p = p;
380  if (qualifier) {
381  memcpy(&entry->qualifier, qualifier,
383  }
384  entry->qualifier_object = qualifier_object;
385  entry->get = get;
386  entry->data = data;
387  entry->secure = secure;
388 
389  return entry;
390 }
391 
392 
393 static const afw_value_t *
394 impl_get_object_variable(
396  const afw_utf8_t *name,
397  afw_xctx_t *xctx)
398 {
399  /* Return property from qualifier_object as variable. */
400  return afw_object_get_property(entry->qualifier_object, name, xctx);
401 }
402 
403 
404 /* Push qualifier on to stack. */
405 AFW_DEFINE(void)
407  const afw_utf8_t *qualifier_name,
408  const afw_object_t *qualifier_object,
409  afw_boolean_t secure,
410  const afw_pool_t *p,
411  afw_xctx_t *xctx)
412 {
413 
415 
417  (afw_xctx_qualifier_stack_t *)xctx->qualifier_stack, entry, xctx);
418  afw_memory_clear(entry);
419  entry->p = p;
420  if (qualifier_name) {
421  memcpy(&entry->qualifier, qualifier_name, sizeof(afw_utf8_t));
422  }
423  entry->qualifier_object = qualifier_object;
424  entry->get = impl_get_object_variable;
425  entry->secure = secure;
426 }
427 
428 
429 
430 /*
431  * Implementation of method release of interface afw_xctx.
432  */
433 void
434 impl_afw_xctx_release(
435  afw_xctx_t * instance,
436  afw_xctx_t *xctx)
437 {
438  /* Release streams. */
439  afw_stream_internal_release_all_streams(xctx);
440 
441  /* Release xctx's pool. */
442  if (instance->p) {
443  afw_pool_destroy(instance->p, xctx);
444  }
445 }
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
void afw_application_internal_push_qualifiers(afw_xctx_t *xctx)
Push application qualifiers on xctx's qualifier stack.
afw_authorization_mode_id_user_value
AdaptiveAuthorizationMode user.
#define afw_object_old_get_next_property_as_object(object, iterator, property_name, xctx)
Get next property function for data type object 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_xctx_internal_qualifier_stack_s afw_xctx_qualifier_stack_t
Typedef for xctx qualifier stack.
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
const afw_value_t *(* afw_xctx_get_variable_t)(const afw_xctx_qualifier_stack_entry_t *entry, const afw_utf8_t *name, afw_xctx_t *xctx)
Typedef for function to get a qualified variable.
Definition: afw_common.h:969
apr_int64_t afw_integer_t
typedef for big signed int.
Definition: afw_common.h:321
#define AFW_THROW_UNHANDLED_ERROR(unhandled_error, _ERROR, _CODE, _RV_SOURCE_ID, _RV, _MESSAGE_Z)
Definition: afw_error.h:182
#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
#define afw_memory_clear(to)
Clear preallocated memory for sizeof(*(to)).
Definition: afw_memory.h:47
#define afw_object_get_property(instance, property_name, xctx)
Call method get_property of interface afw_object.
#define afw_object_create(p, xctx)
Create an empty unmanaged object in memory.
Definition: afw_object.h:948
#define afw_pool_destroy(instance, xctx)
Call method destroy of interface afw_pool.
#define afw_pool_get_apr_pool(instance)
Call method get_apr_pool of interface afw_pool.
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
afw_stack_internal_set_qualifier_stack(afw_xctx_t *xctx)
Definition: afw_stack.c:31
#define afw_stack_push_and_get_entry(instance, entry, xctx)
Increment stack->top to location of next entry and get entry.
Definition: afw_stack.h:230
afw_dateTime_set_now(afw_dateTime_t *dateTime_local, afw_dateTime_t *dateTime_utc, afw_xctx_t *xctx)
Set local and/or utc dateTime to now.
Definition: afw_time.c:523
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_uuid_create_utf8(const afw_pool_t *p, afw_xctx_t *xctx)
Create a UUID as a standard format UUID utf-8 string.
Definition: afw_uuid.c:62
afw_xctx_internal_create_initialize(afw_try_t *unhandled_error, afw_error_t *error, afw_environment_internal_t *env, const afw_pool_t *p)
Definition: afw_xctx.c:35
afw_xctx_define_variable(const afw_utf8_t *name, const afw_value_t *value, afw_xctx_t *xctx)
Defined a variable in current xctx frame.
Definition: afw_xctx.c:235
afw_xctx_set_local_variable(const afw_utf8_t *name, const afw_value_t *value, afw_xctx_t *xctx)
Set a variable then current xctx frame.
Definition: afw_xctx.c:289
afw_xctx_get_qualified_variable(const afw_utf8_t *qualifier, const afw_utf8_t *name, afw_xctx_t *xctx)
Get a variable from xctx stack.
Definition: afw_xctx.c:176
afw_xctx_get_qualifier_stack_top(afw_xctx_t *xctx)
Get qualifier stack top.
Definition: afw_xctx.c:316
afw_xctx_push_qualifier_object(const afw_utf8_t *qualifier_name, const afw_object_t *qualifier_object, afw_boolean_t secure, const afw_pool_t *p, afw_xctx_t *xctx)
Push qualifier object on to stack.
Definition: afw_xctx.c:406
afw_xctx_push_qualifiers_object(const afw_object_t *context_object, afw_boolean_t secure, const afw_pool_t *p, afw_xctx_t *xctx)
Push qualifiers object on to stack.
Definition: afw_xctx.c:336
afw_xctx_set_qualifier_stack_top(int top, afw_xctx_t *xctx)
Set stack top index.
Definition: afw_xctx.c:325
afw_xctx_create(const afw_utf8_t *name, afw_integer_t number, afw_xctx_t *xctx)
Create an Adaptive Framework xctx.
Definition: afw_xctx.c:145
afw_xctx_set_defined_variable(const afw_utf8_t *name, const afw_value_t *value, afw_xctx_t *xctx)
Set a defined variable in xctx.
Definition: afw_xctx.c:263
afw_xctx_push_qualifier(const afw_utf8_t *qualifier, const afw_object_t *qualifier_object, afw_boolean_t secure, afw_xctx_get_variable_t get, void *data, const afw_pool_t *p, afw_xctx_t *xctx)
Push qualifier on to stack.
Definition: afw_xctx.c:359
Struct for typedef afw_environment_t defined in afw_common.h.
Definition: afw_common.h:1383
Adaptive Framework Error.
Definition: afw_error.h:65
Typedef for name/value pair.
Definition: afw_common.h:680
Interface afw_object public struct.
Interface afw_pool public struct.
Struct for public part of afw_pool_t.
Definition: afw_thread.h:56
const afw_pool_t * p
The thread specific pool for the thread.
Definition: afw_thread.h:72
const afw_utf8_t * name
The name passed on afw_thread_create().
Definition: afw_thread.h:66
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Interface afw_value public struct.
Definition: afw_xctx.h:352
const afw_object_t * qualifier_object
qualifier_object. This may be NULL now.
Definition: afw_xctx.h:361
void * data
Data that will be passed to get/set.
Definition: afw_xctx.h:367
const afw_pool_t * p
Pool used while processing entry.
Definition: afw_xctx.h:355
afw_utf8_t qualifier
qualifier or len=0 if unqualified.
Definition: afw_xctx.h:358
afw_xctx_get_variable_t get
Get routine or NULL if get not allowed.
Definition: afw_xctx.h:364
afw_boolean_t secure
Secure access to this qualifier is allowed.
Definition: afw_xctx.h:373
Interface afw_xctx public struct.