FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
Stack.c
1
20#include <winpr/config.h>
21
22#include <winpr/collections.h>
23#include <winpr/assert.h>
24
25struct s_wStack
26{
27 size_t size;
28 size_t capacity;
29 void** array;
31 BOOL synchronized;
32 wObject object;
33};
34
48size_t Stack_Count(wStack* stack)
49{
50 size_t ret = 0;
51 WINPR_ASSERT(stack);
52 if (stack->synchronized)
53 EnterCriticalSection(&stack->lock);
54
55 ret = stack->size;
56
57 if (stack->synchronized)
58 LeaveCriticalSection(&stack->lock);
59
60 return ret;
61}
62
67BOOL Stack_IsSynchronized(wStack* stack)
68{
69 WINPR_ASSERT(stack);
70 return stack->synchronized;
71}
72
73wObject* Stack_Object(wStack* stack)
74{
75 WINPR_ASSERT(stack);
76 return &stack->object;
77}
78
87void Stack_Clear(wStack* stack)
88{
89 WINPR_ASSERT(stack);
90 if (stack->synchronized)
91 EnterCriticalSection(&stack->lock);
92
93 for (size_t index = 0; index < stack->size; index++)
94 {
95 if (stack->object.fnObjectFree)
96 stack->object.fnObjectFree(stack->array[index]);
97
98 stack->array[index] = NULL;
99 }
100
101 stack->size = 0;
102
103 if (stack->synchronized)
104 LeaveCriticalSection(&stack->lock);
105}
106
111BOOL Stack_Contains(wStack* stack, const void* obj)
112{
113 BOOL found = FALSE;
114
115 WINPR_ASSERT(stack);
116 if (stack->synchronized)
117 EnterCriticalSection(&stack->lock);
118
119 for (size_t i = 0; i < stack->size; i++)
120 {
121 if (stack->object.fnObjectEquals(stack->array[i], obj))
122 {
123 found = TRUE;
124 break;
125 }
126 }
127
128 if (stack->synchronized)
129 LeaveCriticalSection(&stack->lock);
130
131 return found;
132}
133
138void Stack_Push(wStack* stack, void* obj)
139{
140 WINPR_ASSERT(stack);
141 if (stack->synchronized)
142 EnterCriticalSection(&stack->lock);
143
144 if ((stack->size + 1) >= stack->capacity)
145 {
146 const size_t new_cap = stack->capacity * 2;
147 void** new_arr = (void**)realloc((void*)stack->array, sizeof(void*) * new_cap);
148
149 if (!new_arr)
150 goto end;
151
152 stack->array = new_arr;
153 stack->capacity = new_cap;
154 }
155
156 stack->array[(stack->size)++] = obj;
157
158end:
159 if (stack->synchronized)
160 LeaveCriticalSection(&stack->lock);
161}
162
167void* Stack_Pop(wStack* stack)
168{
169 void* obj = NULL;
170
171 WINPR_ASSERT(stack);
172 if (stack->synchronized)
173 EnterCriticalSection(&stack->lock);
174
175 if (stack->size > 0)
176 obj = stack->array[--(stack->size)];
177
178 if (stack->synchronized)
179 LeaveCriticalSection(&stack->lock);
180
181 return obj;
182}
183
188void* Stack_Peek(wStack* stack)
189{
190 void* obj = NULL;
191
192 WINPR_ASSERT(stack);
193 if (stack->synchronized)
194 EnterCriticalSection(&stack->lock);
195
196 if (stack->size > 0)
197 obj = stack->array[stack->size - 1];
198
199 if (stack->synchronized)
200 LeaveCriticalSection(&stack->lock);
201
202 return obj;
203}
204
205static BOOL default_stack_equals(const void* obj1, const void* obj2)
206{
207 return (obj1 == obj2);
208}
209
214wStack* Stack_New(BOOL synchronized)
215{
216 wStack* stack = NULL;
217 stack = (wStack*)calloc(1, sizeof(wStack));
218
219 if (!stack)
220 return NULL;
221
222 stack->object.fnObjectEquals = default_stack_equals;
223 stack->synchronized = synchronized;
224 stack->capacity = 32;
225 stack->array = (void**)calloc(stack->capacity, sizeof(void*));
226
227 if (!stack->array)
228 goto out_free;
229
230 if (stack->synchronized && !InitializeCriticalSectionAndSpinCount(&stack->lock, 4000))
231 goto out_free;
232
233 return stack;
234out_free:
235 WINPR_PRAGMA_DIAG_PUSH
236 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
237 Stack_Free(stack);
238 WINPR_PRAGMA_DIAG_POP
239 return NULL;
240}
241
242void Stack_Free(wStack* stack)
243{
244 if (stack)
245 {
246 if (stack->synchronized)
247 DeleteCriticalSection(&stack->lock);
248
249 free((void*)stack->array);
250 free(stack);
251 }
252}
This struct contains function pointer to initialize/free objects.
Definition collections.h:57