20#include <winpr/config.h>
22#include <winpr/collections.h>
23#include <winpr/assert.h>
48size_t Stack_Count(wStack* stack)
52 if (stack->synchronized)
53 EnterCriticalSection(&stack->lock);
57 if (stack->synchronized)
58 LeaveCriticalSection(&stack->lock);
67BOOL Stack_IsSynchronized(wStack* stack)
70 return stack->synchronized;
73wObject* Stack_Object(wStack* stack)
76 return &stack->object;
87void Stack_Clear(wStack* stack)
90 if (stack->synchronized)
91 EnterCriticalSection(&stack->lock);
93 for (
size_t index = 0; index < stack->size; index++)
95 if (stack->object.fnObjectFree)
96 stack->object.fnObjectFree(stack->array[index]);
98 stack->array[index] = NULL;
103 if (stack->synchronized)
104 LeaveCriticalSection(&stack->lock);
111BOOL Stack_Contains(wStack* stack,
const void* obj)
116 if (stack->synchronized)
117 EnterCriticalSection(&stack->lock);
119 for (
size_t i = 0; i < stack->size; i++)
121 if (stack->object.fnObjectEquals(stack->array[i], obj))
128 if (stack->synchronized)
129 LeaveCriticalSection(&stack->lock);
138void Stack_Push(wStack* stack,
void* obj)
141 if (stack->synchronized)
142 EnterCriticalSection(&stack->lock);
144 WINPR_ASSERT(stack->size < SIZE_MAX);
145 if ((stack->size + 1ull) >= stack->capacity)
147 size_t new_cap = stack->capacity;
150 WINPR_ASSERT(new_cap <= SIZE_MAX - 128ull);
152 }
while (new_cap <= stack->size + 1ull);
153 void** new_arr = (
void**)realloc((
void*)stack->array,
sizeof(
void*) * new_cap);
158 stack->array = new_arr;
159 stack->capacity = new_cap;
162 stack->array[(stack->size)++] = obj;
165 if (stack->synchronized)
166 LeaveCriticalSection(&stack->lock);
173void* Stack_Pop(wStack* stack)
178 if (stack->synchronized)
179 EnterCriticalSection(&stack->lock);
182 obj = stack->array[--(stack->size)];
184 if (stack->synchronized)
185 LeaveCriticalSection(&stack->lock);
194void* Stack_Peek(wStack* stack)
199 if (stack->synchronized)
200 EnterCriticalSection(&stack->lock);
203 obj = stack->array[stack->size - 1];
205 if (stack->synchronized)
206 LeaveCriticalSection(&stack->lock);
211static BOOL default_stack_equals(
const void* obj1,
const void* obj2)
213 return (obj1 == obj2);
220wStack* Stack_New(BOOL
synchronized)
222 wStack* stack = NULL;
223 stack = (wStack*)calloc(1,
sizeof(wStack));
228 stack->object.fnObjectEquals = default_stack_equals;
229 stack->synchronized =
synchronized;
230 stack->capacity = 32;
231 stack->array = (
void**)calloc(stack->capacity,
sizeof(
void*));
236 if (stack->synchronized && !InitializeCriticalSectionAndSpinCount(&stack->lock, 4000))
241 WINPR_PRAGMA_DIAG_PUSH
242 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
244 WINPR_PRAGMA_DIAG_POP
248void Stack_Free(wStack* stack)
252 if (stack->synchronized)
253 DeleteCriticalSection(&stack->lock);
255 free((
void*)stack->array);
This struct contains function pointer to initialize/free objects.