From 6e690ee98dc263d9fff72aafb7cfd1a00d8aafea Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 18 Apr 2017 17:18:08 -0500 Subject: [PATCH 1/8] 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 2/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 7/8] 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 8/8] 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);