From 4c55409dc42563b150cba2a71672416ddd0f65da Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sun, 9 Apr 2017 08:30:21 -0500 Subject: [PATCH 01/45] Add endianness adapters to OxFS --- src/ox/fs/filestore.hpp | 56 +++++++++------- src/ox/std/CMakeLists.txt | 1 + src/ox/std/byteswap.cpp | 9 +++ src/ox/std/byteswap.hpp | 134 ++++++++++++++++++++++++++++++++++++++ src/ox/std/std.hpp | 1 + 5 files changed, 176 insertions(+), 25 deletions(-) create mode 100644 src/ox/std/byteswap.cpp create mode 100644 src/ox/std/byteswap.hpp diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 5a8402325..b971c0a4c 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -45,52 +45,52 @@ struct FileStoreHeader { template void FileStoreHeader::setVersion(uint16_t version) { - m_version = version; + m_version = std::toLittleEndian(version); } template uint16_t FileStoreHeader::getVersion() { - return m_version; + return std::nativizeLittleEndian(m_version); } template void FileStoreHeader::setFsType(uint16_t fsType) { - m_fsType = fsType; + m_fsType = std::toLittleEndian(fsType); } template uint16_t FileStoreHeader::getFsType() { - return m_fsType; + return std::nativizeLittleEndian(m_fsType); } template void FileStoreHeader::setSize(FsSize_t size) { - m_size = size; + m_size = std::toLittleEndian(size); } template FsSize_t FileStoreHeader::getSize() { - return m_size; + return std::nativizeLittleEndian(m_size); } template void FileStoreHeader::setMemUsed(FsSize_t memUsed) { - m_memUsed = memUsed; + m_memUsed = std::toLittleEndian(memUsed); } template FsSize_t FileStoreHeader::getMemUsed() { - return m_memUsed; + return std::nativizeLittleEndian(m_memUsed); } template void FileStoreHeader::setRootInode(FsSize_t rootInode) { - m_rootInode = rootInode; + m_rootInode = std::toLittleEndian(rootInode); } template FsSize_t FileStoreHeader::getRootInode() { - return m_rootInode; + return std::nativizeLittleEndian(m_rootInode); } template @@ -121,6 +121,7 @@ class FileStore { public: typename Header::FsSize_t size(); + void setDataLen(typename Header::FsSize_t); typename Header::FsSize_t getDataLen(); void setPrev(typename Header::FsSize_t); @@ -315,78 +316,83 @@ class FileStore { template typename Header::FsSize_t FileStore
::Inode::size() { - return sizeof(Inode) + m_dataLen; + return std::nativizeLittleEndian(sizeof(Inode) + getDataLen()); +} + +template +void FileStore
::Inode::setDataLen(typename Header::FsSize_t dataLen) { + this->m_dataLen = std::toLittleEndian(dataLen); } template typename Header::FsSize_t FileStore
::Inode::getDataLen() { - return this->m_dataLen; + return std::nativizeLittleEndian(this->m_dataLen); } template void FileStore
::Inode::setPrev(typename Header::FsSize_t prev) { - this->m_prev = prev; + this->m_prev = std::toLittleEndian(prev); } template typename Header::FsSize_t FileStore
::Inode::getPrev() { - return this->m_prev; + return std::nativizeLittleEndian(this->m_prev); } template void FileStore
::Inode::setNext(typename Header::FsSize_t next) { - this->m_next = next; + this->m_next = std::toLittleEndian(next); } template typename Header::FsSize_t FileStore
::Inode::getNext() { - return this->m_next; + return std::nativizeLittleEndian(this->m_next); } template void FileStore
::Inode::setId(InodeId_t id) { - this->m_id = id; + this->m_id = std::toLittleEndian(id); } template typename Header::InodeId_t FileStore
::Inode::getId() { - return this->m_id; + return std::nativizeLittleEndian(this->m_id); } template void FileStore
::Inode::setFileType(uint8_t fileType) { - this->m_fileType = fileType; + this->m_fileType = std::toLittleEndian(fileType); } template uint8_t FileStore
::Inode::getFileType() { - return this->m_fileType; + return std::nativizeLittleEndian(this->m_fileType); } template void FileStore
::Inode::setLeft(typename Header::FsSize_t left) { - this->m_left = left; + this->m_left = std::toLittleEndian(left); } template typename Header::FsSize_t FileStore
::Inode::getLeft() { - return this->m_left; + return std::nativizeLittleEndian(this->m_left); } template void FileStore
::Inode::setRight(typename Header::FsSize_t right) { - this->m_right = right; + this->m_right = std::toLittleEndian(right); } template typename Header::FsSize_t FileStore
::Inode::getRight() { - return this->m_right; + return std::nativizeLittleEndian(this->m_right); } template void FileStore
::Inode::setData(void *data, typename Header::FsSize_t size) { ox_memcpy(this->getData(), data, size); - m_dataLen = size; + setDataLen(size); } diff --git a/src/ox/std/CMakeLists.txt b/src/ox/std/CMakeLists.txt index f24ef2fdf..6c28d48a1 100644 --- a/src/ox/std/CMakeLists.txt +++ b/src/ox/std/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.8) add_library( OxStd + byteswap.cpp memops.cpp strops.cpp ) diff --git a/src/ox/std/byteswap.cpp b/src/ox/std/byteswap.cpp new file mode 100644 index 000000000..68801f3d6 --- /dev/null +++ b/src/ox/std/byteswap.cpp @@ -0,0 +1,9 @@ +/* + * Copyright 2015 - 2017 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/. + */ + +#include "byteswap.hpp" diff --git a/src/ox/std/byteswap.hpp b/src/ox/std/byteswap.hpp new file mode 100644 index 000000000..7d247e7a4 --- /dev/null +++ b/src/ox/std/byteswap.hpp @@ -0,0 +1,134 @@ +/* + * Copyright 2015 - 2017 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 "types.hpp" + +namespace ox { +namespace std { + +inline uint16_t byteSwap(uint16_t i) { + return (i << 8) | (i >> 8); +} + +inline uint32_t byteSwap(uint32_t i) { + return ((i >> 24) & 0x000000ff) | + ((i >> 8) & 0x0000ff00) | + ((i << 8) & 0x00ff0000) | + ((i << 24) & 0xff000000); +} + +inline uint64_t byteSwap(uint64_t i) { + return ((i >> 56) & 0x00000000000000ff) | + ((i >> 40) & 0x000000000000ff00) | + ((i >> 24) & 0x0000000000ff0000) | + ((i >> 8) & 0x00000000ff000000) | + ((i << 8) & 0x000000ff00000000) | + ((i << 24) & 0x0000ff0000000000) | + ((i << 40) & 0x00ff000000000000) | + ((i << 56) & 0xff00000000000000); +} + + +/** + * Takes a little endian int and byte swaps if the platform is big endian. + */ +inline uint8_t nativizeLittleEndian(uint8_t i) { + return i; +} + +/** + * Takes a little endian int and byte swaps if the platform is big endian. + */ +inline uint16_t nativizeLittleEndian(uint16_t i) { +#ifdef __BIG_ENDIAN__ + return byteSwap(i); +#else + return i; +#endif +} + +/** + * Takes a little endian int and byte swaps if the platform is big endian. + */ +inline uint32_t nativizeLittleEndian(uint32_t i) { +#ifdef __BIG_ENDIAN__ + return byteSwap(i); +#else + return i; +#endif +} + +/** + * Takes a little endian int and byte swaps if the platform is big endian. + */ +inline uint64_t nativizeLittleEndian(uint64_t i) { +#ifdef __BIG_ENDIAN__ + return byteSwap(i); +#else + return i; +#endif +} + + +inline uint8_t toLittleEndian(uint8_t i) { + return i; +} + +inline uint16_t toLittleEndian(uint16_t i) { +#ifdef __BIG_ENDIAN__ + return byteSwap(i); +#else + return i; +#endif +} + +inline uint32_t toLittleEndian(uint32_t i) { +#ifdef __BIG_ENDIAN__ + return byteSwap(i); +#else + return i; +#endif +} + +inline uint64_t toLittleEndian(uint64_t i) { +#ifdef __BIG_ENDIAN__ + return byteSwap(i); +#else + return i; +#endif +} + + +inline uint16_t toBigEndian(uint16_t i) { +#ifdef __LITTLE_ENDIAN__ + return byteSwap(i); +#else + return i; +#endif +} + +inline uint32_t toBigEndian(uint32_t i) { +#ifdef __LITTLE_ENDIAN__ + return byteSwap(i); +#else + return i; +#endif +} + +inline uint64_t toBigEndian(uint64_t i) { +#ifdef __LITTLE_ENDIAN__ + return byteSwap(i); +#else + return i; +#endif +} + +} +} diff --git a/src/ox/std/std.hpp b/src/ox/std/std.hpp index 7e7f1c9ca..823b00943 100644 --- a/src/ox/std/std.hpp +++ b/src/ox/std/std.hpp @@ -7,6 +7,7 @@ */ #pragma once +#include "byteswap.hpp" #include "memops.hpp" #include "strops.hpp" #include "types.hpp" From 4fdf5f48eb96c15e1b2bf1c66509ec1246210bae Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sun, 9 Apr 2017 15:55:39 -0500 Subject: [PATCH 02/45] Fix big endian reading of Inode size --- src/ox/fs/filestore.hpp | 2 +- src/ox/std/byteswap.hpp | 1 + src/ox/std/test/CMakeLists.txt | 13 ++++++++++++ src/ox/std/test/byteswap_test.cpp | 34 +++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/ox/std/test/byteswap_test.cpp diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index b971c0a4c..aedfbac80 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -316,7 +316,7 @@ class FileStore { template typename Header::FsSize_t FileStore
::Inode::size() { - return std::nativizeLittleEndian(sizeof(Inode) + getDataLen()); + return sizeof(Inode) + getDataLen(); } template diff --git a/src/ox/std/byteswap.hpp b/src/ox/std/byteswap.hpp index 7d247e7a4..0628b29c0 100644 --- a/src/ox/std/byteswap.hpp +++ b/src/ox/std/byteswap.hpp @@ -13,6 +13,7 @@ namespace ox { namespace std { + inline uint16_t byteSwap(uint16_t i) { return (i << 8) | (i >> 8); } diff --git a/src/ox/std/test/CMakeLists.txt b/src/ox/std/test/CMakeLists.txt index 3fd5793c5..66d76eea2 100644 --- a/src/ox/std/test/CMakeLists.txt +++ b/src/ox/std/test/CMakeLists.txt @@ -28,3 +28,16 @@ add_test("Test\\ ox_strcmp\\ hijk\\ !=\\ asdf" StrOpsTest "hijk > asdf") add_test("Test\\ ox_strcmp\\ read\\ !=\\ resize" StrOpsTest "read < resize") add_test("Test\\ ox_strcmp\\ resize\\ !=\\ read" StrOpsTest "resize > read") add_test("Test\\ ox_strcmp\\ resize\\ ==\\ resize" StrOpsTest "resize == resize") + + +################################################################################ +# Byte Swap Tests + +add_executable( + ByteSwapTest + byteswap_test.cpp +) + +target_link_libraries(ByteSwapTest OxStd) + +add_test("Test\\ nativizeLittleEndian\\ 40\\ ==\\ 671088640" ByteSwapTest "40") diff --git a/src/ox/std/test/byteswap_test.cpp b/src/ox/std/test/byteswap_test.cpp new file mode 100644 index 000000000..46862e8b7 --- /dev/null +++ b/src/ox/std/test/byteswap_test.cpp @@ -0,0 +1,34 @@ +/* + * Copyright 2015 - 2017 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/. + */ +#include +#include +#include +#include + +using namespace std; +using namespace ox::std; + +map> tests = { + { + "40", + []() { + cout << (nativizeLittleEndian((uint32_t) 40)) << endl; + return !(nativizeLittleEndian((uint32_t) 40) == 671088640); + } + }, +}; + +int main(int argc, const char **args) { + if (argc > 1) { + auto testName = args[1]; + if (tests.find(testName) != tests.end()) { + return tests[testName](); + } + } + return -1; +} From e0cf5c1a2bc404684deabd8089108be1c7254f42 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sun, 9 Apr 2017 17:15:23 -0500 Subject: [PATCH 03/45] Fix nativizeLittleEndian test to work on little endian systems --- src/ox/std/test/CMakeLists.txt | 2 +- src/ox/std/test/byteswap_test.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ox/std/test/CMakeLists.txt b/src/ox/std/test/CMakeLists.txt index 66d76eea2..de5fe4044 100644 --- a/src/ox/std/test/CMakeLists.txt +++ b/src/ox/std/test/CMakeLists.txt @@ -40,4 +40,4 @@ add_executable( target_link_libraries(ByteSwapTest OxStd) -add_test("Test\\ nativizeLittleEndian\\ 40\\ ==\\ 671088640" ByteSwapTest "40") +add_test("Test\\ nativizeLittleEndian\\ 40" ByteSwapTest "40") diff --git a/src/ox/std/test/byteswap_test.cpp b/src/ox/std/test/byteswap_test.cpp index 46862e8b7..b7d36d668 100644 --- a/src/ox/std/test/byteswap_test.cpp +++ b/src/ox/std/test/byteswap_test.cpp @@ -17,8 +17,7 @@ map> tests = { { "40", []() { - cout << (nativizeLittleEndian((uint32_t) 40)) << endl; - return !(nativizeLittleEndian((uint32_t) 40) == 671088640); + return !(nativizeLittleEndian(nativizeLittleEndian((uint32_t) 40)) == 40); } }, }; From 8e9a3e91df4e7ea5556c2bc365a72b9867c78c5f Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sun, 9 Apr 2017 23:12:46 -0500 Subject: [PATCH 04/45] Allow littleEndianToNative test parameters to be specified only in CMake --- src/ox/fs/filestore.hpp | 24 +++++++++++----------- src/ox/std/byteswap.hpp | 33 ++++--------------------------- src/ox/std/test/CMakeLists.txt | 17 +++++++++++++++- src/ox/std/test/byteswap_test.cpp | 18 +++++++++++------ 4 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index aedfbac80..e00af641e 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -50,7 +50,7 @@ void FileStoreHeader::setVersion(uint16_t version) { template uint16_t FileStoreHeader::getVersion() { - return std::nativizeLittleEndian(m_version); + return std::littleEndianToNative(m_version); } template @@ -60,7 +60,7 @@ void FileStoreHeader::setFsType(uint16_t fsType) { template uint16_t FileStoreHeader::getFsType() { - return std::nativizeLittleEndian(m_fsType); + return std::littleEndianToNative(m_fsType); } template @@ -70,7 +70,7 @@ void FileStoreHeader::setSize(FsSize_t size) { template FsSize_t FileStoreHeader::getSize() { - return std::nativizeLittleEndian(m_size); + return std::littleEndianToNative(m_size); } template @@ -80,7 +80,7 @@ void FileStoreHeader::setMemUsed(FsSize_t memUsed) { template FsSize_t FileStoreHeader::getMemUsed() { - return std::nativizeLittleEndian(m_memUsed); + return std::littleEndianToNative(m_memUsed); } template @@ -90,7 +90,7 @@ void FileStoreHeader::setRootInode(FsSize_t rootInode) { template FsSize_t FileStoreHeader::getRootInode() { - return std::nativizeLittleEndian(m_rootInode); + return std::littleEndianToNative(m_rootInode); } template @@ -326,7 +326,7 @@ void FileStore
::Inode::setDataLen(typename Header::FsSize_t dataLen) { template typename Header::FsSize_t FileStore
::Inode::getDataLen() { - return std::nativizeLittleEndian(this->m_dataLen); + return std::littleEndianToNative(this->m_dataLen); } template @@ -336,7 +336,7 @@ void FileStore
::Inode::setPrev(typename Header::FsSize_t prev) { template typename Header::FsSize_t FileStore
::Inode::getPrev() { - return std::nativizeLittleEndian(this->m_prev); + return std::littleEndianToNative(this->m_prev); } template @@ -346,7 +346,7 @@ void FileStore
::Inode::setNext(typename Header::FsSize_t next) { template typename Header::FsSize_t FileStore
::Inode::getNext() { - return std::nativizeLittleEndian(this->m_next); + return std::littleEndianToNative(this->m_next); } template @@ -356,7 +356,7 @@ void FileStore
::Inode::setId(InodeId_t id) { template typename Header::InodeId_t FileStore
::Inode::getId() { - return std::nativizeLittleEndian(this->m_id); + return std::littleEndianToNative(this->m_id); } template @@ -366,7 +366,7 @@ void FileStore
::Inode::setFileType(uint8_t fileType) { template uint8_t FileStore
::Inode::getFileType() { - return std::nativizeLittleEndian(this->m_fileType); + return std::littleEndianToNative(this->m_fileType); } template @@ -376,7 +376,7 @@ void FileStore
::Inode::setLeft(typename Header::FsSize_t left) { template typename Header::FsSize_t FileStore
::Inode::getLeft() { - return std::nativizeLittleEndian(this->m_left); + return std::littleEndianToNative(this->m_left); } template @@ -386,7 +386,7 @@ void FileStore
::Inode::setRight(typename Header::FsSize_t right) { template typename Header::FsSize_t FileStore
::Inode::getRight() { - return std::nativizeLittleEndian(this->m_right); + return std::littleEndianToNative(this->m_right); } template diff --git a/src/ox/std/byteswap.hpp b/src/ox/std/byteswap.hpp index 0628b29c0..7ddd3a742 100644 --- a/src/ox/std/byteswap.hpp +++ b/src/ox/std/byteswap.hpp @@ -40,14 +40,14 @@ inline uint64_t byteSwap(uint64_t i) { /** * Takes a little endian int and byte swaps if the platform is big endian. */ -inline uint8_t nativizeLittleEndian(uint8_t i) { +inline uint8_t littleEndianToNative(uint8_t i) { return i; } /** * Takes a little endian int and byte swaps if the platform is big endian. */ -inline uint16_t nativizeLittleEndian(uint16_t i) { +inline uint16_t littleEndianToNative(uint16_t i) { #ifdef __BIG_ENDIAN__ return byteSwap(i); #else @@ -58,7 +58,7 @@ inline uint16_t nativizeLittleEndian(uint16_t i) { /** * Takes a little endian int and byte swaps if the platform is big endian. */ -inline uint32_t nativizeLittleEndian(uint32_t i) { +inline uint32_t littleEndianToNative(uint32_t i) { #ifdef __BIG_ENDIAN__ return byteSwap(i); #else @@ -69,7 +69,7 @@ inline uint32_t nativizeLittleEndian(uint32_t i) { /** * Takes a little endian int and byte swaps if the platform is big endian. */ -inline uint64_t nativizeLittleEndian(uint64_t i) { +inline uint64_t littleEndianToNative(uint64_t i) { #ifdef __BIG_ENDIAN__ return byteSwap(i); #else @@ -106,30 +106,5 @@ inline uint64_t toLittleEndian(uint64_t i) { #endif } - -inline uint16_t toBigEndian(uint16_t i) { -#ifdef __LITTLE_ENDIAN__ - return byteSwap(i); -#else - return i; -#endif -} - -inline uint32_t toBigEndian(uint32_t i) { -#ifdef __LITTLE_ENDIAN__ - return byteSwap(i); -#else - return i; -#endif -} - -inline uint64_t toBigEndian(uint64_t i) { -#ifdef __LITTLE_ENDIAN__ - return byteSwap(i); -#else - return i; -#endif -} - } } diff --git a/src/ox/std/test/CMakeLists.txt b/src/ox/std/test/CMakeLists.txt index de5fe4044..bdcefc14d 100644 --- a/src/ox/std/test/CMakeLists.txt +++ b/src/ox/std/test/CMakeLists.txt @@ -40,4 +40,19 @@ add_executable( target_link_libraries(ByteSwapTest OxStd) -add_test("Test\\ nativizeLittleEndian\\ 40" ByteSwapTest "40") +add_test("Test\\ littleEndianToNative\\ 0x00ff" ByteSwapTest littleEndianToNative 0x00ff) +add_test("Test\\ littleEndianToNative\\ 0xff00" ByteSwapTest littleEndianToNative 0xff00) + +add_test("Test\\ littleEndianToNative\\ 0x000000ff" ByteSwapTest littleEndianToNative 0x000000ff) +add_test("Test\\ littleEndianToNative\\ 0x0000ff00" ByteSwapTest littleEndianToNative 0x0000ff00) +add_test("Test\\ littleEndianToNative\\ 0x00ff0000" ByteSwapTest littleEndianToNative 0x00ff0000) +add_test("Test\\ littleEndianToNative\\ 0xff000000" ByteSwapTest littleEndianToNative 0xff000000) + +add_test("Test\\ littleEndianToNative\\ 0x00000000000000ff" ByteSwapTest littleEndianToNative 0x00000000000000ff) +add_test("Test\\ littleEndianToNative\\ 0x000000000000ff00" ByteSwapTest littleEndianToNative 0x000000000000ff00) +add_test("Test\\ littleEndianToNative\\ 0x0000000000ff0000" ByteSwapTest littleEndianToNative 0x0000000000ff0000) +add_test("Test\\ littleEndianToNative\\ 0x00000000ff000000" ByteSwapTest littleEndianToNative 0x00000000ff000000) +add_test("Test\\ littleEndianToNative\\ 0x000000ff00000000" ByteSwapTest littleEndianToNative 0x000000ff00000000) +add_test("Test\\ littleEndianToNative\\ 0x0000ff0000000000" ByteSwapTest littleEndianToNative 0x0000ff0000000000) +add_test("Test\\ littleEndianToNative\\ 0x00ff000000000000" ByteSwapTest littleEndianToNative 0x00ff000000000000) +add_test("Test\\ littleEndianToNative\\ 0xff00000000000000" ByteSwapTest littleEndianToNative 0xff00000000000000) diff --git a/src/ox/std/test/byteswap_test.cpp b/src/ox/std/test/byteswap_test.cpp index b7d36d668..9f6cb8573 100644 --- a/src/ox/std/test/byteswap_test.cpp +++ b/src/ox/std/test/byteswap_test.cpp @@ -13,20 +13,26 @@ using namespace std; using namespace ox::std; -map> tests = { +template +int testLittleEndianToNative(string str) { + auto i = (T) stoul(str, nullptr, 16); + return !(littleEndianToNative(littleEndianToNative(i)) == i); +} + +map> tests = { { - "40", - []() { - return !(nativizeLittleEndian(nativizeLittleEndian((uint32_t) 40)) == 40); - } + { "littleEndianToNative", testLittleEndianToNative }, + { "littleEndianToNative", testLittleEndianToNative }, + { "littleEndianToNative", testLittleEndianToNative }, }, }; int main(int argc, const char **args) { if (argc > 1) { auto testName = args[1]; + auto testArg = args[2]; if (tests.find(testName) != tests.end()) { - return tests[testName](); + return tests[testName](testArg); } } return -1; From 31396a071ca7c484880a75630d65dfb7025b077c Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sun, 9 Apr 2017 23:28:58 -0500 Subject: [PATCH 05/45] Cleanup endianess converion redundancy --- src/ox/fs/filestore.hpp | 48 +++++++++++++++---------------- src/ox/std/byteswap.hpp | 44 ++++++---------------------- src/ox/std/test/CMakeLists.txt | 28 +++++++++--------- src/ox/std/test/byteswap_test.cpp | 10 +++---- 4 files changed, 51 insertions(+), 79 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index e00af641e..6176ab42d 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -45,52 +45,52 @@ struct FileStoreHeader { template void FileStoreHeader::setVersion(uint16_t version) { - m_version = std::toLittleEndian(version); + m_version = std::bigEndianAdapt(version); } template uint16_t FileStoreHeader::getVersion() { - return std::littleEndianToNative(m_version); + return std::bigEndianAdapt(m_version); } template void FileStoreHeader::setFsType(uint16_t fsType) { - m_fsType = std::toLittleEndian(fsType); + m_fsType = std::bigEndianAdapt(fsType); } template uint16_t FileStoreHeader::getFsType() { - return std::littleEndianToNative(m_fsType); + return std::bigEndianAdapt(m_fsType); } template void FileStoreHeader::setSize(FsSize_t size) { - m_size = std::toLittleEndian(size); + m_size = std::bigEndianAdapt(size); } template FsSize_t FileStoreHeader::getSize() { - return std::littleEndianToNative(m_size); + return std::bigEndianAdapt(m_size); } template void FileStoreHeader::setMemUsed(FsSize_t memUsed) { - m_memUsed = std::toLittleEndian(memUsed); + m_memUsed = std::bigEndianAdapt(memUsed); } template FsSize_t FileStoreHeader::getMemUsed() { - return std::littleEndianToNative(m_memUsed); + return std::bigEndianAdapt(m_memUsed); } template void FileStoreHeader::setRootInode(FsSize_t rootInode) { - m_rootInode = std::toLittleEndian(rootInode); + m_rootInode = std::bigEndianAdapt(rootInode); } template FsSize_t FileStoreHeader::getRootInode() { - return std::littleEndianToNative(m_rootInode); + return std::bigEndianAdapt(m_rootInode); } template @@ -321,72 +321,72 @@ typename Header::FsSize_t FileStore
::Inode::size() { template void FileStore
::Inode::setDataLen(typename Header::FsSize_t dataLen) { - this->m_dataLen = std::toLittleEndian(dataLen); + this->m_dataLen = std::bigEndianAdapt(dataLen); } template typename Header::FsSize_t FileStore
::Inode::getDataLen() { - return std::littleEndianToNative(this->m_dataLen); + return std::bigEndianAdapt(this->m_dataLen); } template void FileStore
::Inode::setPrev(typename Header::FsSize_t prev) { - this->m_prev = std::toLittleEndian(prev); + this->m_prev = std::bigEndianAdapt(prev); } template typename Header::FsSize_t FileStore
::Inode::getPrev() { - return std::littleEndianToNative(this->m_prev); + return std::bigEndianAdapt(this->m_prev); } template void FileStore
::Inode::setNext(typename Header::FsSize_t next) { - this->m_next = std::toLittleEndian(next); + this->m_next = std::bigEndianAdapt(next); } template typename Header::FsSize_t FileStore
::Inode::getNext() { - return std::littleEndianToNative(this->m_next); + return std::bigEndianAdapt(this->m_next); } template void FileStore
::Inode::setId(InodeId_t id) { - this->m_id = std::toLittleEndian(id); + this->m_id = std::bigEndianAdapt(id); } template typename Header::InodeId_t FileStore
::Inode::getId() { - return std::littleEndianToNative(this->m_id); + return std::bigEndianAdapt(this->m_id); } template void FileStore
::Inode::setFileType(uint8_t fileType) { - this->m_fileType = std::toLittleEndian(fileType); + this->m_fileType = std::bigEndianAdapt(fileType); } template uint8_t FileStore
::Inode::getFileType() { - return std::littleEndianToNative(this->m_fileType); + return std::bigEndianAdapt(this->m_fileType); } template void FileStore
::Inode::setLeft(typename Header::FsSize_t left) { - this->m_left = std::toLittleEndian(left); + this->m_left = std::bigEndianAdapt(left); } template typename Header::FsSize_t FileStore
::Inode::getLeft() { - return std::littleEndianToNative(this->m_left); + return std::bigEndianAdapt(this->m_left); } template void FileStore
::Inode::setRight(typename Header::FsSize_t right) { - this->m_right = std::toLittleEndian(right); + this->m_right = std::bigEndianAdapt(right); } template typename Header::FsSize_t FileStore
::Inode::getRight() { - return std::littleEndianToNative(this->m_right); + return std::bigEndianAdapt(this->m_right); } template diff --git a/src/ox/std/byteswap.hpp b/src/ox/std/byteswap.hpp index 7ddd3a742..cbe5e8068 100644 --- a/src/ox/std/byteswap.hpp +++ b/src/ox/std/byteswap.hpp @@ -38,16 +38,16 @@ inline uint64_t byteSwap(uint64_t i) { /** - * Takes a little endian int and byte swaps if the platform is big endian. + * Takes an int and byte swaps if the platform is big endian. */ -inline uint8_t littleEndianToNative(uint8_t i) { +inline uint8_t bigEndianAdapt(uint8_t i) { return i; } /** - * Takes a little endian int and byte swaps if the platform is big endian. + * Takes an int and byte swaps if the platform is big endian. */ -inline uint16_t littleEndianToNative(uint16_t i) { +inline uint16_t bigEndianAdapt(uint16_t i) { #ifdef __BIG_ENDIAN__ return byteSwap(i); #else @@ -56,9 +56,9 @@ inline uint16_t littleEndianToNative(uint16_t i) { } /** - * Takes a little endian int and byte swaps if the platform is big endian. + * Takes an int and byte swaps if the platform is big endian. */ -inline uint32_t littleEndianToNative(uint32_t i) { +inline uint32_t bigEndianAdapt(uint32_t i) { #ifdef __BIG_ENDIAN__ return byteSwap(i); #else @@ -67,9 +67,9 @@ inline uint32_t littleEndianToNative(uint32_t i) { } /** - * Takes a little endian int and byte swaps if the platform is big endian. + * Takes an int and byte swaps if the platform is big endian. */ -inline uint64_t littleEndianToNative(uint64_t i) { +inline uint64_t bigEndianAdapt(uint64_t i) { #ifdef __BIG_ENDIAN__ return byteSwap(i); #else @@ -78,33 +78,5 @@ inline uint64_t littleEndianToNative(uint64_t i) { } -inline uint8_t toLittleEndian(uint8_t i) { - return i; -} - -inline uint16_t toLittleEndian(uint16_t i) { -#ifdef __BIG_ENDIAN__ - return byteSwap(i); -#else - return i; -#endif -} - -inline uint32_t toLittleEndian(uint32_t i) { -#ifdef __BIG_ENDIAN__ - return byteSwap(i); -#else - return i; -#endif -} - -inline uint64_t toLittleEndian(uint64_t i) { -#ifdef __BIG_ENDIAN__ - return byteSwap(i); -#else - return i; -#endif -} - } } diff --git a/src/ox/std/test/CMakeLists.txt b/src/ox/std/test/CMakeLists.txt index bdcefc14d..82f23987c 100644 --- a/src/ox/std/test/CMakeLists.txt +++ b/src/ox/std/test/CMakeLists.txt @@ -40,19 +40,19 @@ add_executable( target_link_libraries(ByteSwapTest OxStd) -add_test("Test\\ littleEndianToNative\\ 0x00ff" ByteSwapTest littleEndianToNative 0x00ff) -add_test("Test\\ littleEndianToNative\\ 0xff00" ByteSwapTest littleEndianToNative 0xff00) +add_test("Test\\ bigEndianAdapt\\ 0x00ff" ByteSwapTest bigEndianAdapt 0x00ff) +add_test("Test\\ bigEndianAdapt\\ 0xff00" ByteSwapTest bigEndianAdapt 0xff00) -add_test("Test\\ littleEndianToNative\\ 0x000000ff" ByteSwapTest littleEndianToNative 0x000000ff) -add_test("Test\\ littleEndianToNative\\ 0x0000ff00" ByteSwapTest littleEndianToNative 0x0000ff00) -add_test("Test\\ littleEndianToNative\\ 0x00ff0000" ByteSwapTest littleEndianToNative 0x00ff0000) -add_test("Test\\ littleEndianToNative\\ 0xff000000" ByteSwapTest littleEndianToNative 0xff000000) +add_test("Test\\ bigEndianAdapt\\ 0x000000ff" ByteSwapTest bigEndianAdapt 0x000000ff) +add_test("Test\\ bigEndianAdapt\\ 0x0000ff00" ByteSwapTest bigEndianAdapt 0x0000ff00) +add_test("Test\\ bigEndianAdapt\\ 0x00ff0000" ByteSwapTest bigEndianAdapt 0x00ff0000) +add_test("Test\\ bigEndianAdapt\\ 0xff000000" ByteSwapTest bigEndianAdapt 0xff000000) -add_test("Test\\ littleEndianToNative\\ 0x00000000000000ff" ByteSwapTest littleEndianToNative 0x00000000000000ff) -add_test("Test\\ littleEndianToNative\\ 0x000000000000ff00" ByteSwapTest littleEndianToNative 0x000000000000ff00) -add_test("Test\\ littleEndianToNative\\ 0x0000000000ff0000" ByteSwapTest littleEndianToNative 0x0000000000ff0000) -add_test("Test\\ littleEndianToNative\\ 0x00000000ff000000" ByteSwapTest littleEndianToNative 0x00000000ff000000) -add_test("Test\\ littleEndianToNative\\ 0x000000ff00000000" ByteSwapTest littleEndianToNative 0x000000ff00000000) -add_test("Test\\ littleEndianToNative\\ 0x0000ff0000000000" ByteSwapTest littleEndianToNative 0x0000ff0000000000) -add_test("Test\\ littleEndianToNative\\ 0x00ff000000000000" ByteSwapTest littleEndianToNative 0x00ff000000000000) -add_test("Test\\ littleEndianToNative\\ 0xff00000000000000" ByteSwapTest littleEndianToNative 0xff00000000000000) +add_test("Test\\ bigEndianAdapt\\ 0x00000000000000ff" ByteSwapTest bigEndianAdapt 0x00000000000000ff) +add_test("Test\\ bigEndianAdapt\\ 0x000000000000ff00" ByteSwapTest bigEndianAdapt 0x000000000000ff00) +add_test("Test\\ bigEndianAdapt\\ 0x0000000000ff0000" ByteSwapTest bigEndianAdapt 0x0000000000ff0000) +add_test("Test\\ bigEndianAdapt\\ 0x00000000ff000000" ByteSwapTest bigEndianAdapt 0x00000000ff000000) +add_test("Test\\ bigEndianAdapt\\ 0x000000ff00000000" ByteSwapTest bigEndianAdapt 0x000000ff00000000) +add_test("Test\\ bigEndianAdapt\\ 0x0000ff0000000000" ByteSwapTest bigEndianAdapt 0x0000ff0000000000) +add_test("Test\\ bigEndianAdapt\\ 0x00ff000000000000" ByteSwapTest bigEndianAdapt 0x00ff000000000000) +add_test("Test\\ bigEndianAdapt\\ 0xff00000000000000" ByteSwapTest bigEndianAdapt 0xff00000000000000) diff --git a/src/ox/std/test/byteswap_test.cpp b/src/ox/std/test/byteswap_test.cpp index 9f6cb8573..fc679c800 100644 --- a/src/ox/std/test/byteswap_test.cpp +++ b/src/ox/std/test/byteswap_test.cpp @@ -14,16 +14,16 @@ using namespace std; using namespace ox::std; template -int testLittleEndianToNative(string str) { +int testBigEndianAdapt(string str) { auto i = (T) stoul(str, nullptr, 16); - return !(littleEndianToNative(littleEndianToNative(i)) == i); + return !(bigEndianAdapt(bigEndianAdapt(i)) == i); } map> tests = { { - { "littleEndianToNative", testLittleEndianToNative }, - { "littleEndianToNative", testLittleEndianToNative }, - { "littleEndianToNative", testLittleEndianToNative }, + { "bigEndianAdapt", testBigEndianAdapt }, + { "bigEndianAdapt", testBigEndianAdapt }, + { "bigEndianAdapt", testBigEndianAdapt }, }, }; From aaac08d3b20e7df96a96758d8b3c01d9742aa00c Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 10 Apr 2017 00:10:15 -0500 Subject: [PATCH 06/45] Fix some PowerPC issues in the byteswap test --- src/ox/std/test/byteswap_test.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/ox/std/test/byteswap_test.cpp b/src/ox/std/test/byteswap_test.cpp index fc679c800..096739f2a 100644 --- a/src/ox/std/test/byteswap_test.cpp +++ b/src/ox/std/test/byteswap_test.cpp @@ -5,9 +5,7 @@ * 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/. */ -#include #include -#include #include using namespace std; @@ -15,11 +13,11 @@ using namespace ox::std; template int testBigEndianAdapt(string str) { - auto i = (T) stoul(str, nullptr, 16); + auto i = (T) stoull(str, nullptr, 16); return !(bigEndianAdapt(bigEndianAdapt(i)) == i); } -map> tests = { +map tests = { { { "bigEndianAdapt", testBigEndianAdapt }, { "bigEndianAdapt", testBigEndianAdapt }, @@ -28,12 +26,13 @@ map> tests = { }; int main(int argc, const char **args) { + int retval = -1; if (argc > 1) { auto testName = args[1]; - auto testArg = args[2]; + string testArg = args[2]; if (tests.find(testName) != tests.end()) { - return tests[testName](testArg); + retval = tests[testName](testArg); } } - return -1; + return retval; } From eab7e0ff3ac87eb16d78cac5dee00ae79ac665c9 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 10 Apr 2017 01:35:47 -0500 Subject: [PATCH 07/45] Add byteswap.hpp to the list of installed headers --- src/ox/fs/filesystem.cpp | 2 +- src/ox/std/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index b4a3a758a..b0e5de159 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -30,7 +30,7 @@ FileSystem *createFileSystem(void *buff) { } break; default: - return nullptr; + break; } return fs; diff --git a/src/ox/std/CMakeLists.txt b/src/ox/std/CMakeLists.txt index 6c28d48a1..c0d2f10e2 100644 --- a/src/ox/std/CMakeLists.txt +++ b/src/ox/std/CMakeLists.txt @@ -9,6 +9,7 @@ add_library( install( FILES + byteswap.hpp memops.hpp strops.hpp std.hpp From da410b7f39105aefcdba16a64bf5a338cb16ee1d Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 10 Apr 2017 17:09:47 -0500 Subject: [PATCH 08/45] Add shell command to Makefile --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 26fc78cd7..d74c9481d 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ HOST_ENV=${OS}-$(shell uname -m) DEVENV=devenv$(shell pwd | sed 's/\//-/g') DEVENV_IMAGE=wombatant/devenv ifeq ($(shell docker inspect --format="{{.State.Status}}" ${DEVENV} 2>&1),running) - ENV_RUN=docker exec --user $(shell id -u ${USER}) ${DEVENV} + ENV_RUN=docker exec -i -t --user $(shell id -u ${USER}) ${DEVENV} endif make: @@ -31,6 +31,9 @@ devenv: devenv-destroy: docker rm -f ${DEVENV} +shell: + ${ENV_RUN} bash + release: ${ENV_RUN} rm -rf build/${HOST_ENV}-release ${ENV_RUN} ./scripts/setup_build ${HOST_ENV} From 02b25ef8823e25b54358f417a9c32916a07a5232 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 10 Apr 2017 17:11:07 -0500 Subject: [PATCH 09/45] Add non-CMAKE_FIND_ROOT_PATH paths to OxConfig.cmake --- OxConfig.cmake | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/OxConfig.cmake b/OxConfig.cmake index 2c7ee2bb4..5d53f7bae 100644 --- a/OxConfig.cmake +++ b/OxConfig.cmake @@ -1,3 +1,9 @@ -set(Ox_INCLUDE_DIRS ${CMAKE_FIND_ROOT_PATH}/include/) -set(OxStd_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxStd.a) -set(OxFs_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxFs.a) +if(${CMAKE_FIND_ROOT_PATH}) + set(Ox_INCLUDE_DIRS ${CMAKE_FIND_ROOT_PATH}/include/) + set(OxStd_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxStd.a) + set(OxFs_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxFs.a) +else(${CMAKE_FIND_ROOT_PATH}) + set(Ox_INCLUDE_DIRS /usr/local/include/) + set(OxStd_LIBRARY /usr/local/lib/ox/libOxStd.a) + set(OxFs_LIBRARY /usr/local/lib/ox/libOxFs.a) +endif(${CMAKE_FIND_ROOT_PATH}) From 8eb73298f547f0fac22a3887c31056a533efe5ce Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 10 Apr 2017 23:17:39 -0500 Subject: [PATCH 10/45] Put the current inode space usage back into the spaceNeeded method --- src/ox/fs/filestore.hpp | 7 +------ src/ox/fs/oxfstool.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 6176ab42d..928e8b0a5 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -571,12 +571,7 @@ typename FileStore
::StatInfo FileStore
::stat(InodeId_t id) { template typename Header::FsSize_t FileStore
::spaceNeeded(InodeId_t id, typename Header::FsSize_t size) { - typename Header::FsSize_t needed = sizeof(Inode) + size;; - auto inode = getInode(ptr(m_header.getRootInode()), id); - if (inode) { - needed -= inode->size(); - } - return needed; + return sizeof(Inode) + size; } template diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index 235d1e14a..d49af7a07 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -30,8 +30,7 @@ const static auto usage = "usage:\n" "\toxfs compact \n" "\toxfs version\n"; -char *loadFileBuff(const char *path, ::size_t *sizeOut = nullptr) { - auto file = fopen(path, "rb"); +char *loadFileBuff(FILE *file, ::size_t *sizeOut = nullptr) { if (file) { fseek(file, 0, SEEK_END); const auto size = ftell(file); @@ -48,6 +47,10 @@ char *loadFileBuff(const char *path, ::size_t *sizeOut = nullptr) { } } +char *loadFileBuff(const char *path, ::size_t *sizeOut = nullptr) { + return loadFileBuff(fopen(path, "rb"), sizeOut); +} + size_t bytes(const char *str) { auto size = ::ox_strlen(str); const auto lastChar = str[size-1]; From 416883b35467d72d500858a088920fc65bb0b033 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 11 Apr 2017 19:08:13 -0500 Subject: [PATCH 11/45] Add explicit include to byteswap test --- src/ox/std/test/byteswap_test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ox/std/test/byteswap_test.cpp b/src/ox/std/test/byteswap_test.cpp index 096739f2a..6bad03536 100644 --- a/src/ox/std/test/byteswap_test.cpp +++ b/src/ox/std/test/byteswap_test.cpp @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include #include using namespace std; From 78edb14d76c2721e3c62f00fb7964a40a22ff8d3 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 11 Apr 2017 19:55:17 -0500 Subject: [PATCH 12/45] Fix some issues in in FileStore::alloc that caused buffer overflows --- src/ox/fs/filestore.hpp | 46 +++++++++++++++-------------------------- src/ox/fs/oxfstool.cpp | 21 +++++++++++-------- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 928e8b0a5..68bb747f4 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -276,15 +276,9 @@ class FileStore { */ bool insert(Inode *root, Inode *insertValue); - /** - * Gets the FsSize_t associated with the next Inode to be allocated. - * @retrun the FsSize_t associated with the next Inode to be allocated - */ - typename Header::FsSize_t iterator(); - typename Header::FsSize_t firstInode(); - Inode *lastInode(); + typename Header::FsSize_t lastInode(); /** * Updates the address of the inode in the tree. @@ -326,7 +320,7 @@ void FileStore
::Inode::setDataLen(typename Header::FsSize_t dataLen) { template typename Header::FsSize_t FileStore
::Inode::getDataLen() { - return std::bigEndianAdapt(this->m_dataLen); + return std::bigEndianAdapt(m_dataLen); } template @@ -336,7 +330,7 @@ void FileStore
::Inode::setPrev(typename Header::FsSize_t prev) { template typename Header::FsSize_t FileStore
::Inode::getPrev() { - return std::bigEndianAdapt(this->m_prev); + return std::bigEndianAdapt(m_prev); } template @@ -346,7 +340,7 @@ void FileStore
::Inode::setNext(typename Header::FsSize_t next) { template typename Header::FsSize_t FileStore
::Inode::getNext() { - return std::bigEndianAdapt(this->m_next); + return std::bigEndianAdapt(m_next); } template @@ -356,7 +350,7 @@ void FileStore
::Inode::setId(InodeId_t id) { template typename Header::InodeId_t FileStore
::Inode::getId() { - return std::bigEndianAdapt(this->m_id); + return std::bigEndianAdapt(m_id); } template @@ -366,7 +360,7 @@ void FileStore
::Inode::setFileType(uint8_t fileType) { template uint8_t FileStore
::Inode::getFileType() { - return std::bigEndianAdapt(this->m_fileType); + return std::bigEndianAdapt(m_fileType); } template @@ -376,7 +370,7 @@ void FileStore
::Inode::setLeft(typename Header::FsSize_t left) { template typename Header::FsSize_t FileStore
::Inode::getLeft() { - return std::bigEndianAdapt(this->m_left); + return std::bigEndianAdapt(m_left); } template @@ -386,12 +380,12 @@ void FileStore
::Inode::setRight(typename Header::FsSize_t right) { template typename Header::FsSize_t FileStore
::Inode::getRight() { - return std::bigEndianAdapt(this->m_right); + return std::bigEndianAdapt(m_right); } template void FileStore
::Inode::setData(void *data, typename Header::FsSize_t size) { - ox_memcpy(this->getData(), data, size); + ox_memcpy(getData(), data, size); setDataLen(size); } @@ -630,17 +624,16 @@ typename FileStore
::Inode *FileStore
::getInodeParent(Inode *root template typename Header::FsSize_t FileStore
::nextInodeAddr() { - typename Header::FsSize_t next = ptr(lastInode()) + lastInode()->size(); - return next; + return lastInode() + ptr(lastInode())->size(); } template void *FileStore
::alloc(typename Header::FsSize_t size) { - typename Header::FsSize_t next = nextInodeAddr(); - if ((next + size) > (uint64_t) end()) { + auto next = nextInodeAddr(); + if ((next + size) > ptr(end())) { compact(); next = nextInodeAddr(); - if ((next + size) > (uint64_t) end()) { + if ((next + size) > ptr(end())) { return nullptr; } } @@ -649,7 +642,7 @@ void *FileStore
::alloc(typename Header::FsSize_t size) { const auto inode = ptr(retval); ox_memset(inode, 0, size); inode->setPrev(ptr(firstInode())->getPrev()); - inode->setNext(retval + size); + inode->setNext(firstInode()); m_header.setMemUsed(m_header.getMemUsed() + size); ptr(firstInode())->setPrev(retval); return inode; @@ -697,11 +690,6 @@ bool FileStore
::insert(Inode *root, Inode *insertValue) { return retval; } -template -typename Header::FsSize_t FileStore
::iterator() { - return ptr(lastInode()) + lastInode()->size(); -} - template typename Header::FsSize_t FileStore
::ptr(void *ptr) { #ifdef _MSC_VER @@ -719,8 +707,8 @@ typename Header::FsSize_t FileStore
::firstInode() { } template -typename FileStore
::Inode *FileStore
::lastInode() { - return ptr(ptr(firstInode())->getPrev()); +typename Header::FsSize_t FileStore
::lastInode() { + return ptr(firstInode())->getPrev(); } template @@ -744,7 +732,7 @@ uint8_t *FileStore
::format(uint8_t *buffer, typename Header::FsSize_t si fs->m_header.setMemUsed(sizeof(FileStore
) + sizeof(Inode)); fs->m_header.setRootInode(sizeof(FileStore
)); ((Inode*) (fs + 1))->setPrev(sizeof(FileStore
)); - fs->lastInode()->setNext(sizeof(FileStore
)); + ((Inode*) (fs + 1))->setNext(sizeof(FileStore
)); return (uint8_t*) buffer; } diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index d49af7a07..273958e17 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -55,8 +55,9 @@ size_t bytes(const char *str) { auto size = ::ox_strlen(str); const auto lastChar = str[size-1]; auto multiplier = 1; - auto copy = new char[size]; - ox_memcpy(copy, str, size); + char copy[size + 1]; + ox_memcpy(copy, str, size + 1); + // parse size unit if (lastChar < '0' || lastChar > '9') { copy[size-1] = 0; switch (lastChar) { @@ -76,9 +77,7 @@ size_t bytes(const char *str) { multiplier = -1; } } - const auto retval = ((size_t) ox_atoi(copy)) * multiplier; - delete []copy; - return retval; + return ox_atoi(copy) * multiplier; } int format(int argc, char **args) { @@ -86,13 +85,10 @@ int format(int argc, char **args) { auto err = 0; if (argc >= 5) { auto type = ox_atoi(args[2]); - cout << args[3] << endl; auto size = bytes(args[3]); auto path = args[4]; auto buff = (uint8_t*) malloc(size); - cout << "Size: " << size << " bytes\n"; - cout << "Type: " << type << endl; if (size < sizeof(FileStore64)) { err = 1; @@ -198,10 +194,11 @@ int write(int argc, char **args, bool expand) { if (itemsRead) { auto srcBuff = loadFileBuff(srcPath, &srcSize); if (srcBuff) { + auto expanded = false; auto fs = createFileSystem(fsBuff); if (fs) { if (expand && fs->available() <= srcSize) { - auto needed = fs->spaceNeeded(inode, srcSize); + auto needed = fs->size() + fs->spaceNeeded(inode, srcSize); auto cloneBuff = new uint8_t[needed]; ox_memcpy(cloneBuff, fsBuff, fsSize); @@ -214,6 +211,12 @@ int write(int argc, char **args, bool expand) { fs->resize(fsSize); } err |= fs->write(inode, srcBuff, srcSize); + + // compact the file system if it was expanded + if (expanded) { + fs->resize(); + } + if (err) { fprintf(stderr, "Could not write to file system.\n"); } From 0052cccc14433f6ed620acbceb4321bf7f73c31b Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 11 Apr 2017 22:41:23 -0500 Subject: [PATCH 13/45] Fix OxConfig.cmake to work with GBA builds again --- OxConfig.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OxConfig.cmake b/OxConfig.cmake index 5d53f7bae..b1c111846 100644 --- a/OxConfig.cmake +++ b/OxConfig.cmake @@ -1,9 +1,9 @@ -if(${CMAKE_FIND_ROOT_PATH}) - set(Ox_INCLUDE_DIRS ${CMAKE_FIND_ROOT_PATH}/include/) - set(OxStd_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxStd.a) - set(OxFs_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxFs.a) -else(${CMAKE_FIND_ROOT_PATH}) +if("${CMAKE_FIND_ROOT_PATH}" STREQUAL "") set(Ox_INCLUDE_DIRS /usr/local/include/) set(OxStd_LIBRARY /usr/local/lib/ox/libOxStd.a) set(OxFs_LIBRARY /usr/local/lib/ox/libOxFs.a) -endif(${CMAKE_FIND_ROOT_PATH}) +else("${CMAKE_FIND_ROOT_PATH}" STREQUAL "") + set(Ox_INCLUDE_DIRS ${CMAKE_FIND_ROOT_PATH}/include/) + set(OxStd_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxStd.a) + set(OxFs_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxFs.a) +endif("${CMAKE_FIND_ROOT_PATH}" STREQUAL "") From 9f3b338fed5b713c3413fed7d4ade4b7c66960dc Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 12 Apr 2017 00:20:17 -0500 Subject: [PATCH 14/45] Add ClArgs library --- src/ox/CMakeLists.txt | 1 + src/ox/clargs/CMakeLists.txt | 20 ++++++++++++++++++++ src/ox/clargs/clargs.cpp | 31 +++++++++++++++++++++++++++++++ src/ox/clargs/clargs.hpp | 28 ++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 src/ox/clargs/CMakeLists.txt create mode 100644 src/ox/clargs/clargs.cpp create mode 100644 src/ox/clargs/clargs.hpp diff --git a/src/ox/CMakeLists.txt b/src/ox/CMakeLists.txt index dea24e700..d0dd6848e 100644 --- a/src/ox/CMakeLists.txt +++ b/src/ox/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 2.8) +add_subdirectory(clargs) add_subdirectory(fs) add_subdirectory(std) diff --git a/src/ox/clargs/CMakeLists.txt b/src/ox/clargs/CMakeLists.txt new file mode 100644 index 000000000..172c773ae --- /dev/null +++ b/src/ox/clargs/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8) + +add_library( + OxClArgs + clargs.cpp +) + +install( + FILES + clargs.hpp + DESTINATION + include/ox/clargs +) + +install( + TARGETS + OxClArgs + LIBRARY DESTINATION lib/ox + ARCHIVE DESTINATION lib/ox +) diff --git a/src/ox/clargs/clargs.cpp b/src/ox/clargs/clargs.cpp new file mode 100644 index 000000000..c20db5559 --- /dev/null +++ b/src/ox/clargs/clargs.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2015 - 2017 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/. + */ + +#include "clargs.hpp" + +namespace ox { +namespace clargs { + +ClArgs::ClArgs(int argc, const char **args) { + for (int i = 0; i < argc; i++) { + std::string arg = args[i]; + if (arg[0] == '-') { + while (arg[0] == '-' && arg.size()) { + arg = arg.substr(1); + } + m_args[arg] = true; + } + } +} + +bool ClArgs::operator[](std::string arg) { + return m_args[arg]; +} + +} +} diff --git a/src/ox/clargs/clargs.hpp b/src/ox/clargs/clargs.hpp new file mode 100644 index 000000000..be250d56c --- /dev/null +++ b/src/ox/clargs/clargs.hpp @@ -0,0 +1,28 @@ +/* + * Copyright 2015 - 2017 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 +#include + +namespace ox { +namespace clargs { + +class ClArgs { + private: + std::map m_args; + + public: + ClArgs(int argc, const char **args); + + bool operator[](std::string arg); +}; + +} +} From 5e80cc80b8ea65779387e651ed16e0bab7853f70 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 12 Apr 2017 21:26:23 -0500 Subject: [PATCH 15/45] Add size check to createFileSystem --- src/ox/clargs/clargs.hpp | 4 ++-- src/ox/fs/filesystem.cpp | 7 ++++++- src/ox/fs/filesystem.hpp | 2 +- src/ox/fs/oxfstool.cpp | 10 +++++----- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/ox/clargs/clargs.hpp b/src/ox/clargs/clargs.hpp index be250d56c..630b9d2a8 100644 --- a/src/ox/clargs/clargs.hpp +++ b/src/ox/clargs/clargs.hpp @@ -16,12 +16,12 @@ namespace clargs { class ClArgs { private: - std::map m_args; + ::std::map<::std::string, bool> m_args; public: ClArgs(int argc, const char **args); - bool operator[](std::string arg); + bool operator[](::std::string arg); }; } diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index b0e5de159..7346ee3fc 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -10,7 +10,7 @@ namespace ox { namespace fs { -FileSystem *createFileSystem(void *buff) { +FileSystem *createFileSystem(void *buff, size_t buffSize) { auto version = ((FileStore16*) buff)->version(); auto type = ((FileStore16*) buff)->fsType(); FileSystem *fs = nullptr; @@ -33,6 +33,11 @@ FileSystem *createFileSystem(void *buff) { break; } + if (fs->size() > buffSize) { + delete fs; + fs = nullptr; + } + return fs; } diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index 8cd1f135d..34980466c 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -53,7 +53,7 @@ class FileSystem { virtual uint64_t size() = 0; }; -FileSystem *createFileSystem(void *buff); +FileSystem *createFileSystem(void *buff, size_t buffSize); template class FileSystemTemplate: public FileSystem { diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index 273958e17..cdcc9e586 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -148,7 +148,7 @@ int read(int argc, char **args) { auto fsBuff = loadFileBuff(fsPath, &fsSize); if (fsBuff) { - auto fs = createFileSystem(fsBuff); + auto fs = createFileSystem(fsBuff, fsSize); if (fs) { auto output = fs->read(inode, &fileSize); @@ -195,7 +195,7 @@ int write(int argc, char **args, bool expand) { auto srcBuff = loadFileBuff(srcPath, &srcSize); if (srcBuff) { auto expanded = false; - auto fs = createFileSystem(fsBuff); + auto fs = createFileSystem(fsBuff, fsSize); if (fs) { if (expand && fs->available() <= srcSize) { auto needed = fs->size() + fs->spaceNeeded(inode, srcSize); @@ -206,7 +206,7 @@ int write(int argc, char **args, bool expand) { delete []fsBuff; fsBuff = cloneBuff; - fs = createFileSystem(fsBuff); + fs = createFileSystem(fsBuff, fsSize); fsSize = needed; fs->resize(fsSize); } @@ -264,7 +264,7 @@ int compact(int argc, char **args) { auto fsBuff = loadFileBuff(fsPath, &fsSize); if (fsBuff) { - auto fs = createFileSystem(fsBuff); + auto fs = createFileSystem(fsBuff, fsSize); if (fs) { fs->resize(); @@ -304,7 +304,7 @@ int remove(int argc, char **args) { auto fsBuff = loadFileBuff(fsPath, &fsSize); if (fsBuff) { - auto fs = createFileSystem(fsBuff); + auto fs = createFileSystem(fsBuff, fsSize); if (fs) { err = fs->remove(inode); From 4fde40ece952af86c62583be6bf6dc270d92a9ea Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 12 Apr 2017 21:27:55 -0500 Subject: [PATCH 16/45] Remove ox::std namespace --- src/ox/std/types.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ox/std/types.hpp b/src/ox/std/types.hpp index 478af561e..bc200352e 100644 --- a/src/ox/std/types.hpp +++ b/src/ox/std/types.hpp @@ -23,11 +23,9 @@ typedef unsigned long uint64_t; #endif namespace ox { -namespace std { typedef uint32_t Error; -} } #if defined(_LP64) || defined(__ppc64__) || defined(__aarch64__) From 9328113fcd0b6c127e24954f8d522e1198b19763 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 12 Apr 2017 22:03:56 -0500 Subject: [PATCH 17/45] Fix library paths in OxConfig.cmake --- OxConfig.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OxConfig.cmake b/OxConfig.cmake index b1c111846..63a0a417c 100644 --- a/OxConfig.cmake +++ b/OxConfig.cmake @@ -1,9 +1,9 @@ if("${CMAKE_FIND_ROOT_PATH}" STREQUAL "") set(Ox_INCLUDE_DIRS /usr/local/include/) set(OxStd_LIBRARY /usr/local/lib/ox/libOxStd.a) - set(OxFs_LIBRARY /usr/local/lib/ox/libOxFs.a) + set(OxFS_LIBRARY /usr/local/lib/ox/libOxFS.a) else("${CMAKE_FIND_ROOT_PATH}" STREQUAL "") set(Ox_INCLUDE_DIRS ${CMAKE_FIND_ROOT_PATH}/include/) set(OxStd_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxStd.a) - set(OxFs_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxFs.a) + set(OxFS_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxFS.a) endif("${CMAKE_FIND_ROOT_PATH}" STREQUAL "") From 0402fac3898b080e48e0ad7a6508fab08f828205 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 12 Apr 2017 23:47:19 -0500 Subject: [PATCH 18/45] Add string and in options to ClArgs --- OxConfig.cmake | 2 ++ src/ox/clargs/clargs.cpp | 33 +++++++++++++++++++++++++++++---- src/ox/clargs/clargs.hpp | 10 ++++++++-- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/OxConfig.cmake b/OxConfig.cmake index 63a0a417c..6312e31c8 100644 --- a/OxConfig.cmake +++ b/OxConfig.cmake @@ -2,8 +2,10 @@ if("${CMAKE_FIND_ROOT_PATH}" STREQUAL "") set(Ox_INCLUDE_DIRS /usr/local/include/) set(OxStd_LIBRARY /usr/local/lib/ox/libOxStd.a) set(OxFS_LIBRARY /usr/local/lib/ox/libOxFS.a) + set(OxClArgs_LIBRARY /usr/local/lib/ox/libOxClArgs.a) else("${CMAKE_FIND_ROOT_PATH}" STREQUAL "") set(Ox_INCLUDE_DIRS ${CMAKE_FIND_ROOT_PATH}/include/) set(OxStd_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxStd.a) set(OxFS_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxFS.a) + set(OxClArgs_LIBRARY ${CMAKE_FIND_ROOT_PATH}/lib/ox/libOxClArgs.a) endif("${CMAKE_FIND_ROOT_PATH}" STREQUAL "") diff --git a/src/ox/clargs/clargs.cpp b/src/ox/clargs/clargs.cpp index c20db5559..cf32e861b 100644 --- a/src/ox/clargs/clargs.cpp +++ b/src/ox/clargs/clargs.cpp @@ -6,25 +6,50 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include #include "clargs.hpp" namespace ox { namespace clargs { +using ::std::string; +using namespace ::std; + ClArgs::ClArgs(int argc, const char **args) { for (int i = 0; i < argc; i++) { - std::string arg = args[i]; + string arg = args[i]; if (arg[0] == '-') { while (arg[0] == '-' && arg.size()) { arg = arg.substr(1); } - m_args[arg] = true; + m_bools[arg.c_str()] = true; + + // parse additional arguments + if (i < argc) { + string val = args[i + 1]; + if (val[i] != '-') { + if (val == "false") { + m_bools[arg.c_str()] = false; + } + m_strings[arg.c_str()] = val.c_str(); + m_ints[arg.c_str()] = ox_atoi(val.c_str()); + i++; + } + } } } } -bool ClArgs::operator[](std::string arg) { - return m_args[arg]; +bool ClArgs::getBool(const char *arg) { + return m_bools[arg]; +} + +const char *ClArgs::getString(const char *arg) { + return m_strings[arg]; +} + +int ClArgs::getInt(const char *arg) { + return m_ints[arg]; } } diff --git a/src/ox/clargs/clargs.hpp b/src/ox/clargs/clargs.hpp index be250d56c..443f82a94 100644 --- a/src/ox/clargs/clargs.hpp +++ b/src/ox/clargs/clargs.hpp @@ -16,12 +16,18 @@ namespace clargs { class ClArgs { private: - std::map m_args; + ::std::map<::std::string, bool> m_bools; + ::std::map<::std::string, const char*> m_strings; + ::std::map<::std::string, int> m_ints; public: ClArgs(int argc, const char **args); - bool operator[](std::string arg); + bool getBool(const char *arg); + + const char *getString(const char *arg); + + int getInt(const char *arg); }; } From 7fdf5751b1cf50af2fa8eff4a65079ddf8e63383 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 13 Apr 2017 02:12:26 -0500 Subject: [PATCH 19/45] Add expandCopy and expandCopyCleanup --- src/ox/fs/filesystem.cpp | 30 ++++++++++++++++++++++++++++++ src/ox/fs/filesystem.hpp | 20 ++++++++++++++++++++ src/ox/fs/oxfstool.cpp | 24 ++++++++---------------- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index b0e5de159..280a46247 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -5,6 +5,7 @@ * 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/. */ +#include #include "filesystem.hpp" namespace ox { @@ -36,5 +37,34 @@ FileSystem *createFileSystem(void *buff) { return fs; } +FileSystem *expandCopy(FileSystem *fs, size_t size) { + auto fsBuff = fs->buff(); + FileSystem *retval = nullptr; + + if (fs->size() <= size) { + auto cloneBuff = new uint8_t[size]; + ox_memcpy(cloneBuff, fsBuff, fs->size()); + + fsBuff = cloneBuff; + retval = createFileSystem(fsBuff); + retval->resize(size); + } + + return retval; +} + +FileSystem *expandCopyCleanup(FileSystem *fs, size_t size) { + auto out = expandCopy(fs, size); + + if (out) { + delete fs->buff(); + delete fs; + } else { + out = fs; + } + + return out; +} + } } diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index 8cd1f135d..cac8f7c4e 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -51,10 +51,23 @@ class FileSystem { virtual uint64_t available() = 0; virtual uint64_t size() = 0; + + virtual uint8_t *buff() = 0; }; FileSystem *createFileSystem(void *buff); +/** + * Creates a larger version of the given FileSystem. + */ +FileSystem *expandCopy(FileSystem *src); + +/** + * Calls expandCopy and deletes the original FileSystem and buff a resize was + * performed. + */ +FileSystem *expandCopyCleanup(FileSystem *fs, size_t size); + template class FileSystemTemplate: public FileSystem { @@ -117,6 +130,8 @@ class FileSystemTemplate: public FileSystem { uint64_t size() override; + uint8_t *buff() override; + static uint8_t *format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories); }; @@ -233,6 +248,11 @@ uint64_t FileSystemTemplate::size() { return store->size(); } +template +uint8_t *FileSystemTemplate::buff() { + return (uint8_t*) store; +} + #ifdef _MSC_VER #pragma warning(disable:4244) #endif diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index 273958e17..7078f0db7 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -35,7 +35,7 @@ char *loadFileBuff(FILE *file, ::size_t *sizeOut = nullptr) { fseek(file, 0, SEEK_END); const auto size = ftell(file); rewind(file); - auto buff = (char*) malloc(size); + auto buff = new char[size]; auto itemsRead = fread(buff, size, 1, file); fclose(file); if (sizeOut) { @@ -87,7 +87,7 @@ int format(int argc, char **args) { auto type = ox_atoi(args[2]); auto size = bytes(args[3]); auto path = args[4]; - auto buff = (uint8_t*) malloc(size); + auto buff = new uint8_t[size]; if (size < sizeof(FileStore64)) { @@ -125,7 +125,7 @@ int format(int argc, char **args) { } } - free(buff); + delete []buff; if (err == 0) { fprintf(stderr, "Created file system %s\n", path); @@ -160,7 +160,7 @@ int read(int argc, char **args) { } delete fs; - free(fsBuff); + delete []fsBuff; } else { fprintf(stderr, "Invalid file system type: %d.\n", *(uint32_t*) fsBuff); } @@ -199,16 +199,8 @@ int write(int argc, char **args, bool expand) { if (fs) { if (expand && fs->available() <= srcSize) { auto needed = fs->size() + fs->spaceNeeded(inode, srcSize); - auto cloneBuff = new uint8_t[needed]; - ox_memcpy(cloneBuff, fsBuff, fsSize); - - delete fs; - delete []fsBuff; - - fsBuff = cloneBuff; - fs = createFileSystem(fsBuff); fsSize = needed; - fs->resize(fsSize); + fs = expandCopyCleanup(fs, needed); } err |= fs->write(inode, srcBuff, srcSize); @@ -239,7 +231,7 @@ int write(int argc, char **args, bool expand) { err = 1; } } - free(srcBuff); + delete []fsBuff; } else { err = 1; fprintf(stderr, "Could not load source file: %s.\n", srcPath); @@ -285,7 +277,7 @@ int compact(int argc, char **args) { } delete fs; - free(fsBuff); + delete []fsBuff; } else { fprintf(stderr, "Could not open file: %s\n", fsPath); } @@ -328,7 +320,7 @@ int remove(int argc, char **args) { } delete fs; - free(fsBuff); + delete []fsBuff; } else { fprintf(stderr, "Could not open file: %s\n", fsPath); } From 75e4aaa3b4234a3267b422f2175db0e7fa0e40e7 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 13 Apr 2017 03:19:53 -0500 Subject: [PATCH 20/45] Make clargs use std::string --- src/ox/clargs/clargs.cpp | 2 +- src/ox/clargs/clargs.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ox/clargs/clargs.cpp b/src/ox/clargs/clargs.cpp index cf32e861b..82e1f2b0a 100644 --- a/src/ox/clargs/clargs.cpp +++ b/src/ox/clargs/clargs.cpp @@ -44,7 +44,7 @@ bool ClArgs::getBool(const char *arg) { return m_bools[arg]; } -const char *ClArgs::getString(const char *arg) { +string ClArgs::getString(const char *arg) { return m_strings[arg]; } diff --git a/src/ox/clargs/clargs.hpp b/src/ox/clargs/clargs.hpp index 443f82a94..42acd120e 100644 --- a/src/ox/clargs/clargs.hpp +++ b/src/ox/clargs/clargs.hpp @@ -17,7 +17,7 @@ namespace clargs { class ClArgs { private: ::std::map<::std::string, bool> m_bools; - ::std::map<::std::string, const char*> m_strings; + ::std::map<::std::string, ::std::string> m_strings; ::std::map<::std::string, int> m_ints; public: @@ -25,7 +25,7 @@ class ClArgs { bool getBool(const char *arg); - const char *getString(const char *arg); + ::std::string getString(const char *arg); int getInt(const char *arg); }; From 5c02645036f732db1a0fafc06e098747602762bd Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 13 Apr 2017 03:39:40 -0500 Subject: [PATCH 21/45] Fix issues with clarg parsing bools --- src/ox/clargs/clargs.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/ox/clargs/clargs.cpp b/src/ox/clargs/clargs.cpp index 82e1f2b0a..999f47de6 100644 --- a/src/ox/clargs/clargs.cpp +++ b/src/ox/clargs/clargs.cpp @@ -12,7 +12,6 @@ namespace ox { namespace clargs { -using ::std::string; using namespace ::std; ClArgs::ClArgs(int argc, const char **args) { @@ -22,17 +21,17 @@ ClArgs::ClArgs(int argc, const char **args) { while (arg[0] == '-' && arg.size()) { arg = arg.substr(1); } - m_bools[arg.c_str()] = true; + m_bools[arg] = true; // parse additional arguments - if (i < argc) { + if (i < argc && args[i + 1]) { string val = args[i + 1]; - if (val[i] != '-') { + if (val.size() && val[i] != '-') { if (val == "false") { - m_bools[arg.c_str()] = false; + m_bools[arg] = false; } - m_strings[arg.c_str()] = val.c_str(); - m_ints[arg.c_str()] = ox_atoi(val.c_str()); + m_strings[arg] = val; + m_ints[arg] = ox_atoi(val.c_str()); i++; } } From 709cfbf7501c5a2c74c1df527af4babc04851459 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 13 Apr 2017 03:49:54 -0500 Subject: [PATCH 22/45] Remove inode parameter from space needed --- src/ox/fs/filestore.hpp | 4 ++-- src/ox/fs/filesystem.hpp | 8 ++++---- src/ox/fs/oxfstool.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 68bb747f4..6044d52c8 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -200,7 +200,7 @@ class FileStore { * @param size the size of the data to insert * @return the space currently available in this file store. */ - typename Header::FsSize_t spaceNeeded(InodeId_t id, typename Header::FsSize_t size); + typename Header::FsSize_t spaceNeeded(typename Header::FsSize_t size); /** * Returns the size of the file store. @@ -564,7 +564,7 @@ typename FileStore
::StatInfo FileStore
::stat(InodeId_t id) { } template -typename Header::FsSize_t FileStore
::spaceNeeded(InodeId_t id, typename Header::FsSize_t size) { +typename Header::FsSize_t FileStore
::spaceNeeded(typename Header::FsSize_t size) { return sizeof(Inode) + size; } diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index b3b97812e..f952bd1e3 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -46,7 +46,7 @@ class FileSystem { virtual FileStat stat(uint64_t inode) = 0; - virtual uint64_t spaceNeeded(uint64_t id, uint64_t size) = 0; + virtual uint64_t spaceNeeded(uint64_t size) = 0; virtual uint64_t available() = 0; @@ -124,7 +124,7 @@ class FileSystemTemplate: public FileSystem { FileStat stat(uint64_t inode) override; - uint64_t spaceNeeded(uint64_t id, uint64_t size) override; + uint64_t spaceNeeded(uint64_t size) override; uint64_t available() override; @@ -234,8 +234,8 @@ void FileSystemTemplate::resize(uint64_t size) { } template -uint64_t FileSystemTemplate::spaceNeeded(uint64_t id, uint64_t size) { - return store->spaceNeeded(id, size); +uint64_t FileSystemTemplate::spaceNeeded(uint64_t size) { + return store->spaceNeeded(size); } template diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index d9bd874ef..1ce738242 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -198,7 +198,7 @@ int write(int argc, char **args, bool expand) { auto fs = createFileSystem(fsBuff, fsSize); if (fs) { if (expand && fs->available() <= srcSize) { - auto needed = fs->size() + fs->spaceNeeded(inode, srcSize); + auto needed = fs->size() + fs->spaceNeeded(srcSize); fsSize = needed; fs = expandCopyCleanup(fs, needed); } From c6e33e5285abf27182d932815d85ddb9baf23903 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 13 Apr 2017 04:07:24 -0500 Subject: [PATCH 23/45] Fix error handling for opening an invalid file system --- src/ox/fs/filesystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index 5a577c557..71bd3f3ed 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -34,7 +34,7 @@ FileSystem *createFileSystem(void *buff, size_t buffSize) { break; } - if (fs->size() > buffSize) { + if (fs && fs->size() > buffSize) { delete fs; fs = nullptr; } @@ -62,7 +62,7 @@ FileSystem *expandCopyCleanup(FileSystem *fs, size_t size) { auto out = expandCopy(fs, size); if (out) { - delete fs->buff(); + delete[] fs->buff(); delete fs; } else { out = fs; From 91838156349cd4bac3321068f9475200ec98cba7 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 13 Apr 2017 04:31:30 -0500 Subject: [PATCH 24/45] Fix GBA build not to build libraries that use stdlib --- CMakeLists.txt | 4 +++- scripts/setup_build | 2 +- src/ox/CMakeLists.txt | 4 +++- src/ox/fs/filesystem.cpp | 1 - 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d093272fb..ccc056f01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,9 +7,11 @@ include(address_sanitizer) set(OX_BUILD_EXEC "ON" CACHE STRING "Build executables (ON/OFF)") set(OX_RUN_TESTS "ON" CACHE STRING "Run tests (ON/OFF)") +set(OX_USE_STDLIB "ON" CACHE STRING "Build libraries that need the std lib (ON/OFF)") # can't run tests without building them -if(OX_BUILD_EXEC STREQUAL "OFF") +if(OX_BUILD_EXEC STREQUAL "OFF" OR OX_USE_STDLIB STREQUAL "OFF") + set(OX_BUILD_EXEC "OFF") set(OX_RUN_TESTS "OFF") endif() diff --git a/scripts/setup_build b/scripts/setup_build index 7826a3754..b61c9eb79 100755 --- a/scripts/setup_build +++ b/scripts/setup_build @@ -10,7 +10,7 @@ BUILD_TYPE=$2 if [[ $TARGET == windows ]]; then toolchain="-DCMAKE_TOOLCHAIN_FILE=cmake/Modules/Mingw.cmake" elif [[ $TARGET == gba ]]; then - toolchain="-DCMAKE_TOOLCHAIN_FILE=cmake/Modules/GBA.cmake -DOX_BUILD_EXEC=OFF" + toolchain="-DCMAKE_TOOLCHAIN_FILE=cmake/Modules/GBA.cmake -DOX_USE_STDLIB=OFF" fi if [[ $BUILD_TYPE == debug ]]; then diff --git a/src/ox/CMakeLists.txt b/src/ox/CMakeLists.txt index d0dd6848e..e77392db5 100644 --- a/src/ox/CMakeLists.txt +++ b/src/ox/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required(VERSION 2.8) -add_subdirectory(clargs) +if(OX_USE_STDLIB STREQUAL "ON") + add_subdirectory(clargs) +endif(OX_USE_STDLIB STREQUAL "ON") add_subdirectory(fs) add_subdirectory(std) diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index 71bd3f3ed..9294a16be 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -5,7 +5,6 @@ * 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/. */ -#include #include "filesystem.hpp" namespace ox { From bf110e5341189149aaed835a4db8e303111e3116 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 13 Apr 2017 20:16:42 -0500 Subject: [PATCH 25/45] Add a bounded read option for the file system --- src/ox/fs/filestore.hpp | 63 +++++++++++++++++++++++++++++++++------- src/ox/fs/filesystem.hpp | 39 +++++++++++++++++++------ src/ox/fs/oxfstool.cpp | 3 +- 3 files changed, 85 insertions(+), 20 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 6044d52c8..166f1f354 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -103,7 +103,7 @@ class FileStore { struct StatInfo { InodeId_t inodeId; - typename Header::FsSize_t size; + typename Header::FsSize_t size; uint8_t fileType; }; @@ -143,7 +143,7 @@ class FileStore { typename Header::FsSize_t getRight(); void setData(void *data, typename Header::FsSize_t size); - void *getData(); + uint8_t *getData(); }; Header m_header; @@ -186,6 +186,20 @@ class FileStore { */ int read(InodeId_t id, void *data, typename Header::FsSize_t *size); + /** + * Reads the "file" at the given id. You are responsible for freeing + * the data when done with it. + * @param id id of the "file" + * @param readStart where in the data to start reading + * @param readSize how much data to read + * @param data pointer to the pointer where the data is stored + * @param size pointer to a value that will be assigned the size of data + * @return 0 if read is a success + */ + int read(InodeId_t id, typename Header::FsSize_t readStart, + typename Header::FsSize_t readSize, void *data, + typename Header::FsSize_t *size); + /** * Reads the stat information of the inode of the given inode id. * If the returned inode id is 0, then the requested inode was not found. @@ -240,6 +254,20 @@ class FileStore { */ Inode *getInodeParent(Inode *root, InodeId_t id, typename Header::FsSize_t targetAddr); + /** + * Reads the "file" at the given id. You are responsible for freeing + * the data when done with it. + * @param inode inode of the "file" + * @param readStart where in the data to start reading + * @param readSize how much data to read + * @param data pointer to the pointer where the data is stored + * @param size pointer to a value that will be assigned the size of data + * @return 0 if read is a success + */ + int read(Inode *inode, typename Header::FsSize_t readStart, + typename Header::FsSize_t readSize, void *data, + typename Header::FsSize_t *size); + /** * Removes the inode of the given ID. * @param id the id of the file @@ -391,8 +419,8 @@ void FileStore
::Inode::setData(void *data, typename Header::FsSize_t siz template -void *FileStore
::Inode::getData() { - return this + 1; +uint8_t *FileStore
::Inode::getData() { + return (uint8_t*) (this + 1); } @@ -538,14 +566,29 @@ void FileStore
::updateInodeAddress(InodeId_t id, typename Header::FsSize template int FileStore
::read(InodeId_t id, void *data, typename Header::FsSize_t *size) { auto inode = getInode(ptr(m_header.getRootInode()), id); + return inode ? read(inode, 0, inode->getDataLen(), data, size) : 1; +} + +template +int FileStore
::read(InodeId_t id, typename Header::FsSize_t readStart, + typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size) { + auto inode = getInode(ptr(m_header.getRootInode()), id); + return inode ? read(inode, readStart, readSize, data, size) : 1; +} + +template +int FileStore
::read(Inode *inode, typename Header::FsSize_t readStart, + typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size) { int retval = 1; - if (inode) { - if (size) { - *size = inode->getDataLen(); - } - ox_memcpy(data, inode->getData(), inode->getDataLen()); - retval = 0; + // be sure read size is not greater than what is available to read + if (inode->getDataLen() + readStart < readSize) { + readSize = inode->getDataLen(); } + if (size) { + *size = readSize; + } + ox_memcpy(data, inode->getData() + readStart, inode->getDataLen()); + retval = 0; return retval; } diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index f952bd1e3..bb06d0234 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -34,7 +34,9 @@ class FileSystem { public: virtual ~FileSystem() {}; - virtual int read(uint64_t inode, void *buffer, size_t size) = 0; + virtual int read(uint64_t inode, void *buffer, size_t *size) = 0; + + virtual int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) = 0; virtual uint8_t *read(uint64_t inode, size_t *size) = 0; @@ -110,9 +112,11 @@ class FileSystemTemplate: public FileSystem { int read(const char *path, void *buffer); - uint8_t *read(uint64_t inode, size_t *size) override; + int read(uint64_t inode, void *buffer, size_t *size) override; - int read(uint64_t inode, void *buffer, size_t size) override; + int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size); + + uint8_t *read(uint64_t inode, size_t *size) override; void resize(uint64_t size = 0) override; @@ -174,18 +178,35 @@ FileStat FileSystemTemplate::stat(uint64_t inode) { #pragma warning(disable:4244) #endif template -int FileSystemTemplate::read(uint64_t inode, void *buffer, size_t size) { - auto err = 1; - auto s = store->stat(inode); - if (size == s.size) { - err = store->read(inode, buffer, nullptr); +int FileSystemTemplate::read(uint64_t inode, void *buffer, size_t *size) { + if (size) { + auto stat = store->stat(inode); + *size = stat.size; } - return err; + return store->read(inode, buffer, nullptr); +; } #ifdef _MSC_VER #pragma warning(default:4244) #endif +#ifdef _MSC_VER +#pragma warning(disable:4244) +#endif +template +int FileSystemTemplate::read(uint64_t inode, size_t readStart, + size_t readSize, void *buffer, + size_t *size) { + if (size) { + auto stat = store->stat(inode); + *size = stat.size; + } + return store->read(inode, readStart, readSize, buffer, nullptr); +} +#ifdef _MSC_VER +#pragma warning(disable:4244) +#endif + #ifdef _MSC_VER #pragma warning(disable:4244) #endif diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index 1ce738242..9cf601f77 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -201,6 +201,7 @@ int write(int argc, char **args, bool expand) { auto needed = fs->size() + fs->spaceNeeded(srcSize); fsSize = needed; fs = expandCopyCleanup(fs, needed); + fsBuff = fs->buff(); } err |= fs->write(inode, srcBuff, srcSize); @@ -231,7 +232,7 @@ int write(int argc, char **args, bool expand) { err = 1; } } - delete []fsBuff; + delete []srcBuff; } else { err = 1; fprintf(stderr, "Could not load source file: %s.\n", srcPath); From b7775d3d820f76a776c44102a43a79e1a2e8eb28 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Fri, 14 Apr 2017 01:05:18 -0500 Subject: [PATCH 26/45] Fix override warning and fix buffer overflow check --- src/ox/fs/filestore.hpp | 18 ++++++++---------- src/ox/fs/filesystem.hpp | 16 ++++++++-------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 166f1f354..d3bcfeeea 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -197,8 +197,8 @@ class FileStore { * @return 0 if read is a success */ int read(InodeId_t id, typename Header::FsSize_t readStart, - typename Header::FsSize_t readSize, void *data, - typename Header::FsSize_t *size); + typename Header::FsSize_t readSize, void *data, + typename Header::FsSize_t *size); /** * Reads the stat information of the inode of the given inode id. @@ -265,8 +265,8 @@ class FileStore { * @return 0 if read is a success */ int read(Inode *inode, typename Header::FsSize_t readStart, - typename Header::FsSize_t readSize, void *data, - typename Header::FsSize_t *size); + typename Header::FsSize_t readSize, void *data, + typename Header::FsSize_t *size); /** * Removes the inode of the given ID. @@ -579,17 +579,15 @@ int FileStore
::read(InodeId_t id, typename Header::FsSize_t readStart, template int FileStore
::read(Inode *inode, typename Header::FsSize_t readStart, typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size) { - int retval = 1; // be sure read size is not greater than what is available to read - if (inode->getDataLen() + readStart < readSize) { - readSize = inode->getDataLen(); + if (inode->getDataLen() - readStart < readSize) { + readSize = inode->getDataLen() - readStart; } if (size) { *size = readSize; } - ox_memcpy(data, inode->getData() + readStart, inode->getDataLen()); - retval = 0; - return retval; + ox_memcpy(data, inode->getData() + readStart, readSize); + return 0; } template diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index bb06d0234..e31af75e9 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -34,7 +34,7 @@ class FileSystem { public: virtual ~FileSystem() {}; - virtual int read(uint64_t inode, void *buffer, size_t *size) = 0; + virtual int read(uint64_t inode, void *buffer, size_t size) = 0; virtual int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) = 0; @@ -112,9 +112,9 @@ class FileSystemTemplate: public FileSystem { int read(const char *path, void *buffer); - int read(uint64_t inode, void *buffer, size_t *size) override; + int read(uint64_t inode, void *buffer, size_t buffSize) override; - int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size); + int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) override; uint8_t *read(uint64_t inode, size_t *size) override; @@ -178,12 +178,12 @@ FileStat FileSystemTemplate::stat(uint64_t inode) { #pragma warning(disable:4244) #endif template -int FileSystemTemplate::read(uint64_t inode, void *buffer, size_t *size) { - if (size) { - auto stat = store->stat(inode); - *size = stat.size; +int FileSystemTemplate::read(uint64_t inode, void *buffer, size_t buffSize) { + auto stat = store->stat(inode); + if (stat.size <= buffSize) { + return store->read(inode, buffer, nullptr); } - return store->read(inode, buffer, nullptr); + return 0; ; } #ifdef _MSC_VER From aa1b3d0a7468ad67ec4eddc21aac5c126b3c8448 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 17 Apr 2017 21:58:02 -0500 Subject: [PATCH 27/45] Add alignment attributes to FS structs --- src/ox/fs/filestore.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index d3bcfeeea..c309f50bc 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -13,7 +13,7 @@ namespace ox { namespace fs { template -struct FileStoreHeader { +struct __attribute__((packed)) FileStoreHeader { public: typedef InodeId InodeId_t; typedef FsT FsSize_t; @@ -108,15 +108,17 @@ class FileStore { }; private: - struct Inode { + struct __attribute__((packed)) Inode { private: // the next Inode in memory - typename Header::FsSize_t m_prev, m_next; + typename Header::FsSize_t m_prev; + typename Header::FsSize_t m_next; typename Header::FsSize_t m_dataLen; InodeId_t m_id; uint8_t m_fileType; - typename Header::FsSize_t m_left, m_right; + typename Header::FsSize_t m_left; + typename Header::FsSize_t m_right; public: typename Header::FsSize_t size(); From 58400b950bbcfa60c8fcd2bbafd6118bd1c02964 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 18 Apr 2017 05:00:43 -0500 Subject: [PATCH 28/45] Add install directory GBA build setup --- scripts/setup_build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup_build b/scripts/setup_build index b61c9eb79..f416aa154 100755 --- a/scripts/setup_build +++ b/scripts/setup_build @@ -10,7 +10,7 @@ BUILD_TYPE=$2 if [[ $TARGET == windows ]]; then toolchain="-DCMAKE_TOOLCHAIN_FILE=cmake/Modules/Mingw.cmake" elif [[ $TARGET == gba ]]; then - toolchain="-DCMAKE_TOOLCHAIN_FILE=cmake/Modules/GBA.cmake -DOX_USE_STDLIB=OFF" + toolchain="-DCMAKE_TOOLCHAIN_FILE=cmake/Modules/GBA.cmake -DOX_USE_STDLIB=OFF -DCMAKE_INSTALL_PREFIX=$DEVKITARM" fi if [[ $BUILD_TYPE == debug ]]; then From 6e690ee98dc263d9fff72aafb7cfd1a00d8aafea Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 18 Apr 2017 17:18:08 -0500 Subject: [PATCH 29/45] Add support for reading from FileStore by type --- src/ox/fs/filestore.hpp | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index c309f50bc..f21512fb2 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -202,6 +202,21 @@ class FileStore { typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size); + /** + * Reads the "file" at the given id. You are responsible for freeing + * the data when done with it. + * @param id id of the "file" + * @param readStart where in the data to start reading + * @param readSize how much data to read + * @param data pointer to the pointer where the data is stored + * @param size pointer to a value that will be assigned the size of data + * @return 0 if read is a success + */ + template + int read(InodeId_t id, typename Header::FsSize_t readStart, + typename Header::FsSize_t readSize, T *data, + typename Header::FsSize_t *size); + /** * Reads the stat information of the inode of the given inode id. * If the returned inode id is 0, then the requested inode was not found. @@ -266,8 +281,9 @@ class FileStore { * @param size pointer to a value that will be assigned the size of data * @return 0 if read is a success */ + template int read(Inode *inode, typename Header::FsSize_t readStart, - typename Header::FsSize_t readSize, void *data, + typename Header::FsSize_t readSize, T *data, typename Header::FsSize_t *size); /** @@ -568,19 +584,28 @@ void FileStore
::updateInodeAddress(InodeId_t id, typename Header::FsSize template int FileStore
::read(InodeId_t id, void *data, typename Header::FsSize_t *size) { auto inode = getInode(ptr(m_header.getRootInode()), id); - return inode ? read(inode, 0, inode->getDataLen(), data, size) : 1; + return inode ? read(inode, 0, inode->getDataLen(), (uint8_t*) data, size) : 1; } template int FileStore
::read(InodeId_t id, typename Header::FsSize_t readStart, typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size) { auto inode = getInode(ptr(m_header.getRootInode()), id); + return inode ? read(inode, readStart, readSize, (uint8_t*) data, size) : 1; +} + +template +template +int FileStore
::read(InodeId_t id, typename Header::FsSize_t readStart, + typename Header::FsSize_t readSize, T *data, typename Header::FsSize_t *size) { + auto inode = getInode(ptr(m_header.getRootInode()), id); return inode ? read(inode, readStart, readSize, data, size) : 1; } template +template int FileStore
::read(Inode *inode, typename Header::FsSize_t readStart, - typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size) { + typename Header::FsSize_t readSize, T *data, typename Header::FsSize_t *size) { // be sure read size is not greater than what is available to read if (inode->getDataLen() - readStart < readSize) { readSize = inode->getDataLen() - readStart; @@ -588,7 +613,12 @@ int FileStore
::read(Inode *inode, typename Header::FsSize_t readStart, if (size) { *size = readSize; } - ox_memcpy(data, inode->getData() + readStart, readSize); + + readSize /= sizeof(T); + T *it = (T*) &(inode->getData()[readStart]); + for (typename Header::FsSize_t i = 0; i < readSize; i++) { + *(data++) = *(it++); + } return 0; } From e3ff37c6c99977e7de6956507d6a2558cc12f96e Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 18 Apr 2017 17:20:13 -0500 Subject: [PATCH 30/45] Make FileSystem constructor explicit --- src/ox/fs/filesystem.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index e31af75e9..8146f92ca 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -106,7 +106,7 @@ class FileSystemTemplate: public FileSystem { FileStore *store = nullptr; public: - FileSystemTemplate(void *buff); + explicit FileSystemTemplate(void *buff); int mkdir(const char *path); From e976fd3fe62c98be29c4389ba6700a4a1fb8e0ae Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 18 Apr 2017 17:24:41 -0500 Subject: [PATCH 31/45] Upgrade FileStore format verion due to addition of packed attribute --- src/ox/fs/filestore.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index f21512fb2..a6319c463 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -17,7 +17,7 @@ struct __attribute__((packed)) FileStoreHeader { public: typedef InodeId InodeId_t; typedef FsT FsSize_t; - const static auto VERSION = 4; + const static auto VERSION = 5; private: uint16_t m_version; From 87c265e17bb94c5f46c8b9df3a2fcc13b6b43747 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 19 Apr 2017 00:58:14 -0500 Subject: [PATCH 32/45] Put FileSystem format version bump in createFileSystem --- src/ox/fs/filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index 9294a16be..ccc57173a 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -16,7 +16,7 @@ FileSystem *createFileSystem(void *buff, size_t buffSize) { FileSystem *fs = nullptr; switch (version) { - case 4: + case 5: switch (type) { case ox::fs::OxFS_16: fs = new FileSystem16(buff); From 7bce077ea81d7dbe10f7ba33eec0e061453f3f12 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Fri, 21 Apr 2017 05:37:24 -0500 Subject: [PATCH 33/45] Made libraries use position indepentent code (PIC) --- src/ox/clargs/CMakeLists.txt | 7 +++++++ src/ox/fs/CMakeLists.txt | 7 +++++++ src/ox/std/CMakeLists.txt | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/src/ox/clargs/CMakeLists.txt b/src/ox/clargs/CMakeLists.txt index 172c773ae..a096079cc 100644 --- a/src/ox/clargs/CMakeLists.txt +++ b/src/ox/clargs/CMakeLists.txt @@ -5,6 +5,13 @@ add_library( clargs.cpp ) +set_property( + TARGET + OxClArgs + PROPERTY + POSITION_INDEPENDENT_CODE ON +) + install( FILES clargs.hpp diff --git a/src/ox/fs/CMakeLists.txt b/src/ox/fs/CMakeLists.txt index c7cd44c28..5b95186dc 100644 --- a/src/ox/fs/CMakeLists.txt +++ b/src/ox/fs/CMakeLists.txt @@ -5,6 +5,13 @@ add_library( filesystem.cpp ) +set_property( + TARGET + OxFS + PROPERTY + POSITION_INDEPENDENT_CODE ON +) + if(OX_BUILD_EXEC STREQUAL "ON") add_executable( oxfstool diff --git a/src/ox/std/CMakeLists.txt b/src/ox/std/CMakeLists.txt index c0d2f10e2..70d68550f 100644 --- a/src/ox/std/CMakeLists.txt +++ b/src/ox/std/CMakeLists.txt @@ -7,6 +7,13 @@ add_library( strops.cpp ) +set_property( + TARGET + OxStd + PROPERTY + POSITION_INDEPENDENT_CODE ON +) + install( FILES byteswap.hpp From 5936a751d3a7bb14d79267f274c2a9187435666d Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 22 Apr 2017 01:27:26 -0500 Subject: [PATCH 34/45] Add PathIterator class for file system --- src/ox/fs/CMakeLists.txt | 2 + src/ox/fs/filesystem.hpp | 17 ++++++-- src/ox/fs/pathiterator.cpp | 39 +++++++++++++++++ src/ox/fs/pathiterator.hpp | 29 +++++++++++++ src/ox/fs/test/CMakeLists.txt | 9 ++++ src/ox/fs/test/tests.cpp | 76 +++++++++++++++++++++++++++++++++ src/ox/std/strops.cpp | 22 +++++++++- src/ox/std/strops.hpp | 4 ++ src/ox/std/test/CMakeLists.txt | 1 + src/ox/std/test/strops_test.cpp | 6 +++ 10 files changed, 200 insertions(+), 5 deletions(-) create mode 100644 src/ox/fs/pathiterator.cpp create mode 100644 src/ox/fs/pathiterator.hpp create mode 100644 src/ox/fs/test/tests.cpp diff --git a/src/ox/fs/CMakeLists.txt b/src/ox/fs/CMakeLists.txt index 5b95186dc..e318f0581 100644 --- a/src/ox/fs/CMakeLists.txt +++ b/src/ox/fs/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8) add_library( OxFS filesystem.cpp + pathiterator.cpp ) set_property( @@ -26,6 +27,7 @@ install( filestore.hpp filesystem.hpp inodemgr.hpp + pathiterator.hpp DESTINATION include/ox/fs ) diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index 8146f92ca..fd4f83fd8 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -74,7 +74,7 @@ template class FileSystemTemplate: public FileSystem { private: - struct DirectoryEntry { + struct __attribute__((packed)) DirectoryEntry { typename FileStore::InodeId_t inode; char *getName() { @@ -89,7 +89,7 @@ class FileSystemTemplate: public FileSystem { } }; - struct Directory { + struct __attribute__((packed)) Directory { /** * Number of files in this directory. */ @@ -110,7 +110,7 @@ class FileSystemTemplate: public FileSystem { int mkdir(const char *path); - int read(const char *path, void *buffer); + int read(const char *path, void *buffer, size_t buffSize); int read(uint64_t inode, void *buffer, size_t buffSize) override; @@ -174,6 +174,17 @@ FileStat FileSystemTemplate::stat(uint64_t inode) { #pragma warning(default:4244) #endif +#ifdef _MSC_VER +#pragma warning(disable:4244) +#endif +template +int FileSystemTemplate::read(const char *path, void *buffer, size_t buffSize) { + return 0; +} +#ifdef _MSC_VER +#pragma warning(default:4244) +#endif + #ifdef _MSC_VER #pragma warning(disable:4244) #endif diff --git a/src/ox/fs/pathiterator.cpp b/src/ox/fs/pathiterator.cpp new file mode 100644 index 000000000..a667a1098 --- /dev/null +++ b/src/ox/fs/pathiterator.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2015 - 2017 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/. + */ + +#include +#include +#include "pathiterator.hpp" + +namespace ox { +namespace fs { + +PathIterator::PathIterator(const char *path, size_t maxSize) { + m_path = path; + m_maxSize = maxSize; +} + +int PathIterator::next(char *pathOut, size_t pathOutSize) { + int size = 0; + const char *substr = ox_strchar(m_path + m_iterator, '/', m_maxSize - m_iterator); + m_iterator = (substr - m_path) + 1; + if (substr && m_iterator < m_maxSize) { + int start = m_iterator; + int end = (ox_strchar(m_path + start, '/', m_maxSize - start) - m_path); + if (end < 0) { + end = m_maxSize; + } + size = end - start; + ox_memcpy(pathOut, &m_path[start], size); + } + pathOut[size] = 0; // end with null terminator + return 0; +} + +} +} diff --git a/src/ox/fs/pathiterator.hpp b/src/ox/fs/pathiterator.hpp new file mode 100644 index 000000000..85a9ae939 --- /dev/null +++ b/src/ox/fs/pathiterator.hpp @@ -0,0 +1,29 @@ +/* + * Copyright 2015 - 2017 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 { + +class PathIterator { + private: + const char *m_path = nullptr; + int m_iterator = 0; + int m_maxSize = 0; + + public: + PathIterator(const char *path, size_t maxSize); + + int next(char *pathOut, size_t pathOutSize); +}; + +} +} diff --git a/src/ox/fs/test/CMakeLists.txt b/src/ox/fs/test/CMakeLists.txt index 9114a83e8..aeb7ad754 100644 --- a/src/ox/fs/test/CMakeLists.txt +++ b/src/ox/fs/test/CMakeLists.txt @@ -15,10 +15,19 @@ add_executable( filestoreio.cpp ) +add_executable( + FSTests + tests.cpp +) + target_link_libraries(FileStoreFormat OxFS OxStd) target_link_libraries(FileSystemFormat OxFS OxStd) target_link_libraries(FileStoreIO OxFS OxStd) +target_link_libraries(FSTests OxFS OxStd) add_test("FileStoreFormat" FileStoreFormat) add_test("FileSystemFormat" FileSystemFormat) add_test("FileStoreIO" FileStoreIO) +add_test("Test\\ PathIterator1" FSTests PathIterator1) +add_test("Test\\ PathIterator2" FSTests PathIterator2) +add_test("Test\\ PathIterator3" FSTests PathIterator3) diff --git a/src/ox/fs/test/tests.cpp b/src/ox/fs/test/tests.cpp new file mode 100644 index 000000000..e2b0e555a --- /dev/null +++ b/src/ox/fs/test/tests.cpp @@ -0,0 +1,76 @@ +/* + * Copyright 2015 - 2017 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/. + */ + +#include +#include +#include +#include +#include + +using namespace std; +using namespace ox::fs; +using namespace ox::std; + +map tests = { + { + { + "PathIterator1", + [](string) { + int retval = 0; + string path = "/usr/share/charset.gbag"; + PathIterator it(path.c_str(), path.size()); + const auto buffSize = path.size() + 1; + char buff[buffSize]; + retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "usr") == 0); + retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "share") == 0); + retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "charset.gbag") == 0); + return retval; + } + }, + { + "PathIterator2", + [](string) { + int retval = 0; + string path = "/usr/share/"; + PathIterator it(path.c_str(), path.size()); + const auto buffSize = path.size() + 1; + char buff[buffSize]; + retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "usr") == 0); + retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "share") == 0); + return retval; + } + }, + { + "PathIterator3", + [](string) { + int retval = 0; + string path = "/"; + PathIterator it(path.c_str(), path.size()); + const auto buffSize = path.size() + 1; + char buff[buffSize]; + retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "\0") == 0); + return retval; + } + }, + }, +}; + +int main(int argc, const char **args) { + int retval = -1; + if (argc > 1) { + auto testName = args[1]; + string testArg = ""; + if (args[2]) { + testArg = args[2]; + } + if (tests.find(testName) != tests.end()) { + retval = tests[testName](testArg); + } + } + return retval; +} diff --git a/src/ox/std/strops.cpp b/src/ox/std/strops.cpp index 83b7085be..f82984037 100644 --- a/src/ox/std/strops.cpp +++ b/src/ox/std/strops.cpp @@ -11,7 +11,7 @@ int ox_strcmp(const char *str1, const char *str2) { auto retval = 0; auto i = 0; - do { + while (str1[i] || str2[i]) { if (str1[i] < str2[i]) { retval = -1; break; @@ -20,7 +20,7 @@ int ox_strcmp(const char *str1, const char *str2) { break; } i++; - } while (str1[i] || str2[i]); + } return retval; } @@ -30,6 +30,24 @@ int ox_strlen(const char *str1) { return len; } +const char *ox_strchar(const char *str, int character, size_t maxLen) { + for (size_t i = 0; i < maxLen && str[i]; i++) { + if (str[i] == character) { + return &str[i]; + } + } + return nullptr; +} + +char *ox_strchar(char *str, int character, size_t maxLen) { + for (size_t i = 0; i < maxLen && str[i]; i++) { + if (str[i] == character) { + return &str[i]; + } + } + return nullptr; +} + int ox_atoi(const char *str) { int total = 0; int multiplier = 1; diff --git a/src/ox/std/strops.hpp b/src/ox/std/strops.hpp index e91a7415a..e72130666 100644 --- a/src/ox/std/strops.hpp +++ b/src/ox/std/strops.hpp @@ -13,4 +13,8 @@ int ox_strcmp(const char *str1, const char *str2); int ox_strlen(const char *str1); +const char *ox_strchar(const char *str, int character, size_t maxLen = 0xFFFFFFFFFFFFFF); + +char *ox_strchar(char *str, int character, size_t maxLen = 0xFFFFFFFFFFFFFF); + int ox_atoi(const char *str); diff --git a/src/ox/std/test/CMakeLists.txt b/src/ox/std/test/CMakeLists.txt index 82f23987c..8926e2528 100644 --- a/src/ox/std/test/CMakeLists.txt +++ b/src/ox/std/test/CMakeLists.txt @@ -28,6 +28,7 @@ add_test("Test\\ ox_strcmp\\ hijk\\ !=\\ asdf" StrOpsTest "hijk > asdf") add_test("Test\\ ox_strcmp\\ read\\ !=\\ resize" StrOpsTest "read < resize") add_test("Test\\ ox_strcmp\\ resize\\ !=\\ read" StrOpsTest "resize > read") add_test("Test\\ ox_strcmp\\ resize\\ ==\\ resize" StrOpsTest "resize == resize") +add_test("Test\\ ox_strcmp\\ resize\\ ==\\ resize" StrOpsTest " == ") ################################################################################ diff --git a/src/ox/std/test/strops_test.cpp b/src/ox/std/test/strops_test.cpp index 8950b5b0d..770c291a5 100644 --- a/src/ox/std/test/strops_test.cpp +++ b/src/ox/std/test/strops_test.cpp @@ -43,6 +43,12 @@ map> tests = { return !(ox_strcmp("resize", "resize") == 0); } }, + { + " == ", + []() { + return !(ox_strcmp("", "") == 0); + } + }, }; int main(int argc, const char **args) { From a3fac6529b5926986e6ab4c6a459a91af5bfbffb Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 22 Apr 2017 01:40:38 -0500 Subject: [PATCH 35/45] Fix to build with GCC --- src/ox/fs/test/tests.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/ox/fs/test/tests.cpp b/src/ox/fs/test/tests.cpp index e2b0e555a..903efa69b 100644 --- a/src/ox/fs/test/tests.cpp +++ b/src/ox/fs/test/tests.cpp @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include #include #include #include @@ -24,11 +25,12 @@ map tests = { int retval = 0; string path = "/usr/share/charset.gbag"; PathIterator it(path.c_str(), path.size()); - const auto buffSize = path.size() + 1; + const auto buffSize = 1024; char buff[buffSize]; - retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "usr") == 0); - retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "share") == 0); - retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "charset.gbag") == 0); + assert(buffSize >= path.size()); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "usr") == 0); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "share") == 0); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "charset.gbag") == 0); return retval; } }, @@ -38,10 +40,11 @@ map tests = { int retval = 0; string path = "/usr/share/"; PathIterator it(path.c_str(), path.size()); - const auto buffSize = path.size() + 1; + const auto buffSize = 1024; char buff[buffSize]; - retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "usr") == 0); - retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "share") == 0); + assert(buffSize >= path.size()); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "usr") == 0); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "share") == 0); return retval; } }, @@ -51,9 +54,10 @@ map tests = { int retval = 0; string path = "/"; PathIterator it(path.c_str(), path.size()); - const auto buffSize = path.size() + 1; + const auto buffSize = 1024; char buff[buffSize]; - retval |= !(it.next(buff, buffSize) == 0 && ox_strcmp(buff, "\0") == 0); + assert(buffSize >= path.size()); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "\0") == 0); return retval; } }, From 1743b8ceba7ad5fa3b886fb310852fca90425bc4 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 22 Apr 2017 01:51:02 -0500 Subject: [PATCH 36/45] Reduce max string length for strops to fit 32 bit systems --- src/ox/std/strops.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ox/std/strops.hpp b/src/ox/std/strops.hpp index e72130666..efea25c4f 100644 --- a/src/ox/std/strops.hpp +++ b/src/ox/std/strops.hpp @@ -13,8 +13,8 @@ int ox_strcmp(const char *str1, const char *str2); int ox_strlen(const char *str1); -const char *ox_strchar(const char *str, int character, size_t maxLen = 0xFFFFFFFFFFFFFF); +const char *ox_strchar(const char *str, int character, size_t maxLen = 0xFFFFFFFF); -char *ox_strchar(char *str, int character, size_t maxLen = 0xFFFFFFFFFFFFFF); +char *ox_strchar(char *str, int character, size_t maxLen = 0xFFFFFFFF); int ox_atoi(const char *str); From d48183218c7dda1d6da715c017f2c0c73f108419 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 22 Apr 2017 02:50:58 -0500 Subject: [PATCH 37/45] Delete byteswap.cpp --- src/ox/std/CMakeLists.txt | 1 - src/ox/std/byteswap.cpp | 9 --------- 2 files changed, 10 deletions(-) delete mode 100644 src/ox/std/byteswap.cpp diff --git a/src/ox/std/CMakeLists.txt b/src/ox/std/CMakeLists.txt index 70d68550f..fe05c4d5f 100644 --- a/src/ox/std/CMakeLists.txt +++ b/src/ox/std/CMakeLists.txt @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 2.8) add_library( OxStd - byteswap.cpp memops.cpp strops.cpp ) diff --git a/src/ox/std/byteswap.cpp b/src/ox/std/byteswap.cpp deleted file mode 100644 index 68801f3d6..000000000 --- a/src/ox/std/byteswap.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2015 - 2017 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/. - */ - -#include "byteswap.hpp" From f9634a2f3a4cc0dc76e2eea96c9311e551346bd1 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 22 Apr 2017 07:11:48 -0500 Subject: [PATCH 38/45] Fix PathIterator for paths that don't end with / --- src/ox/fs/pathiterator.cpp | 25 +++++++++++++++---------- src/ox/fs/pathiterator.hpp | 4 ++-- src/ox/std/strops.cpp | 18 ++++++++++++++---- src/ox/std/strops.hpp | 7 +++++-- src/ox/std/test/CMakeLists.txt | 1 + src/ox/std/test/strops_test.cpp | 7 +++++++ 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/ox/fs/pathiterator.cpp b/src/ox/fs/pathiterator.cpp index a667a1098..17b7eca8d 100644 --- a/src/ox/fs/pathiterator.cpp +++ b/src/ox/fs/pathiterator.cpp @@ -19,17 +19,22 @@ PathIterator::PathIterator(const char *path, size_t maxSize) { } int PathIterator::next(char *pathOut, size_t pathOutSize) { - int size = 0; - const char *substr = ox_strchar(m_path + m_iterator, '/', m_maxSize - m_iterator); - m_iterator = (substr - m_path) + 1; - if (substr && m_iterator < m_maxSize) { - int start = m_iterator; - int end = (ox_strchar(m_path + start, '/', m_maxSize - start) - m_path); - if (end < 0) { - end = m_maxSize; + size_t size = 0; + const char *substr = ox_strchr(m_path + m_iterator, '/', m_maxSize - m_iterator); + if (substr) { + m_iterator = (substr - m_path) + 1; + if (m_iterator < m_maxSize) { + size_t start = m_iterator; + // end is at the next / + substr = ox_strchr(&m_path[start], '/', m_maxSize - start); + // correct end if it is invalid, which happens if there is no next / + if (!substr) { + substr = ox_strchr(&m_path[start], 0, m_maxSize - start); + } + size_t end = substr - m_path; + size = end - start; + ox_memcpy(pathOut, &m_path[start], size); } - size = end - start; - ox_memcpy(pathOut, &m_path[start], size); } pathOut[size] = 0; // end with null terminator return 0; diff --git a/src/ox/fs/pathiterator.hpp b/src/ox/fs/pathiterator.hpp index 85a9ae939..85de80c89 100644 --- a/src/ox/fs/pathiterator.hpp +++ b/src/ox/fs/pathiterator.hpp @@ -16,8 +16,8 @@ namespace fs { class PathIterator { private: const char *m_path = nullptr; - int m_iterator = 0; - int m_maxSize = 0; + size_t m_iterator = 0; + size_t m_maxSize = 0; public: PathIterator(const char *path, size_t maxSize); diff --git a/src/ox/std/strops.cpp b/src/ox/std/strops.cpp index f82984037..52b244ce6 100644 --- a/src/ox/std/strops.cpp +++ b/src/ox/std/strops.cpp @@ -30,19 +30,29 @@ int ox_strlen(const char *str1) { return len; } -const char *ox_strchar(const char *str, int character, size_t maxLen) { - for (size_t i = 0; i < maxLen && str[i]; i++) { +int ox_strlen(char *str1) { + int len; + for (len = 0; str1[len]; len++); + return len; +} + +const char *ox_strchr(const char *str, int character, size_t maxLen) { + for (size_t i = 0; i <= maxLen; i++) { if (str[i] == character) { return &str[i]; + } else if (str[i] == 0) { + return nullptr; } } return nullptr; } -char *ox_strchar(char *str, int character, size_t maxLen) { - for (size_t i = 0; i < maxLen && str[i]; i++) { +char *ox_strchr(char *str, int character, size_t maxLen) { + for (size_t i = 0; i < maxLen; i++) { if (str[i] == character) { return &str[i]; + } else if (str[i] == 0) { + return nullptr; } } return nullptr; diff --git a/src/ox/std/strops.hpp b/src/ox/std/strops.hpp index efea25c4f..80e574398 100644 --- a/src/ox/std/strops.hpp +++ b/src/ox/std/strops.hpp @@ -5,6 +5,7 @@ * 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 "types.hpp" @@ -13,8 +14,10 @@ int ox_strcmp(const char *str1, const char *str2); int ox_strlen(const char *str1); -const char *ox_strchar(const char *str, int character, size_t maxLen = 0xFFFFFFFF); +int ox_strlen(char *str1); -char *ox_strchar(char *str, int character, size_t maxLen = 0xFFFFFFFF); +const char *ox_strchr(const char *str, int character, size_t maxLen = 0xFFFFFFFF); + +char *ox_strchr(char *str, int character, size_t maxLen = 0xFFFFFFFF); int ox_atoi(const char *str); diff --git a/src/ox/std/test/CMakeLists.txt b/src/ox/std/test/CMakeLists.txt index 8926e2528..3bf8f2bf1 100644 --- a/src/ox/std/test/CMakeLists.txt +++ b/src/ox/std/test/CMakeLists.txt @@ -29,6 +29,7 @@ add_test("Test\\ ox_strcmp\\ read\\ !=\\ resize" StrOpsTest "read < resize") add_test("Test\\ ox_strcmp\\ resize\\ !=\\ read" StrOpsTest "resize > read") add_test("Test\\ ox_strcmp\\ resize\\ ==\\ resize" StrOpsTest "resize == resize") add_test("Test\\ ox_strcmp\\ resize\\ ==\\ resize" StrOpsTest " == ") +add_test("Test\\ ox_strchr\\ 0" StrOpsTest "ox_strchr 0") ################################################################################ diff --git a/src/ox/std/test/strops_test.cpp b/src/ox/std/test/strops_test.cpp index 770c291a5..963b0f486 100644 --- a/src/ox/std/test/strops_test.cpp +++ b/src/ox/std/test/strops_test.cpp @@ -49,6 +49,13 @@ map> tests = { return !(ox_strcmp("", "") == 0); } }, + { + "ox_strchr 0", + []() { + auto testStr = "asdf"; + return !(ox_strchr(testStr, 0, 4) == &testStr[4]); + } + }, }; int main(int argc, const char **args) { From c3fe5e9cc2deb266d1e2851f511e88c6211677a4 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 22 Apr 2017 14:34:20 -0500 Subject: [PATCH 39/45] Fix PathIterator to allow paths that don't start with / --- src/ox/fs/pathiterator.cpp | 32 +++++++++++++++++--------------- src/ox/fs/test/CMakeLists.txt | 1 + src/ox/fs/test/tests.cpp | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/ox/fs/pathiterator.cpp b/src/ox/fs/pathiterator.cpp index 17b7eca8d..596116959 100644 --- a/src/ox/fs/pathiterator.cpp +++ b/src/ox/fs/pathiterator.cpp @@ -20,24 +20,26 @@ PathIterator::PathIterator(const char *path, size_t maxSize) { int PathIterator::next(char *pathOut, size_t pathOutSize) { size_t size = 0; - const char *substr = ox_strchr(m_path + m_iterator, '/', m_maxSize - m_iterator); - if (substr) { - m_iterator = (substr - m_path) + 1; - if (m_iterator < m_maxSize) { - size_t start = m_iterator; - // end is at the next / - substr = ox_strchr(&m_path[start], '/', m_maxSize - start); - // correct end if it is invalid, which happens if there is no next / - if (!substr) { - substr = ox_strchr(&m_path[start], 0, m_maxSize - start); - } - size_t end = substr - m_path; - size = end - start; - ox_memcpy(pathOut, &m_path[start], size); + int retval = 1; + if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) { + retval = 0; + if (m_path[m_iterator] == '/') { + m_iterator++; } + size_t start = m_iterator; + // end is at the next / + const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start); + // correct end if it is invalid, which happens if there is no next / + if (!substr) { + substr = ox_strchr(&m_path[start], 0, m_maxSize - start); + } + size_t end = substr - m_path; + size = end - start; + ox_memcpy(pathOut, &m_path[start], size); } pathOut[size] = 0; // end with null terminator - return 0; + m_iterator += size; + return retval; } } diff --git a/src/ox/fs/test/CMakeLists.txt b/src/ox/fs/test/CMakeLists.txt index aeb7ad754..2ee7a32a5 100644 --- a/src/ox/fs/test/CMakeLists.txt +++ b/src/ox/fs/test/CMakeLists.txt @@ -31,3 +31,4 @@ add_test("FileStoreIO" FileStoreIO) add_test("Test\\ PathIterator1" FSTests PathIterator1) add_test("Test\\ PathIterator2" FSTests PathIterator2) add_test("Test\\ PathIterator3" FSTests PathIterator3) +add_test("Test\\ PathIterator4" FSTests PathIterator4) diff --git a/src/ox/fs/test/tests.cpp b/src/ox/fs/test/tests.cpp index 903efa69b..8e6607b88 100644 --- a/src/ox/fs/test/tests.cpp +++ b/src/ox/fs/test/tests.cpp @@ -19,7 +19,7 @@ using namespace ox::std; map tests = { { - { + { "PathIterator1", [](string) { int retval = 0; @@ -34,7 +34,7 @@ map tests = { return retval; } }, - { + { "PathIterator2", [](string) { int retval = 0; @@ -48,7 +48,7 @@ map tests = { return retval; } }, - { + { "PathIterator3", [](string) { int retval = 0; @@ -61,6 +61,35 @@ map tests = { return retval; } }, + { + "PathIterator4", + [](string) { + int retval = 0; + string path = "usr/share/charset.gbag"; + PathIterator it(path.c_str(), path.size()); + const auto buffSize = 1024; + char buff[buffSize]; + assert(buffSize >= path.size()); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "usr") == 0); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "share") == 0); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "charset.gbag") == 0); + return retval; + } + }, + { + "PathIterator5", + [](string) { + int retval = 0; + string path = "usr/share/"; + PathIterator it(path.c_str(), path.size()); + const auto buffSize = 1024; + char buff[buffSize]; + assert(buffSize >= path.size()); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "usr") == 0); + retval |= !(it.next(buff, path.size()) == 0 && ox_strcmp(buff, "share") == 0); + return retval; + } + }, }, }; From 32d50a42df5bd6baf93d3493ead8f9dfd3ac1d95 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sun, 23 Apr 2017 03:58:31 -0500 Subject: [PATCH 40/45] Fix oxfstool format to corrctly set the use directories setting --- src/ox/fs/oxfstool.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index 9cf601f77..d7a84da1d 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -99,13 +99,13 @@ int format(int argc, char **args) { // format switch (type) { case 16: - FileStore16::format(buff, (FileStore16::FsSize_t) size, ox::fs::OxFS_16); + FileStore16::format(buff, (FileStore16::FsSize_t) size, true); break; case 32: - FileStore32::format(buff, (FileStore32::FsSize_t) size, ox::fs::OxFS_32); + FileStore32::format(buff, (FileStore32::FsSize_t) size, true); break; case 64: - FileStore64::format(buff, size, ox::fs::OxFS_64); + FileStore64::format(buff, size, true); break; default: err = 1; From 7c54d3fb474f1d373475ab9bb155ee2063b9c9eb Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sun, 23 Apr 2017 04:10:12 -0500 Subject: [PATCH 41/45] Add initial support for looking up file by path --- src/ox/fs/filesystem.cpp | 1 + src/ox/fs/filesystem.hpp | 173 +++++++++++++++++++++++++++++----- src/ox/fs/pathiterator.cpp | 17 ++++ src/ox/fs/pathiterator.hpp | 5 + src/ox/fs/test/CMakeLists.txt | 3 + src/ox/fs/test/tests.cpp | 13 +++ 6 files changed, 186 insertions(+), 26 deletions(-) diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index ccc57173a..2fef1603a 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -5,6 +5,7 @@ * 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/. */ + #include "filesystem.hpp" namespace ox { diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index fd4f83fd8..cbd00ff94 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -8,6 +8,7 @@ #pragma once #include +#include "pathiterator.hpp" #include "filestore.hpp" namespace ox { @@ -34,6 +35,8 @@ class FileSystem { public: virtual ~FileSystem() {}; + virtual int read(const char *path, void *buffer, size_t buffSize) = 0; + virtual int read(uint64_t inode, void *buffer, size_t size) = 0; virtual int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) = 0; @@ -44,6 +47,8 @@ class FileSystem { virtual void resize(uint64_t size = 0) = 0; + virtual int write(const char *path, void *buffer, uint64_t size, uint8_t fileType = NormalFile) = 0; + virtual int write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType = NormalFile) = 0; virtual FileStat stat(uint64_t inode) = 0; @@ -87,6 +92,17 @@ class FileSystemTemplate: public FileSystem { ox_memcpy(data, &name, nameLen); data[nameLen] = 0; } + + /** + * The size in bytes. + */ + uint64_t size() { + return sizeof(DirectoryEntry) + ox_strlen(getName()); + } + + static uint64_t spaceNeeded(const char *fileName) { + return sizeof(DirectoryEntry) + ox_strlen(fileName); + } }; struct __attribute__((packed)) Directory { @@ -96,21 +112,23 @@ class FileSystemTemplate: public FileSystem { typename FileStore::InodeId_t size = 0; DirectoryEntry *files() { - return (DirectoryEntry*) (this + 1); + return size ? (DirectoryEntry*) (this + 1) : nullptr; } + + uint64_t getFileInode(const char *name, uint64_t buffSize); }; + FileStore *m_store = nullptr; + + public: // static members static typename FileStore::InodeId_t INODE_ROOT_DIR; - FileStore *store = nullptr; - - public: explicit FileSystemTemplate(void *buff); int mkdir(const char *path); - int read(const char *path, void *buffer, size_t buffSize); + int read(const char *path, void *buffer, size_t buffSize) override; int read(uint64_t inode, void *buffer, size_t buffSize) override; @@ -122,12 +140,16 @@ class FileSystemTemplate: public FileSystem { int remove(uint64_t inode) override; + int write(const char *path, void *buffer, uint64_t size, uint8_t fileType = NormalFile) override; + int write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType) override; FileStat stat(const char *path); FileStat stat(uint64_t inode) override; + uint64_t findInodeOf(const char *name); + uint64_t spaceNeeded(uint64_t size) override; uint64_t available() override; @@ -137,11 +159,14 @@ class FileSystemTemplate: public FileSystem { uint8_t *buff() override; static uint8_t *format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories); + + private: + int insertDirectoryEntry(uint64_t inode, const char *dirPath, const char *fileName); }; template FileSystemTemplate::FileSystemTemplate(void *buff) { - store = (FileStore*) buff; + m_store = (FileStore*) buff; } template @@ -164,7 +189,7 @@ FileStat FileSystemTemplate::stat(const char *path) { template FileStat FileSystemTemplate::stat(uint64_t inode) { FileStat stat; - auto s = store->stat(inode); + auto s = m_store->stat(inode); stat.size = s.size; stat.inode = s.inodeId; stat.fileType = s.fileType; @@ -179,7 +204,17 @@ FileStat FileSystemTemplate::stat(uint64_t inode) { #endif template int FileSystemTemplate::read(const char *path, void *buffer, size_t buffSize) { - return 0; + int retval = -1; + + // find the inode for the given path + auto inode = findInodeOf(path); + + // if inode exists, read the data into buffer + if (inode) { + read(inode, buffer, buffSize); + } + + return retval; } #ifdef _MSC_VER #pragma warning(default:4244) @@ -190,11 +225,11 @@ int FileSystemTemplate::read(const char *path, void *buffer, #endif template int FileSystemTemplate::read(uint64_t inode, void *buffer, size_t buffSize) { - auto stat = store->stat(inode); + auto stat = m_store->stat(inode); if (stat.size <= buffSize) { - return store->read(inode, buffer, nullptr); + return m_store->read(inode, buffer, nullptr); } - return 0; + return -1; ; } #ifdef _MSC_VER @@ -209,10 +244,10 @@ int FileSystemTemplate::read(uint64_t inode, size_t readStar size_t readSize, void *buffer, size_t *size) { if (size) { - auto stat = store->stat(inode); + auto stat = m_store->stat(inode); *size = stat.size; } - return store->read(inode, readStart, readSize, buffer, nullptr); + return m_store->read(inode, readStart, readSize, buffer, nullptr); } #ifdef _MSC_VER #pragma warning(disable:4244) @@ -223,12 +258,12 @@ int FileSystemTemplate::read(uint64_t inode, size_t readStar #endif template uint8_t *FileSystemTemplate::read(uint64_t inode, size_t *size) { - auto s = store->stat(inode); + auto s = m_store->stat(inode); auto buff = new uint8_t[s.size]; if (size) { *size = s.size; } - if (store->read(inode, buff, nullptr)) { + if (m_store->read(inode, buff, nullptr)) { delete []buff; buff = nullptr; } @@ -243,7 +278,28 @@ uint8_t *FileSystemTemplate::read(uint64_t inode, size_t *si #endif template int FileSystemTemplate::remove(uint64_t inode) { - return store->remove(inode); + return m_store->remove(inode); +} +#ifdef _MSC_VER +#pragma warning(default:4244) +#endif + +#ifdef _MSC_VER +#pragma warning(disable:4244) +#endif +template +int FileSystemTemplate::write(const char *path, void *buffer, uint64_t size, uint8_t fileType) { + int retval = -1; + + // find the inode for the given path + auto inode = findInodeOf(path); + + // if inode exists, read the data into buffer + if (inode) { + retval = write(inode, buffer, size, fileType); + } + + return retval; } #ifdef _MSC_VER #pragma warning(default:4244) @@ -254,7 +310,44 @@ int FileSystemTemplate::remove(uint64_t inode) { #endif template int FileSystemTemplate::write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType) { - return store->write(inode, buffer, size, fileType); + return m_store->write(inode, buffer, size, fileType); +} +#ifdef _MSC_VER +#pragma warning(default:4244) +#endif + +#ifdef _MSC_VER +#pragma warning(disable:4244) +#endif +template +uint64_t FileSystemTemplate::findInodeOf(const char *path) { + const auto pathLen = ox_strlen(path); + PathIterator it(path, pathLen); + char fileName[pathLen]; + uint64_t inode = INODE_ROOT_DIR; + while (inode) { + auto dirStat = m_store->stat(inode); + if (dirStat.size >= sizeof(Directory)) { + uint8_t dirBuffer[dirStat.size]; + auto dir = (Directory*) dirBuffer; + if (read(inode, dirBuffer, dirStat.size) == 0) { + if (dirStat.fileType == FileType::Directory && it.next(fileName, pathLen) == 0) { + if (!it.hasNext()) { + // no further name components, inode points to the correct file + break; + } + inode = dir->getFileInode(fileName, dirStat.size); + } else { + inode = 0; // null out inode and break + } + } else { + inode = 0; // null out inode and break + } + } else { + inode = 0; // null out inode and break + } + } + return inode; } #ifdef _MSC_VER #pragma warning(default:4244) @@ -262,27 +355,27 @@ int FileSystemTemplate::write(uint64_t inode, void *buffer, template void FileSystemTemplate::resize(uint64_t size) { - return store->resize(size); + return m_store->resize(size); } template uint64_t FileSystemTemplate::spaceNeeded(uint64_t size) { - return store->spaceNeeded(size); + return m_store->spaceNeeded(size); } template uint64_t FileSystemTemplate::available() { - return store->available(); + return m_store->available(); } template uint64_t FileSystemTemplate::size() { - return store->size(); + return m_store->size(); } template uint8_t *FileSystemTemplate::buff() { - return (uint8_t*) store; + return (uint8_t*) m_store; } #ifdef _MSC_VER @@ -294,10 +387,8 @@ uint8_t *FileSystemTemplate::format(void *buffer, typename F FileSystemTemplate fs(buffer); if (buffer && useDirectories) { - char dirBuff[sizeof(Directory) + sizeof(DirectoryEntry) + 2]; - auto *dir = (Directory*) dirBuff; - dir->files(); - fs.write(INODE_ROOT_DIR, dirBuff, useDirectories, FileType::Directory); + Directory dir; + fs.write(INODE_ROOT_DIR, &dir, sizeof(dir), FileType::Directory); } return (uint8_t*) buffer; @@ -306,6 +397,36 @@ uint8_t *FileSystemTemplate::format(void *buffer, typename F #pragma warning(default:4244) #endif +#ifdef _MSC_VER +#pragma warning(disable:4244) +#endif +template +int FileSystemTemplate::insertDirectoryEntry(uint64_t inode, const char *dirPath, const char *fileName) { + return 0; +} +#ifdef _MSC_VER +#pragma warning(default:4244) +#endif + +// Directory + +template +uint64_t FileSystemTemplate::Directory::getFileInode(const char *name, uint64_t buffSize) { + uint64_t retval = 0; + auto current = files(); + if (current) { + auto end = (DirectoryEntry*) ((uint8_t*) files()) + buffSize; + while (current && ox_strcmp(current->getName(), name) != 0) { + current = (DirectoryEntry*) ((uint8_t*) current) + current->size(); + if (current < end) { + current = nullptr; + } + } + retval = current->inode; + } + return retval; +} + typedef FileSystemTemplate FileSystem16; typedef FileSystemTemplate FileSystem32; typedef FileSystemTemplate FileSystem64; diff --git a/src/ox/fs/pathiterator.cpp b/src/ox/fs/pathiterator.cpp index 596116959..c53fd8fb1 100644 --- a/src/ox/fs/pathiterator.cpp +++ b/src/ox/fs/pathiterator.cpp @@ -42,5 +42,22 @@ int PathIterator::next(char *pathOut, size_t pathOutSize) { return retval; } +bool PathIterator::hasNext() { + size_t size = 0; + if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) { + size_t start = m_iterator; + // end is at the next / + const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start); + // correct end if it is invalid, which happens if there is no next / + if (!substr) { + substr = ox_strchr(&m_path[start], 0, m_maxSize - start); + } + size_t end = substr - m_path; + size = end - start; + } + m_iterator += size; + return size > 0; +} + } } diff --git a/src/ox/fs/pathiterator.hpp b/src/ox/fs/pathiterator.hpp index 85de80c89..4c4921c99 100644 --- a/src/ox/fs/pathiterator.hpp +++ b/src/ox/fs/pathiterator.hpp @@ -22,7 +22,12 @@ class PathIterator { public: PathIterator(const char *path, size_t maxSize); + /** + * @return 0 if no error + */ int next(char *pathOut, size_t pathOutSize); + + bool hasNext(); }; } diff --git a/src/ox/fs/test/CMakeLists.txt b/src/ox/fs/test/CMakeLists.txt index 2ee7a32a5..d95fc0051 100644 --- a/src/ox/fs/test/CMakeLists.txt +++ b/src/ox/fs/test/CMakeLists.txt @@ -32,3 +32,6 @@ add_test("Test\\ PathIterator1" FSTests PathIterator1) add_test("Test\\ PathIterator2" FSTests PathIterator2) add_test("Test\\ PathIterator3" FSTests PathIterator3) add_test("Test\\ PathIterator4" FSTests PathIterator4) +add_test("Test\\ PathIterator5" FSTests PathIterator5) + +add_test("Test\\ FileSystem32::findInodeOf" FSTests FileSystem32::findInodeOf) diff --git a/src/ox/fs/test/tests.cpp b/src/ox/fs/test/tests.cpp index 8e6607b88..9c6072f74 100644 --- a/src/ox/fs/test/tests.cpp +++ b/src/ox/fs/test/tests.cpp @@ -90,6 +90,19 @@ map tests = { return retval; } }, + { + "FileSystem32::findInodeOf", + [](string) { + int retval = 0; + const auto size = 1024; + uint8_t buff[size]; + FileSystem32::format(buff, (FileStore32::FsSize_t) size, true); + auto fs = (FileSystem32*) createFileSystem(buff, size); + retval |= !(fs->findInodeOf("/") == FileSystem32::INODE_ROOT_DIR); + delete fs; + return retval; + } + }, }, }; From 7abbf8768f6266455303ed7eed027aaaeb1d1ba8 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 24 Apr 2017 02:38:23 -0500 Subject: [PATCH 42/45] Add support for writing file by path --- src/ox/fs/filesystem.hpp | 94 ++++++++++++++++++++++++--------- src/ox/fs/pathiterator.cpp | 39 +++++++++++++- src/ox/fs/pathiterator.hpp | 10 ++++ src/ox/fs/test/CMakeLists.txt | 16 +++--- src/ox/fs/test/tests.cpp | 64 +++++++++++++++++++--- src/ox/std/CMakeLists.txt | 1 + src/ox/std/bitops.hpp | 19 +++++++ src/ox/std/random.cpp | 39 ++++++++++++++ src/ox/std/random.hpp | 30 +++++++++++ src/ox/std/std.hpp | 2 + src/ox/std/strops.cpp | 20 +++++++ src/ox/std/strops.hpp | 4 ++ src/ox/std/test/CMakeLists.txt | 1 + src/ox/std/test/strops_test.cpp | 10 ++++ 14 files changed, 308 insertions(+), 41 deletions(-) create mode 100644 src/ox/std/bitops.hpp create mode 100644 src/ox/std/random.cpp create mode 100644 src/ox/std/random.hpp diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index cbd00ff94..a6b71b43d 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -89,7 +89,7 @@ class FileSystemTemplate: public FileSystem { void setName(const char *name) { auto data = getName(); auto nameLen = ox_strlen(name); - ox_memcpy(data, &name, nameLen); + ox_memcpy(data, name, nameLen); data[nameLen] = 0; } @@ -101,7 +101,7 @@ class FileSystemTemplate: public FileSystem { } static uint64_t spaceNeeded(const char *fileName) { - return sizeof(DirectoryEntry) + ox_strlen(fileName); + return sizeof(DirectoryEntry) + ox_strlen(fileName) + 1; } }; @@ -109,7 +109,7 @@ class FileSystemTemplate: public FileSystem { /** * Number of files in this directory. */ - typename FileStore::InodeId_t size = 0; + typename FileStore::FsSize_t size = 0; DirectoryEntry *files() { return size ? (DirectoryEntry*) (this + 1) : nullptr; @@ -161,7 +161,7 @@ class FileSystemTemplate: public FileSystem { static uint8_t *format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories); private: - int insertDirectoryEntry(uint64_t inode, const char *dirPath, const char *fileName); + int insertDirectoryEntry(const char *dirPath, const char *fileName, uint64_t inode); }; template @@ -179,7 +179,12 @@ int FileSystemTemplate::mkdir(const char *path) { template FileStat FileSystemTemplate::stat(const char *path) { + auto inode = findInodeOf(path); FileStat stat; + auto s = m_store->stat(inode); + stat.size = s.size; + stat.inode = s.inodeId; + stat.fileType = s.fileType; return stat; } @@ -289,17 +294,34 @@ int FileSystemTemplate::remove(uint64_t inode) { #endif template int FileSystemTemplate::write(const char *path, void *buffer, uint64_t size, uint8_t fileType) { - int retval = -1; - - // find the inode for the given path - auto inode = findInodeOf(path); - - // if inode exists, read the data into buffer - if (inode) { - retval = write(inode, buffer, size, fileType); + int err = 0; + size_t pathLen = ox_strlen(path); + char dirPath[pathLen]; + char fileName[pathLen]; + PathIterator pathReader(path, pathLen); + err |= pathReader.fileName(fileName, pathLen); + err |= pathReader.dirPath(dirPath, pathLen); + if (err) { + return err; } - return retval; + uint64_t inode = findInodeOf(path); + // find an inode value for the given path + if (!inode) { + while (!inode) { + inode = ox_rand() >> 48; + // make sure this does not already exist + if (stat(inode).inode) { + // that result was unusable, try again + inode = 0; + } + } + insertDirectoryEntry(dirPath, fileName, inode); + } + + err = write(inode, buffer, size, fileType); + + return err; } #ifdef _MSC_VER #pragma warning(default:4244) @@ -325,26 +347,25 @@ uint64_t FileSystemTemplate::findInodeOf(const char *path) { PathIterator it(path, pathLen); char fileName[pathLen]; uint64_t inode = INODE_ROOT_DIR; - while (inode) { + while (it.hasNext()) { auto dirStat = m_store->stat(inode); if (dirStat.size >= sizeof(Directory)) { uint8_t dirBuffer[dirStat.size]; auto dir = (Directory*) dirBuffer; if (read(inode, dirBuffer, dirStat.size) == 0) { if (dirStat.fileType == FileType::Directory && it.next(fileName, pathLen) == 0) { - if (!it.hasNext()) { - // no further name components, inode points to the correct file - break; - } inode = dir->getFileInode(fileName, dirStat.size); } else { inode = 0; // null out inode and break + break; } } else { inode = 0; // null out inode and break + break; } } else { inode = 0; // null out inode and break + break; } } return inode; @@ -401,30 +422,51 @@ uint8_t *FileSystemTemplate::format(void *buffer, typename F #pragma warning(disable:4244) #endif template -int FileSystemTemplate::insertDirectoryEntry(uint64_t inode, const char *dirPath, const char *fileName) { - return 0; +int FileSystemTemplate::insertDirectoryEntry(const char *dirPath, const char *fileName, uint64_t inode) { + auto s = stat(dirPath); + if (s.inode) { + size_t dirBuffSize = s.size + DirectoryEntry::spaceNeeded(fileName) + 100; + uint8_t dirBuff[dirBuffSize]; + int err = read(s.inode, dirBuff, dirBuffSize); + + if (!err) { + auto dir = (Directory*) dirBuff; + dir->size += DirectoryEntry::spaceNeeded(fileName); + auto entry = (DirectoryEntry*) &dirBuff[s.size]; + entry->inode = inode; + entry->setName(fileName); + return write(s.inode, dirBuff, dirBuffSize, FileType::Directory); + } else { + return 1; + } + } else { + return 2; + } } #ifdef _MSC_VER #pragma warning(default:4244) #endif + // Directory template uint64_t FileSystemTemplate::Directory::getFileInode(const char *name, uint64_t buffSize) { - uint64_t retval = 0; + uint64_t inode = 0; auto current = files(); if (current) { - auto end = (DirectoryEntry*) ((uint8_t*) files()) + buffSize; + auto end = (DirectoryEntry*) (((uint8_t*) files()) + buffSize); while (current && ox_strcmp(current->getName(), name) != 0) { - current = (DirectoryEntry*) ((uint8_t*) current) + current->size(); - if (current < end) { + current = (DirectoryEntry*) (((uint8_t*) current) + current->size()); + if (current >= end) { current = nullptr; } } - retval = current->inode; + if (current) { + inode = current->inode; + } } - return retval; + return inode; } typedef FileSystemTemplate FileSystem16; diff --git a/src/ox/fs/pathiterator.cpp b/src/ox/fs/pathiterator.cpp index c53fd8fb1..f82cd8bee 100644 --- a/src/ox/fs/pathiterator.cpp +++ b/src/ox/fs/pathiterator.cpp @@ -18,6 +18,41 @@ PathIterator::PathIterator(const char *path, size_t maxSize) { m_maxSize = maxSize; } +/** + * @return 0 if no error + */ +int PathIterator::dirPath(char *out, size_t outSize) { + int idx = ox_lastIndexOf(m_path, '/', m_maxSize); + size_t size = idx + 1; + if (idx >= 0 && size < outSize) { + ox_memcpy(out, m_path, size); + out[size] = 0; + return 0; + } else { + return 1; + } +} + +/** + * @return 0 if no error + */ +int PathIterator::fileName(char *out, size_t outSize) { + auto idx = ox_lastIndexOf(m_path, '/', m_maxSize); + if (idx >= 0) { + idx++; // pass up the preceding / + size_t fileNameSize = ox_strlen(&m_path[idx]); + if (fileNameSize < outSize) { + ox_memcpy(out, &m_path[idx], fileNameSize); + out[fileNameSize] = 0; + return 0; + } else { + return 1; + } + } else { + return 2; + } +} + int PathIterator::next(char *pathOut, size_t pathOutSize) { size_t size = 0; int retval = 1; @@ -46,6 +81,9 @@ bool PathIterator::hasNext() { size_t size = 0; if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) { size_t start = m_iterator; + if (m_path[start] == '/') { + start++; + } // end is at the next / const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start); // correct end if it is invalid, which happens if there is no next / @@ -55,7 +93,6 @@ bool PathIterator::hasNext() { size_t end = substr - m_path; size = end - start; } - m_iterator += size; return size > 0; } diff --git a/src/ox/fs/pathiterator.hpp b/src/ox/fs/pathiterator.hpp index 4c4921c99..789e8ac8d 100644 --- a/src/ox/fs/pathiterator.hpp +++ b/src/ox/fs/pathiterator.hpp @@ -22,6 +22,16 @@ class PathIterator { public: PathIterator(const char *path, size_t maxSize); + /** + * @return 0 if no error + */ + int dirPath(char *pathOut, size_t pathOutSize); + + /** + * @return 0 if no error + */ + int fileName(char *out, size_t outSize); + /** * @return 0 if no error */ diff --git a/src/ox/fs/test/CMakeLists.txt b/src/ox/fs/test/CMakeLists.txt index d95fc0051..90a8016f3 100644 --- a/src/ox/fs/test/CMakeLists.txt +++ b/src/ox/fs/test/CMakeLists.txt @@ -28,10 +28,14 @@ target_link_libraries(FSTests OxFS OxStd) add_test("FileStoreFormat" FileStoreFormat) add_test("FileSystemFormat" FileSystemFormat) add_test("FileStoreIO" FileStoreIO) -add_test("Test\\ PathIterator1" FSTests PathIterator1) -add_test("Test\\ PathIterator2" FSTests PathIterator2) -add_test("Test\\ PathIterator3" FSTests PathIterator3) -add_test("Test\\ PathIterator4" FSTests PathIterator4) -add_test("Test\\ PathIterator5" FSTests PathIterator5) +add_test("Test\\ PathIterator::next1" FSTests PathIterator::next1) +add_test("Test\\ PathIterator::next2" FSTests PathIterator::next2) +add_test("Test\\ PathIterator::next3" FSTests PathIterator::next3) +add_test("Test\\ PathIterator::next4" FSTests PathIterator::next4) +add_test("Test\\ PathIterator::next5" FSTests PathIterator::next5) -add_test("Test\\ FileSystem32::findInodeOf" FSTests FileSystem32::findInodeOf) +add_test("Test\\ PathIterator::dirPath" FSTests PathIterator::dirPath) +add_test("Test\\ PathIterator::fileName" FSTests PathIterator::fileName) + +add_test("Test\\ FileSystem32::findInodeOf\\ /" FSTests "FileSystem32::findInodeOf /") +add_test("Test\\ FileSystem32::write\\(string\\)" FSTests "FileSystem32::write(string)") diff --git a/src/ox/fs/test/tests.cpp b/src/ox/fs/test/tests.cpp index 9c6072f74..161e2ca6c 100644 --- a/src/ox/fs/test/tests.cpp +++ b/src/ox/fs/test/tests.cpp @@ -15,12 +15,11 @@ using namespace std; using namespace ox::fs; -using namespace ox::std; -map tests = { +map> tests = { { { - "PathIterator1", + "PathIterator::next1", [](string) { int retval = 0; string path = "/usr/share/charset.gbag"; @@ -35,7 +34,7 @@ map tests = { } }, { - "PathIterator2", + "PathIterator::next2", [](string) { int retval = 0; string path = "/usr/share/"; @@ -49,7 +48,7 @@ map tests = { } }, { - "PathIterator3", + "PathIterator::next3", [](string) { int retval = 0; string path = "/"; @@ -62,7 +61,7 @@ map tests = { } }, { - "PathIterator4", + "PathIterator::next4", [](string) { int retval = 0; string path = "usr/share/charset.gbag"; @@ -77,7 +76,7 @@ map tests = { } }, { - "PathIterator5", + "PathIterator::next5", [](string) { int retval = 0; string path = "usr/share/"; @@ -91,7 +90,33 @@ map tests = { } }, { - "FileSystem32::findInodeOf", + "PathIterator::dirPath", + [] (string) { + int retval = 0; + string path = "/usr/share/charset.gbag"; + PathIterator it(path.c_str(), path.size()); + const auto buffSize = 1024; + char buff[buffSize]; + assert(buffSize >= path.size()); + retval |= !(it.dirPath(buff, path.size()) == 0 && ox_strcmp(buff, "/usr/share/") == 0); + return retval; + } + }, + { + "PathIterator::fileName", + [](string) { + int retval = 0; + string path = "/usr/share/charset.gbag"; + PathIterator it(path.c_str(), path.size()); + const auto buffSize = 1024; + char buff[buffSize]; + assert(buffSize >= path.size()); + retval |= !(it.fileName(buff, path.size()) == 0 && ox_strcmp(buff, "charset.gbag") == 0); + return retval; + } + }, + { + "FileSystem32::findInodeOf /", [](string) { int retval = 0; const auto size = 1024; @@ -103,6 +128,29 @@ map tests = { return retval; } }, + { + "FileSystem32::write(string)", + [](string) { + // this value will likely need to change if anything about the + // random number generator changes + const auto targetInode = 58542; + + int retval = 0; + auto path = "/charset.gbag"; + auto data = "test"; + + const auto size = 1024; + uint8_t buff[size]; + FileSystem32::format(buff, (FileStore32::FsSize_t) size, true); + auto fs = (FileSystem32*) createFileSystem(buff, size); + + retval |= fs->write(path, &data, ox_strlen(data)); + retval |= !(fs->findInodeOf(path) == targetInode); + + delete fs; + return retval; + } + }, }, }; diff --git a/src/ox/std/CMakeLists.txt b/src/ox/std/CMakeLists.txt index fe05c4d5f..35e38cbe9 100644 --- a/src/ox/std/CMakeLists.txt +++ b/src/ox/std/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8) add_library( OxStd memops.cpp + random.cpp strops.cpp ) diff --git a/src/ox/std/bitops.hpp b/src/ox/std/bitops.hpp new file mode 100644 index 000000000..863790235 --- /dev/null +++ b/src/ox/std/bitops.hpp @@ -0,0 +1,19 @@ +/* + * Copyright 2015 - 2017 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 "types.hpp" + +namespace ox { + +inline uint64_t rotateLeft(uint64_t i, int shift) { + return (i << shift) | (i >> (64 - shift)); +} + +} diff --git a/src/ox/std/random.cpp b/src/ox/std/random.cpp new file mode 100644 index 000000000..98a3dfe43 --- /dev/null +++ b/src/ox/std/random.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2015 - 2017 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/. + */ + +#include "bitops.hpp" +#include "random.hpp" + +namespace ox { + +RandomSeed Random::DEFAULT_SEED = {540932923848, 540932540932}; + +Random::Random(RandomSeed seed) { + m_seed[0] = seed[0]; + m_seed[1] = seed[1]; +} + +uint64_t Random::gen() { + auto s0 = m_seed[0]; + auto s1 = m_seed[1]; + auto retval = s0 + s1; + + s1 ^= s0; + m_seed[0] = ox::rotateLeft(s0, 55) ^ s1 ^ (s1 << 14); + m_seed[1] = ox::rotateLeft(s1, 36); + + return retval; +} + +} + + +uint64_t ox_rand() { + static ox::Random rand; + return rand.gen(); +} diff --git a/src/ox/std/random.hpp b/src/ox/std/random.hpp new file mode 100644 index 000000000..43d4daaf7 --- /dev/null +++ b/src/ox/std/random.hpp @@ -0,0 +1,30 @@ +/* + * Copyright 2015 - 2017 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 + +uint64_t ox_rand(); + +namespace ox { + +typedef uint64_t RandomSeed[2]; + +class Random { + public: + static RandomSeed DEFAULT_SEED; + + private: + RandomSeed m_seed; + + public: + Random(RandomSeed seed = DEFAULT_SEED); + + uint64_t gen(); +}; + +} diff --git a/src/ox/std/std.hpp b/src/ox/std/std.hpp index 823b00943..93c9ad20c 100644 --- a/src/ox/std/std.hpp +++ b/src/ox/std/std.hpp @@ -7,7 +7,9 @@ */ #pragma once +#include "bitops.hpp" #include "byteswap.hpp" #include "memops.hpp" +#include "random.hpp" #include "strops.hpp" #include "types.hpp" diff --git a/src/ox/std/strops.cpp b/src/ox/std/strops.cpp index 52b244ce6..5176b9b0b 100644 --- a/src/ox/std/strops.cpp +++ b/src/ox/std/strops.cpp @@ -58,6 +58,26 @@ char *ox_strchr(char *str, int character, size_t maxLen) { return nullptr; } +int ox_lastIndexOf(const char *str, int character, int maxLen) { + int retval = -1; + for (int i = 0; i < maxLen && str[i]; i++) { + if (str[i] == character) { + retval = i; + } + } + return retval; +} + +int ox_lastIndexOf(char *str, int character, int maxLen) { + int retval = -1; + for (int i = 0; i < maxLen && str[i]; i++) { + if (str[i] == character) { + retval = i; + } + } + return retval; +} + int ox_atoi(const char *str) { int total = 0; int multiplier = 1; diff --git a/src/ox/std/strops.hpp b/src/ox/std/strops.hpp index 80e574398..4fc8b9157 100644 --- a/src/ox/std/strops.hpp +++ b/src/ox/std/strops.hpp @@ -20,4 +20,8 @@ const char *ox_strchr(const char *str, int character, size_t maxLen = 0xFFFFFFFF char *ox_strchr(char *str, int character, size_t maxLen = 0xFFFFFFFF); +int ox_lastIndexOf(const char *str, int character, int maxLen = 0xFFFFFFFF); + +int ox_lastIndexOf(char *str, int character, int maxLen = 0xFFFFFFFF); + int ox_atoi(const char *str); diff --git a/src/ox/std/test/CMakeLists.txt b/src/ox/std/test/CMakeLists.txt index 3bf8f2bf1..da900ca6c 100644 --- a/src/ox/std/test/CMakeLists.txt +++ b/src/ox/std/test/CMakeLists.txt @@ -30,6 +30,7 @@ add_test("Test\\ ox_strcmp\\ resize\\ !=\\ read" StrOpsTest "resize > read") add_test("Test\\ ox_strcmp\\ resize\\ ==\\ resize" StrOpsTest "resize == resize") add_test("Test\\ ox_strcmp\\ resize\\ ==\\ resize" StrOpsTest " == ") add_test("Test\\ ox_strchr\\ 0" StrOpsTest "ox_strchr 0") +add_test("Test\\ ox_lastIndexOf\\ aaaa\\ a" StrOpsTest "ox_lastIndexOf aaaa a") ################################################################################ diff --git a/src/ox/std/test/strops_test.cpp b/src/ox/std/test/strops_test.cpp index 963b0f486..9aaf14be4 100644 --- a/src/ox/std/test/strops_test.cpp +++ b/src/ox/std/test/strops_test.cpp @@ -56,6 +56,16 @@ map> tests = { return !(ox_strchr(testStr, 0, 4) == &testStr[4]); } }, + { + "ox_lastIndexOf aaaa a", + []() { + int retval = 0; + auto testStr = "aaaa"; + retval |= !(ox_lastIndexOf((char*) testStr, 'a', ox_strlen(testStr)) == 3); + retval |= !(ox_lastIndexOf((const char*) testStr, 'a', ox_strlen(testStr)) == 3); + return retval; + } + }, }; int main(int argc, const char **args) { From 41c017e305a3ec375fcc953694f0ce9b781adcbc Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 24 Apr 2017 02:41:57 -0500 Subject: [PATCH 43/45] Remove use of std::function in fs test --- src/ox/fs/test/tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ox/fs/test/tests.cpp b/src/ox/fs/test/tests.cpp index 161e2ca6c..fe1a8d9ae 100644 --- a/src/ox/fs/test/tests.cpp +++ b/src/ox/fs/test/tests.cpp @@ -16,7 +16,7 @@ using namespace std; using namespace ox::fs; -map> tests = { +map tests = { { { "PathIterator::next1", From b7b5772c349123efa0b80d1a01c1b3849bdee99d Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 24 Apr 2017 20:13:15 -0500 Subject: [PATCH 44/45] Add comment crediting the random number generation algorithm --- src/ox/std/random.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ox/std/random.cpp b/src/ox/std/random.cpp index 98a3dfe43..247cab5aa 100644 --- a/src/ox/std/random.cpp +++ b/src/ox/std/random.cpp @@ -19,6 +19,7 @@ Random::Random(RandomSeed seed) { } uint64_t Random::gen() { + // An implementation of the Xoroshiro128+ algorithm auto s0 = m_seed[0]; auto s1 = m_seed[1]; auto retval = s0 + s1; From c5410c8755236afe6eb3150c2bf6ed6db11d6a60 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 25 Apr 2017 18:30:29 -0500 Subject: [PATCH 45/45] Fix issue with allocator that caused deallocation to reset the allocation point --- src/ox/fs/filestore.hpp | 51 +++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index a6319c463..4cafea904 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -487,8 +487,15 @@ int FileStore
::write(InodeId_t id, void *data, typename Header::FsSize_t auto root = ptr(m_header.getRootInode()); if (insert(root, inode) || root == inode) { retval = 0; + } else { + dealloc(inode); + retval = 2; } + } else { + retval = 3; } + } else { + retval = 4; } return retval; } @@ -504,41 +511,37 @@ int FileStore
::remove(Inode *root, InodeId_t id) { if (root->getId() > id) { if (root->getLeft()) { - auto node = ptr(root->getLeft()); - if (node->getId() != id) { - err = remove(node, id); + auto left = ptr(root->getLeft()); + if (left->getId() != id) { + err = remove(left, id); } else { root->setLeft(0); - if (node->getRight()) { - insert(root, ptr(node->getRight())); + // pass children to parent + if (left->getRight()) { + insert(root, ptr(left->getRight())); } - if (node->getLeft()) { - insert(root, ptr(node->getLeft())); + if (left->getLeft()) { + insert(root, ptr(left->getLeft())); } - dealloc(node); - node->setId(0); - node->setLeft(0); - node->setRight(0); + dealloc(left); err = 0; } } } else if (root->getId() < id) { if (root->getRight()) { - auto node = ptr(root->getRight()); - if (node->getId() != id) { - err = remove(node, id); + auto right = ptr(root->getRight()); + if (right->getId() != id) { + err = remove(right, id); } else { root->setRight(0); - if (node->getRight()) { - insert(root, ptr(node->getRight())); + // pass children to parent + if (right->getRight()) { + insert(root, ptr(right->getRight())); } - if (node->getLeft()) { - insert(root, ptr(node->getLeft())); + if (right->getLeft()) { + insert(root, ptr(right->getLeft())); } - dealloc(node); - node->setId(0); - node->setLeft(0); - node->setRight(0); + dealloc(right); err = 0; } } @@ -548,9 +551,6 @@ int FileStore
::remove(Inode *root, InodeId_t id) { insert(ptr(m_header.getRootInode()), ptr(root->getLeft())); } dealloc(root); - root->setId(0); - root->setLeft(0); - root->setRight(0); err = 0; } @@ -717,6 +717,7 @@ void *FileStore
::alloc(typename Header::FsSize_t size) { inode->setPrev(ptr(firstInode())->getPrev()); inode->setNext(firstInode()); m_header.setMemUsed(m_header.getMemUsed() + size); + ptr(lastInode())->setNext(retval); ptr(firstInode())->setPrev(retval); return inode; }