Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_stack.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Stack Support
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
9 
15 #include "afw_internal.h"
16 
17 
18 
19 typedef struct impl_stack_self_s {
20  afw_stack_t pub;
21  afw_size_t initial_count;
22  afw_size_t maximum_count;
23  afw_size_t entry_size;
24  afw_boolean_t create_subpool_pool;
26 
27 
28 
29 /* Create a stack during xctx creation. */
32  afw_xctx_t *xctx)
33 {
34  impl_stack_self_t *self;
35 
36  /*
37  * This early in xctx creation requires that nothing be called that
38  * directly or indirectly uses AFW_TRY such as afw_pool_calloc().
39  */
40  self = apr_pcalloc(afw_pool_get_apr_pool(xctx->p),
41  sizeof(impl_stack_self_t));
42  self->pub.p = xctx->p;
43  self->initial_count = 5;
44  self->entry_size = sizeof(afw_xctx_qualifier_stack_entry_t);
45  self->maximum_count = 0;
46 
57  self->initial_count = 100;
58  self->maximum_count = 100;
59 
60  self->pub.first = apr_pcalloc(afw_pool_get_apr_pool(xctx->p),
61  self->initial_count * self->entry_size);
62  self->pub.top = (afw_octet_t *)self->pub.first - self->entry_size;
63  self->pub.end = (afw_octet_t *)self->pub.first +
64  (self->entry_size * self->initial_count);
65  xctx->qualifier_stack = (afw_xctx_qualifier_stack_t *)self;
66 }
67 
68 
69 
70 /* Create a stack during xctx creation. */
72 afw_stack_internal_set_evaluation_stack(
73  afw_xctx_t *xctx)
74 {
75  impl_stack_self_t *self;
76 
77  /*
78  * This early in xctx creation requires that nothing be called that directly
79  * or indirectly uses AFW_TRY such as afw_pool_calloc().
80  */
81  self = apr_pcalloc(afw_pool_get_apr_pool(xctx->p),
82  sizeof(impl_stack_self_t));
83  self->pub.p = xctx->p;
84  self->initial_count = xctx->env->evaluation_stack_initial_count;
85  self->entry_size = sizeof(afw_xctx_evaluation_stack_entry_t);
86  self->maximum_count = xctx->env->evaluation_stack_maximum_count;
87 
88  self->pub.first = apr_pcalloc(afw_pool_get_apr_pool(xctx->p),
89  self->initial_count * self->entry_size);
90  self->pub.top = (afw_octet_t *)self->pub.first - self->entry_size;
91  self->pub.end = (afw_octet_t *)self->pub.first +
92  (self->entry_size * self->initial_count);
93  xctx->evaluation_stack = (afw_xctx_evaluation_stack_t *)self;
94 }
95 
96 
97 /* Create a stack. */
100  afw_size_t entry_size,
101  afw_size_t initial_count,
102  afw_size_t maximum_count,
103  afw_boolean_t create_subpool_pool,
104  const afw_pool_t *p,
105  afw_xctx_t *xctx)
106 {
107  impl_stack_self_t *self;
108 
109  if (create_subpool_pool) {
110  p = afw_pool_create(p, xctx);
111  }
112 
113  self = afw_pool_calloc_type(p, impl_stack_self_t, xctx);
114  self->pub.p = p;
115  self->initial_count = initial_count;
116  self->entry_size = entry_size;
117  self->maximum_count = maximum_count;
118  self->create_subpool_pool = create_subpool_pool;
119 
120  self->pub.first = afw_pool_calloc(p, initial_count * entry_size, xctx);
121  self->pub.top = (afw_octet_t *)self->pub.first - entry_size;
122  self->pub.end = (afw_octet_t *)self->pub.first +
123  (entry_size * initial_count);
124 
125  return &self->pub;
126 }
127 
128 
129 /* Release stack. */
130 AFW_DEFINE(void)
132  afw_stack_t * instance,
133  afw_xctx_t *xctx)
134 {
135  impl_stack_self_t *self =
136  (impl_stack_self_t *)instance;
137 
138  /* If subpool was created, release it. */
139  if (self->create_subpool_pool) {
140  afw_pool_release(self->pub.p, xctx);
141  }
142 }
143 
144 
145 
146 /* Copy stack. */
147 AFW_DEFINE(void)
149  afw_stack_t *instance,
150  afw_size_t *count,
151  const void ***ptr,
152  const afw_pool_t *p,
153  afw_xctx_t *xctx)
154 {
155  impl_stack_self_t *self = (impl_stack_self_t *)instance;
156  afw_size_t size;
157 
158  *ptr = NULL;
159  size = (afw_octet_t *)instance->top - (afw_octet_t *)instance->first +
160  self->entry_size;
161  if (count) {
162  *count = size / self->entry_size;
163  }
164  if (size > 0) {
165  *ptr = afw_pool_malloc(p, size, xctx);
166  memcpy((void *)*ptr, instance->first, size);
167  }
168 }
169 
170 
171 
172 /*
173  * Implementation of method extend for interface afw_stack.
174  */
175 AFW_DEFINE(void)
177  afw_stack_t * instance,
178  afw_xctx_t *xctx)
179 {
180  impl_stack_self_t *self =
181  (impl_stack_self_t *)instance;
182 
183  afw_size_t count, new_count;
184  afw_octet_t *new_first;
185 
186  count = ((afw_octet_t *)self->pub.end - (afw_octet_t *)self->pub.first) /
187  self->entry_size;
188 
189  if (self->maximum_count == 0) {
190  new_count = count * 2;
191  }
192  else {
193  if (count >= self->maximum_count) {
194  AFW_THROW_ERROR_Z(general, "Stack max_count exceeded", xctx);
195  }
196  new_count = count * 2;
197  if (new_count > self->maximum_count) {
198  new_count = self->maximum_count;
199  }
200  }
201 
202  new_first = afw_pool_calloc(self->pub.p, new_count * self->entry_size,
203  xctx);
204  memcpy(new_first, self->pub.first, self->entry_size * count);
205  self->pub.first = new_first;
206  self->pub.top = (afw_octet_t *)self->pub.first +
207  (self->entry_size * count);
208  self->pub.end = (afw_octet_t *)self->pub.first +
209  (self->entry_size * new_count);
210 }
AFW_DEFINE(const afw_object_t *)
#define AFW_DEFINE_INTERNAL(type)
Define an internal function for /src/afw/ source*.c files.
Adaptive Framework Core Internal.
struct afw_xctx_qualifier_stack_entry_s afw_xctx_qualifier_stack_entry_t
Typedef for xctx qualifier stack entry.
struct afw_xctx_evaluation_stack_entry_s afw_xctx_evaluation_stack_entry_t
struct afw_xctx_internal_qualifier_stack_s afw_xctx_qualifier_stack_t
Typedef for xctx qualifier stack.
_Bool afw_boolean_t
Definition: afw_common.h:373
struct afw_xctx_evaluation_stack_s afw_xctx_evaluation_stack_t
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
#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_pool_malloc(instance, size, xctx)
Call method malloc of interface afw_pool.
#define afw_pool_calloc(instance, size, xctx)
Call method calloc of interface afw_pool.
#define afw_pool_get_apr_pool(instance)
Call method get_apr_pool of interface afw_pool.
#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_stack_internal_set_qualifier_stack(afw_xctx_t *xctx)
Definition: afw_stack.c:31
afw_stack_copy_impl(afw_stack_t *instance, afw_size_t *count, const void ***ptr, const afw_pool_t *p, afw_xctx_t *xctx)
Copy stack implementation.
Definition: afw_stack.c:148
afw_stack_create_impl(afw_size_t entry_size, afw_size_t initial_count, afw_size_t maximum_count, afw_boolean_t create_subpool_pool, const afw_pool_t *p, afw_xctx_t *xctx)
Create a stack implementation.
Definition: afw_stack.c:99
afw_stack_release_impl(afw_stack_t *instance, afw_xctx_t *xctx)
Release stack implementation.
Definition: afw_stack.c:131
afw_stack_extend_impl(afw_stack_t *instance, afw_xctx_t *xctx)
Extend stack implementation.
Definition: afw_stack.c:176
afw_size_t evaluation_stack_maximum_count
maximum_count used to create xctx's evaluation stack.
Definition: afw_common.h:1458
afw_size_t evaluation_stack_initial_count
initial_count used to create xctx's evaluation stack.
Definition: afw_common.h:1455
Interface afw_pool public struct.
Struct for afw_stack_t typedef.
Definition: afw_common.h:669
Interface afw_xctx public struct.