diff --git a/stack.cpp b/stack.cpp index 954a5a5..8e69614 100644 --- a/stack.cpp +++ b/stack.cpp @@ -1,48 +1,118 @@ #include "stack.hpp" #include - -// TODO: remove me -#define UNUSED(VAR) (void)(VAR) +#include +#include +#include namespace stack { + struct Node + { + std::size_t count; + Node* last; + std::size_t dataSize; + unsigned char* data; -Handle create() -{ - return -1; -} + Node(Node* last, unsigned char* data, const std::size_t dataSize) + { + this->count = 1; + if (last != nullptr) + { + this->count = last->count + 1; + } + this->dataSize = dataSize; + this->last = last; + this->data = data; + } -void destroy(const Handle handle) -{ - UNUSED(handle); -} + ~Node() + { + delete[] data; + } + }; -bool valid(const Handle handle) -{ - UNUSED(handle); - return false; -} + static Handle stackCount = 0; + static std::unordered_map stackDict; -std::size_t count(const Handle handle) -{ - UNUSED(handle); - return 0u; -} + Handle create() + { + stackDict[stackCount] = nullptr; + return stackCount++; + } -void push(const Handle handle, const void* const data, const std::size_t size) -{ - UNUSED(handle); - UNUSED(data); - UNUSED(size); -} + bool valid(const Handle handle) + { + return stackDict.find(handle) != stackDict.end(); + } -std::size_t pop(const Handle handle, void* const data, const std::size_t size) -{ - UNUSED(handle); - UNUSED(data); - UNUSED(size); - return 0u; -} + void destroy(const Handle handle) + { + if (valid(handle)) + { + Node* current = stackDict.find(handle)->second; + while (current != nullptr) + { + Node* prev = current->last; + delete current; + current = prev; + } + stackDict.erase(handle); + } + } + + std::size_t count(const Handle handle) + { + if (!valid(handle)) + { + return 0u; + } + + Node* head = stackDict.find(handle)->second; + if (head == nullptr) + { + return 0u; + } + + return head->count; + } + + void push(const Handle handle, const void* const data, const std::size_t size) + { + const auto stack = stackDict.find(handle); + if (stack == stackDict.end() || data == nullptr || size <= 0u) + { + return; + } + + Node* lastHead = stack->second; + + unsigned char* buf = new unsigned char[size]; + std::memcpy(buf, data, size); + + Node* newNode = new Node(lastHead, buf, size); + stackDict[handle] = newNode; + } + + std::size_t pop(const Handle handle, void* const data, const std::size_t size) + { + if (!valid(handle) || data == nullptr || size <= 0u) + { + return 0u; + } + + const Node* head = stackDict.find(handle)->second; + if (head == nullptr || head->dataSize > size) + { + return 0u; + } + + stackDict[handle] = head->last; + + const std::size_t copySize = head->dataSize; + std::memcpy(data, head->data, copySize); -} // namespace stack + delete head; + return copySize; + } +} // namespace stack \ No newline at end of file