initial commit
[cgds.git] / src / Stack.c
1 /**
2 * @file Stack.c
3 */
4
5 #include "cgds/Stack.h"
6
7 void _stack_init(Stack* stack, size_t dataSize)
8 {
9 stack->size = 0;
10 stack->dataSize = dataSize;
11 stack->top = NULL;
12 }
13
14 Stack* _stack_new(size_t dataSize)
15 {
16 Stack* stack = (Stack*) safe_malloc(sizeof (Stack));
17 _stack_init(stack, dataSize);
18 return stack;
19 }
20
21 Stack* stack_copy(Stack* stack)
22 {
23 // since a stack is a single-linked list, an auxiliary storage is required
24 void** tmpStorage = (void**) malloc(stack->size * sizeof (void*));
25 StackCell* stackCell = stack->top;
26 for (UInt i = 0; i < stack->size; i++)
27 {
28 tmpStorage[stack->size - 1 - i] = stackCell->data;
29 stackCell = stackCell->previous;
30 }
31 // now transfer tmpStorage contents (pushed in right order) in a new stack
32 Stack* stackCopy = _stack_new(stack->dataSize);
33 for (UInt i = 0; i < stack->size; i++)
34 _stack_push(stackCopy, tmpStorage[i]);
35 free(tmpStorage);
36 return stackCopy;
37 }
38
39 Bool stack_empty(Stack* stack)
40 {
41 return (stack->size == 0);
42 }
43
44 UInt stack_size(Stack* stack)
45 {
46 return stack->size;
47 }
48
49 void _stack_push(Stack* stack, void* data)
50 {
51 StackCell* newStackTop = (StackCell*) safe_malloc(sizeof (StackCell));
52 newStackTop->data = safe_malloc(stack->dataSize);
53 memcpy(newStackTop->data, data, stack->dataSize);
54 newStackTop->previous = stack->top;
55 stack->top = newStackTop;
56 stack->size++;
57 }
58
59 void* _stack_top(Stack* stack)
60 {
61 return stack->top->data;
62 }
63
64 void stack_pop(Stack* stack)
65 {
66 StackCell* toTrash = stack->top;
67 stack->top = stack->top->previous;
68 safe_free(toTrash->data);
69 safe_free(toTrash);
70 stack->size--;
71 }
72
73 void stack_clear(Stack* stack)
74 {
75 while (stack->size > 0)
76 stack_pop(stack);
77 _stack_init(stack, stack->dataSize);
78 }
79
80 void stack_destroy(Stack* stack)
81 {
82 stack_clear(stack);
83 safe_free(stack);
84 }