Commit | Line | Data |
---|---|---|
a7868768 BA |
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 | } |