From e1305a240ef607bd4e0077e1cfe6f06efdf05583 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 5 Mar 2018 20:22:26 -0600 Subject: [PATCH] Start on new FileStore and add test --- deps/ox/src/ox/fs/filestore/filestore.hpp | 51 ++++++++++ .../src/ox/fs/filestore/filestoretemplate.hpp | 98 +++++++++++++++++++ deps/ox/src/ox/fs/filestore/linkedlist.hpp | 75 ++++++++------ deps/ox/src/ox/fs/filestore/ptr.hpp | 54 +++++----- deps/ox/src/ox/fs/test/CMakeLists.txt | 2 + deps/ox/src/ox/fs/test/tests.cpp | 11 ++- deps/ox/src/ox/std/byteswap.hpp | 10 +- deps/ox/src/ox/std/types.hpp | 34 ++++--- 8 files changed, 258 insertions(+), 77 deletions(-) create mode 100644 deps/ox/src/ox/fs/filestore/filestore.hpp create mode 100644 deps/ox/src/ox/fs/filestore/filestoretemplate.hpp diff --git a/deps/ox/src/ox/fs/filestore/filestore.hpp b/deps/ox/src/ox/fs/filestore/filestore.hpp new file mode 100644 index 00000000..a3c6d938 --- /dev/null +++ b/deps/ox/src/ox/fs/filestore/filestore.hpp @@ -0,0 +1,51 @@ +/* + * 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 "linkedlist.hpp" + +namespace ox::fs { + +using InodeId_t = uintptr_t; + +class FileStore { + + public: + struct StatInfo { + InodeId_t inodeId; + InodeId_t links; + InodeId_t size; + uint8_t fileType; + }; + + virtual bool valid(InodeId_t size) = 0; + + virtual void resize(InodeId_t size = 0) = 0; + + virtual Error write(InodeId_t id, void *data, InodeId_t dataLen, uint8_t fileType = 0) = 0; + + virtual Error incLinks(InodeId_t id) = 0; + + virtual Error decLinks(InodeId_t id) = 0; + + virtual Error read(InodeId_t id, void *data, InodeId_t *size) = 0; + + virtual Error read(InodeId_t id, InodeId_t readStart, InodeId_t readSize, void *data, InodeId_t *size) = 0; + + virtual StatInfo stat(InodeId_t id) = 0; + + virtual InodeId_t spaceNeeded(InodeId_t size) = 0; + + virtual InodeId_t size() = 0; + + virtual InodeId_t available() = 0; + +}; + +} diff --git a/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp b/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp new file mode 100644 index 00000000..edc53e19 --- /dev/null +++ b/deps/ox/src/ox/fs/filestore/filestoretemplate.hpp @@ -0,0 +1,98 @@ +/* + * 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 "filestore.hpp" +#include "linkedlist.hpp" + +namespace ox::fs { + +template +class FileStoreTemplate: public FileStore { + + private: + ox::fs::LinkedList *m_linkedList = nullptr; + + public: + FileStoreTemplate(void *buff); + + bool valid(InodeId_t size); + + void resize(InodeId_t size = 0); + + Error write(InodeId_t id, void *data, InodeId_t dataLen, uint8_t fileType = 0); + + Error incLinks(InodeId_t id); + + Error decLinks(InodeId_t id); + + Error read(InodeId_t id, void *data, InodeId_t *size); + + Error read(InodeId_t id, InodeId_t readStart, InodeId_t readSize, void *data, InodeId_t *size); + + StatInfo stat(InodeId_t id); + + InodeId_t spaceNeeded(InodeId_t size); + + InodeId_t size(); + + InodeId_t available(); + +}; + +template +FileStoreTemplate::FileStoreTemplate(void *buff) { + m_linkedList = static_cast*>(buff); +} + +template +bool FileStoreTemplate::valid(size_t size) { + return false; +} + +void FileStoreTemplate::resize(InodeId_t size = 0) { +} + +Error FileStoreTemplate::write(InodeId_t id, void *data, InodeId_t dataLen, uint8_t fileType = 0) { + return 1; +} + +Error FileStoreTemplate::incLinks(InodeId_t id) { + return 1; +} + +Error FileStoreTemplate::decLinks(InodeId_t id) { + return 1; +} + +Error FileStoreTemplate::read(InodeId_t id, void *data, InodeId_t *size) { + return 1; +} + +Error FileStoreTemplate::read(InodeId_t id, InodeId_t readStart, InodeId_t readSize, void *data, InodeId_t *size) { + return 1; +} + +StatInfo FileStoreTemplate::stat(InodeId_t id) { + return {}; +} + +InodeId_t FileStoreTemplate::spaceNeeded(InodeId_t size) { + return 1; +} + +InodeId_t FileStoreTemplate::size() { + return 1; +} + +InodeId_t FileStoreTemplate::available() { + return 1; +} + +} diff --git a/deps/ox/src/ox/fs/filestore/linkedlist.hpp b/deps/ox/src/ox/fs/filestore/linkedlist.hpp index 06c793f0..6dd4b1db 100644 --- a/deps/ox/src/ox/fs/filestore/linkedlist.hpp +++ b/deps/ox/src/ox/fs/filestore/linkedlist.hpp @@ -10,40 +10,46 @@ #include "ptr.hpp" -namespace ox { -namespace fs { +namespace ox::fs { template -class LinkedList { +class __attribute__((packed)) LinkedList { + + public: + struct __attribute__((packed)) Item { + friend LinkedList; + + public: + ox::LittleEndian size = sizeof(Item); + + protected: + ox::LittleEndian prev = 0; + ox::LittleEndian next = 0; + + explicit Item(size_t size) { + this->size = size; + } + }; private: - struct Header { + struct __attribute__((packed)) 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, size_t dataSize, size_t itemOffset, size_t size): + Ptr(dataStart, dataSize, itemOffset, size) { + } - inline ItemPtr(void *dataStart, void *dataEnd, size_t itemOffset) { + inline ItemPtr(void *dataStart, size_t dataSize, 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); + auto itemSpace = dataSize - itemOffset; + auto item = reinterpret_cast(static_cast(dataStart) + itemOffset); + if (itemSpace >= static_cast(sizeof(Item)) and itemSpace >= item->size) { + this->init(dataStart, dataSize, itemOffset, item->size); } else { - ItemPtr(dataStart, dataEnd, 0, 0); + this->init(dataStart, dataSize, 0, 0); } } }; @@ -51,6 +57,10 @@ class LinkedList { Header m_header; public: + LinkedList() = default; + + explicit LinkedList(size_t size); + ItemPtr firstItem(); ItemPtr prev(Item *item); @@ -61,15 +71,22 @@ class LinkedList { ItemPtr ptr(uint8_t *item); - //private: ItemPtr malloc(size_t size); + void free(ItemPtr item); + + private: void compact(void (*cb)(ItemPtr itemMoved)); uint8_t *data(); }; +template +LinkedList::LinkedList(size_t size) { + m_header.size = size; +} + template typename LinkedList::ItemPtr LinkedList::firstItem() { return ptr(m_header.firstItem); @@ -87,17 +104,20 @@ typename LinkedList::ItemPtr LinkedList::next(Item *item) { template typename LinkedList::ItemPtr LinkedList::ptr(size_t offset) { - return ItemPtr(this, this + 1, offset); + return ItemPtr(this, m_header.size, offset); } template typename LinkedList::ItemPtr LinkedList::ptr(uint8_t *item) { - return ItemPtr(this, this + 1, reinterpret_cast(static_cast(item - static_cast(this)))); + return ItemPtr(this, m_header.size, reinterpret_cast(item - static_cast(this))); } template typename LinkedList::ItemPtr LinkedList::malloc(size_t size) { - auto out = ItemPtr(this, this + 1, 0, size); + if (!m_header.firstItem) { + m_header.firstItem = sizeof(m_header); + } + auto out = ItemPtr(this, m_header.size, m_header.firstItem, size); if (out.valid()) { new (out) Item(size); } @@ -106,7 +126,7 @@ typename LinkedList::ItemPtr LinkedList::malloc(size_t size) { template void LinkedList::compact(void (*cb)(ItemPtr)) { - auto src = ptr(firstItem()); + auto src = firstItem(); auto dest = data(); while (src.valid()) { // move node @@ -135,4 +155,3 @@ uint8_t *LinkedList::data() { } } -} diff --git a/deps/ox/src/ox/fs/filestore/ptr.hpp b/deps/ox/src/ox/fs/filestore/ptr.hpp index 4d397150..5e453247 100644 --- a/deps/ox/src/ox/fs/filestore/ptr.hpp +++ b/deps/ox/src/ox/fs/filestore/ptr.hpp @@ -18,29 +18,13 @@ class Ptr { private: uint8_t *m_dataStart = nullptr; - uint8_t *m_dataEnd = nullptr; - size_t m_itemOffset = 0; + size_t m_itemStart = 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 Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize = sizeof(T)); inline bool valid() const; @@ -60,11 +44,19 @@ class Ptr { inline Ptr &operator+=(size_t offset); + protected: + void init(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize); + }; +template +inline Ptr::Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize) { + init(dataStart, dataSize, itemStart, itemSize); +} + template inline bool Ptr::valid() const { - return m_dataStart and m_itemOffset; + return m_dataStart and m_itemStart; } template @@ -74,23 +66,23 @@ inline size_t Ptr::size() const { template inline size_t Ptr::offset() const { - return m_itemOffset; + return m_itemStart; } template inline T *Ptr::operator->() const { - return (T*) m_dataStart + m_itemOffset; + return reinterpret_cast(m_dataStart + m_itemStart); } template inline Ptr::operator T*() const { - return (T*) m_dataStart + m_itemOffset; + return reinterpret_cast(m_dataStart + m_itemStart); } template inline Ptr::operator size_t() const { if (valid()) { - return m_itemOffset; + return m_itemStart; } return 0; } @@ -102,15 +94,27 @@ inline T &Ptr::operator*() const { template inline Ptr &Ptr::operator=(size_t offset) { - m_itemOffset = offset; + m_itemStart = offset; return *this; } template inline Ptr &Ptr::operator+=(size_t offset) { - m_itemOffset += offset; + m_itemStart += offset; return *this; } +template +void Ptr::init(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize) { + // do some sanity checks before assuming this is valid + if (itemSize >= sizeof(T) and + dataStart and + itemStart + itemSize <= dataSize) { + m_dataStart = static_cast(dataStart); + m_itemStart = itemStart; + m_itemSize = itemSize; + } +} + } } diff --git a/deps/ox/src/ox/fs/test/CMakeLists.txt b/deps/ox/src/ox/fs/test/CMakeLists.txt index a6205cfb..dfc796a0 100644 --- a/deps/ox/src/ox/fs/test/CMakeLists.txt +++ b/deps/ox/src/ox/fs/test/CMakeLists.txt @@ -67,3 +67,5 @@ add_test("Test\\ FileSystem32::remove\\(string,\\ true\\)" FSTests "FileSystem32 add_test("Test\\ FileSystem32::move" FSTests "FileSystem32::move") add_test("Test\\ FileSystem32::stripDirectories" FSTests "FileSystem32::stripDirectories") add_test("Test\\ FileSystem32::ls" FSTests "FileSystem32::ls") + +add_test("Test\\ LinkedList::insert" FSTests "LinkedList::insert") diff --git a/deps/ox/src/ox/fs/test/tests.cpp b/deps/ox/src/ox/fs/test/tests.cpp index ea7f9304..88d74fea 100644 --- a/deps/ox/src/ox/fs/test/tests.cpp +++ b/deps/ox/src/ox/fs/test/tests.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include using namespace std; using namespace ox; @@ -330,9 +330,12 @@ map tests = { { "LinkedList::insert", [](string) { - ox::fs::LinkedList list; - list.malloc(50); - list.firstItem(); + constexpr auto buffLen = 5000; + uint8_t buff[buffLen]; + auto list = new (buff) ox::fs::LinkedList(buffLen); + assert(list->malloc(50).valid()); + assert(list->firstItem().valid()); + assert(list->firstItem()->size == 50); return 0; } }, diff --git a/deps/ox/src/ox/std/byteswap.hpp b/deps/ox/src/ox/std/byteswap.hpp index 6c595fff..8b648312 100644 --- a/deps/ox/src/ox/std/byteswap.hpp +++ b/deps/ox/src/ox/std/byteswap.hpp @@ -79,7 +79,7 @@ inline T bigEndianAdapt(T i) { template -class LittleEndian { +class __attribute__((packed)) LittleEndian { private: T m_value; @@ -99,14 +99,6 @@ class LittleEndian { return ox::bigEndianAdapt(m_value); } - inline bool operator==(T value) { - return value == ox::bigEndianAdapt(m_value); - } - - inline bool operator!=(T value) { - return value != ox::bigEndianAdapt(m_value); - } - inline T operator+(T value) const { return ox::bigEndianAdapt(m_value) + value; } diff --git a/deps/ox/src/ox/std/types.hpp b/deps/ox/src/ox/std/types.hpp index 7c768d58..2412d231 100644 --- a/deps/ox/src/ox/std/types.hpp +++ b/deps/ox/src/ox/std/types.hpp @@ -25,18 +25,10 @@ typedef long int64_t; typedef unsigned long uint64_t; typedef int64_t intmax_t; typedef uint64_t uintmax_t; +typedef int64_t intptr_t; +typedef uint64_t uintptr_t; #endif -static_assert(sizeof(int8_t) == 1, "int8_t is wrong size"); -static_assert(sizeof(int16_t) == 2, "int16_t is wrong size"); -static_assert(sizeof(int32_t) == 4, "int32_t is wrong size"); -static_assert(sizeof(int64_t) == 8, "int64_t is wrong size"); - -static_assert(sizeof(uint8_t) == 1, "uint8_t is wrong size"); -static_assert(sizeof(uint16_t) == 2, "uint16_t is wrong size"); -static_assert(sizeof(uint32_t) == 4, "uint32_t is wrong size"); -static_assert(sizeof(uint64_t) == 8, "uint64_t is wrong size"); - namespace ox { typedef uint32_t Error; @@ -45,10 +37,30 @@ typedef uint32_t Error; #if defined(_LP64) || defined(__ppc64__) || defined(__aarch64__) typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; #elif defined(_WIN64) typedef uint64_t size_t; +typedef int64_t intptr_t; +typedef uint64_t uintptr_t; #elif defined(_LP32) || defined(__ppc__) || defined(_WIN32) || defined(__arm__) typedef uint32_t size_t; +typedef int32_t intptr_t; +typedef uint32_t uintptr_t; #else -#error size_t undefined +#error size_t, intptr_t, and uintptr_t undefined #endif + +static_assert(sizeof(int8_t) == 1, "int8_t is wrong size"); +static_assert(sizeof(int16_t) == 2, "int16_t is wrong size"); +static_assert(sizeof(int32_t) == 4, "int32_t is wrong size"); +static_assert(sizeof(int64_t) == 8, "int64_t is wrong size"); +static_assert(sizeof(intptr_t) == sizeof(void*), "intptr_t is wrong size"); + +static_assert(sizeof(uint8_t) == 1, "uint8_t is wrong size"); +static_assert(sizeof(uint16_t) == 2, "uint16_t is wrong size"); +static_assert(sizeof(uint32_t) == 4, "uint32_t is wrong size"); +static_assert(sizeof(uint64_t) == 8, "uint64_t is wrong size"); +static_assert(sizeof(uintptr_t) == sizeof(void*), "uintptr_t is wrong size"); + +static_assert(sizeof(size_t) == sizeof(void*), "size_t is wrong size");