diff --git a/deps/ox/src/ox/fs/CMakeLists.txt b/deps/ox/src/ox/fs/CMakeLists.txt index 08fc5f97..7437dac3 100644 --- a/deps/ox/src/ox/fs/CMakeLists.txt +++ b/deps/ox/src/ox/fs/CMakeLists.txt @@ -35,6 +35,14 @@ install( include/ox/fs ) +install( + FILES + filestore/linkedlist.hpp + filestore/ptr.hpp + DESTINATION + include/ox/fs/filestore +) + install( FILES filesystem/filesystem.hpp diff --git a/deps/ox/src/ox/fs/filestore/linkedlist.hpp b/deps/ox/src/ox/fs/filestore/linkedlist.hpp new file mode 100644 index 00000000..06c793f0 --- /dev/null +++ b/deps/ox/src/ox/fs/filestore/linkedlist.hpp @@ -0,0 +1,138 @@ +/* + * Copyright 2015 - 2018 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "ptr.hpp" + +namespace ox { +namespace fs { + +template +class LinkedList { + + private: + struct Header { + ox::LittleEndian size = sizeof(Header); + ox::LittleEndian firstItem = 0; + }; + + struct Item { + ox::LittleEndian size = sizeof(Item); + ox::LittleEndian prev = 0; + ox::LittleEndian next = 0; + + Item(size_t size) { + this->size = size; + } + }; + + struct ItemPtr: public ox::fs::Ptr { + inline ItemPtr(void *dataStart, void *dataEnd, size_t itemOffset, size_t size): + Ptr(dataStart, dataEnd, itemOffset, size) {} + + inline ItemPtr(void *dataStart, void *dataEnd, size_t itemOffset) { + // make sure this can be read as an Item, and then use Item::size for the size + uint8_t *itemStart = static_cast(dataStart) + itemOffset; + if (static_cast(dataEnd) - itemStart >= static_cast(sizeof(Item))) { + auto item = (Item*) (static_cast(dataStart) + itemOffset); + ItemPtr(dataStart, dataEnd, itemOffset, item->size); + } else { + ItemPtr(dataStart, dataEnd, 0, 0); + } + } + }; + + Header m_header; + + public: + ItemPtr firstItem(); + + ItemPtr prev(Item *item); + + ItemPtr next(Item *item); + + ItemPtr ptr(size_t offset); + + ItemPtr ptr(uint8_t *item); + + //private: + ItemPtr malloc(size_t size); + + void compact(void (*cb)(ItemPtr itemMoved)); + + uint8_t *data(); + +}; + +template +typename LinkedList::ItemPtr LinkedList::firstItem() { + return ptr(m_header.firstItem); +} + +template +typename LinkedList::ItemPtr LinkedList::prev(Item *item) { + return ptr(item->prev); +} + +template +typename LinkedList::ItemPtr LinkedList::next(Item *item) { + return ptr(item->next); +} + +template +typename LinkedList::ItemPtr LinkedList::ptr(size_t offset) { + return ItemPtr(this, this + 1, offset); +} + +template +typename LinkedList::ItemPtr LinkedList::ptr(uint8_t *item) { + return ItemPtr(this, this + 1, reinterpret_cast(static_cast(item - static_cast(this)))); +} + +template +typename LinkedList::ItemPtr LinkedList::malloc(size_t size) { + auto out = ItemPtr(this, this + 1, 0, size); + if (out.valid()) { + new (out) Item(size); + } + return out; +} + +template +void LinkedList::compact(void (*cb)(ItemPtr)) { + auto src = ptr(firstItem()); + auto dest = data(); + while (src.valid()) { + // move node + ox_memcpy(dest, src, src.size()); + if (cb) { + cb(ptr(dest)); + } + // update surrounding nodes + auto prev = ptr(dest->next); + if (prev) { + prev->next = dest; + } + auto next = ptr(dest->next); + if (next) { + next->prev = dest; + } + // update iterators + src = ptr(dest->next); + dest += ptr(dest)->size; + } +} + +template +uint8_t *LinkedList::data() { + return reinterpret_cast(this + 1); +} + +} +} diff --git a/deps/ox/src/ox/fs/filestore/ptr.hpp b/deps/ox/src/ox/fs/filestore/ptr.hpp new file mode 100644 index 00000000..4d397150 --- /dev/null +++ b/deps/ox/src/ox/fs/filestore/ptr.hpp @@ -0,0 +1,116 @@ +/* + * Copyright 2015 - 2018 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include + +namespace ox { +namespace fs { + +template +class Ptr { + + private: + uint8_t *m_dataStart = nullptr; + uint8_t *m_dataEnd = nullptr; + size_t m_itemOffset = 0; + size_t m_itemSize = 0; + + public: + inline Ptr() = default; + + inline Ptr(void *dataStart, void *dataEnd, size_t itemOffset, size_t itemSize = sizeof(T)) { + // do some sanity checks before assuming this is valid + if (itemSize >= sizeof(T) and + m_dataStart and + m_dataStart < m_dataEnd and + m_dataStart + m_itemOffset + m_itemSize < m_dataEnd) { + m_dataStart = static_cast(dataStart); + m_dataEnd = static_cast(dataEnd); + m_itemOffset = itemOffset; + m_itemSize = itemSize; + } + } + + inline Ptr(void *dataStart, void *dataEnd, void *item, size_t itemSize = sizeof(T)) { + Ptr(dataStart, dataEnd, reinterpret_cast(static_cast(item) - static_cast(dataStart)), itemSize); + } + + inline bool valid() const; + + inline size_t size() const; + + inline size_t offset() const; + + inline T *operator->() const; + + inline operator T*() const; + + inline operator size_t() const; + + inline T &operator*() const; + + inline Ptr &operator=(size_t offset); + + inline Ptr &operator+=(size_t offset); + +}; + +template +inline bool Ptr::valid() const { + return m_dataStart and m_itemOffset; +} + +template +inline size_t Ptr::size() const { + return m_itemSize; +} + +template +inline size_t Ptr::offset() const { + return m_itemOffset; +} + +template +inline T *Ptr::operator->() const { + return (T*) m_dataStart + m_itemOffset; +} + +template +inline Ptr::operator T*() const { + return (T*) m_dataStart + m_itemOffset; +} + +template +inline Ptr::operator size_t() const { + if (valid()) { + return m_itemOffset; + } + return 0; +} + +template +inline T &Ptr::operator*() const { + return *static_cast(this); +} + +template +inline Ptr &Ptr::operator=(size_t offset) { + m_itemOffset = offset; + return *this; +} + +template +inline Ptr &Ptr::operator+=(size_t offset) { + m_itemOffset += offset; + return *this; +} + +} +} diff --git a/deps/ox/src/ox/fs/test/tests.cpp b/deps/ox/src/ox/fs/test/tests.cpp index 3686d4c8..ea7f9304 100644 --- a/deps/ox/src/ox/fs/test/tests.cpp +++ b/deps/ox/src/ox/fs/test/tests.cpp @@ -13,6 +13,7 @@ #include #include #include +#include using namespace std; using namespace ox; @@ -326,6 +327,15 @@ map tests = { return retval; } }, + { + "LinkedList::insert", + [](string) { + ox::fs::LinkedList list; + list.malloc(50); + list.firstItem(); + return 0; + } + }, }, }; diff --git a/deps/ox/src/ox/std/byteswap.hpp b/deps/ox/src/ox/std/byteswap.hpp index 08dcf9bb..520443bb 100644 --- a/deps/ox/src/ox/std/byteswap.hpp +++ b/deps/ox/src/ox/std/byteswap.hpp @@ -12,6 +12,10 @@ namespace ox { +inline int8_t byteSwap(int8_t i) { + return i; +} + inline int16_t byteSwap(int16_t i) { return (i << 8) | (i >> 8); } @@ -34,6 +38,10 @@ inline int64_t byteSwap(int64_t i) { ((i << 56) & 0xff00000000000000); } +inline uint16_t byteSwap(uint8_t i) { + return i; +} + inline uint16_t byteSwap(uint16_t i) { return (i << 8) | (i >> 8); } @@ -99,6 +107,70 @@ class LittleEndian { return value != ox::bigEndianAdapt(m_value); } + inline T operator+(T value) const { + return ox::bigEndianAdapt(m_value) + value; + } + + inline T operator+=(T other) { + auto newVal = *this + other; + m_value = ox::bigEndianAdapt(newVal); + return newVal; + } + + inline T operator-(T value) { + return ox::bigEndianAdapt(m_value) - value; + } + + inline T operator-=(T other) { + auto newVal = *this - other; + m_value = ox::bigEndianAdapt(newVal); + return newVal; + } + + inline T operator*(T value) { + return ox::bigEndianAdapt(m_value) * value; + } + + inline T operator*=(T other) { + auto newVal = *this * other; + m_value = ox::bigEndianAdapt(newVal); + return newVal; + } + + inline T operator/(T value) { + return ox::bigEndianAdapt(m_value) / value; + } + + inline T operator/=(T other) { + auto newVal = *this / other; + m_value = ox::bigEndianAdapt(newVal); + return newVal; + } + + // Prefix increment + inline T &operator++() { + return operator+=(1); + } + + // Postfix increment + inline T operator++(int) { + auto old = *this; + ++*this; + return old; + } + + // Prefix decrement + inline T &operator--() { + return operator-=(1); + } + + // Postfix decrement + inline T operator--(int) { + auto old = *this; + --*this; + return old; + } + }; } diff --git a/deps/ox/src/ox/std/memops.hpp b/deps/ox/src/ox/std/memops.hpp index 6de393af..21232910 100644 --- a/deps/ox/src/ox/std/memops.hpp +++ b/deps/ox/src/ox/std/memops.hpp @@ -11,6 +11,6 @@ int ox_memcmp(const void *ptr1, const void *ptr2, size_t size); -void *ox_memcpy(void *src, const void *dest, int64_t size); +void *ox_memcpy(void *dest, const void *src, int64_t size); void *ox_memset(void *ptr, int val, int64_t size);