FreeRDP
Loading...
Searching...
No Matches
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 WINPR_ASSERT(stack->size < SIZE_MAX);
145 if ((stack->size + 1ull) >= stack->capacity)
146 {
147 size_t new_cap = stack->capacity;
148 do
149 {
150 WINPR_ASSERT(new_cap <= SIZE_MAX - 128ull);
151 new_cap += 128ull;
152 } while (new_cap <= stack->size + 1ull);
153 void** new_arr = (void**)realloc((void*)stack->array, sizeof(void*) * new_cap);
154
155 if (!new_arr)
156 goto end;
157
158 stack->array = new_arr;
159 stack->capacity = new_cap;
160 }
161
162 stack->array[(stack->size)++] = obj;
163
164end:
165 if (stack->synchronized)
166 LeaveCriticalSection(&stack->lock);
167}
168
173void* Stack_Pop(wStack* stack)
174{
175 void* obj = NULL;
176
177 WINPR_ASSERT(stack);
178 if (stack->synchronized)
179 EnterCriticalSection(&stack->lock);
180
181 if (stack->size > 0)
182 obj = stack->array[--(stack->size)];
183
184 if (stack->synchronized)
185 LeaveCriticalSection(&stack->lock);
186
187 return obj;
188}
189
194void* Stack_Peek(wStack* stack)
195{
196 void* obj = NULL;
197
198 WINPR_ASSERT(stack);
199 if (stack->synchronized)
200 EnterCriticalSection(&stack->lock);
201
202 if (stack->size > 0)
203 obj = stack->array[stack->size - 1];
204
205 if (stack->synchronized)
206 LeaveCriticalSection(&stack->lock);
207
208 return obj;
209}
210
211static BOOL default_stack_equals(const void* obj1, const void* obj2)
212{
213 return (obj1 == obj2);
214}
215
220wStack* Stack_New(BOOL synchronized)
221{
222 wStack* stack = NULL;
223 stack = (wStack*)calloc(1, sizeof(wStack));
224
225 if (!stack)
226 return NULL;
227
228 stack->object.fnObjectEquals = default_stack_equals;
229 stack->synchronized = synchronized;
230 stack->capacity = 32;
231 stack->array = (void**)calloc(stack->capacity, sizeof(void*));
232
233 if (!stack->array)
234 goto out_free;
235
236 if (stack->synchronized && !InitializeCriticalSectionAndSpinCount(&stack->lock, 4000))
237 goto out_free;
238
239 return stack;
240out_free:
241 WINPR_PRAGMA_DIAG_PUSH
242 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
243 Stack_Free(stack);
244 WINPR_PRAGMA_DIAG_POP
245 return NULL;
246}
247
248void Stack_Free(wStack* stack)
249{
250 if (stack)
251 {
252 if (stack->synchronized)
253 DeleteCriticalSection(&stack->lock);
254
255 free((void*)stack->array);
256 free(stack);
257 }
258}
This struct contains function pointer to initialize/free objects.
Definition collections.h:52