From 5936a751d3a7bb14d79267f274c2a9187435666d Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 22 Apr 2017 01:27:26 -0500 Subject: [PATCH] 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) {