From 00a2218d982f4070d64f45471efad5ef098979c4 Mon Sep 17 00:00:00 2001 From: mrbesen Date: Fri, 2 Oct 2020 15:54:12 +0200 Subject: [PATCH] Util::insertEnd/start, Files::scan --- inc/files.h | 20 ++++++++++++++++++++ inc/util.h | 5 +++++ src/Files.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/Util.cpp | 18 ++++++++++++++++++ tests/filestests.cpp | 22 ++++++++++++++++++++++ tests/main.cpp | 4 +++- tests/utilstest.cpp | 30 ++++++++++++++++++++++++++++++ 7 files changed, 140 insertions(+), 1 deletion(-) diff --git a/inc/files.h b/inc/files.h index 943a75a..a6069df 100644 --- a/inc/files.h +++ b/inc/files.h @@ -1,5 +1,7 @@ #pragma once +#include +#include #include namespace mrbesen::Files { @@ -8,4 +10,22 @@ void parent(const std::string& child, std::string& out); //get the parent direct void file(const std::string& path, std::string& out); //get the filename without the path void extention(const std::string& path, std::string& ext); //get the files extenetion +enum class FileType : unsigned char { + UNKNOWN = 0, + FIFO = 1, + CHARACTER = 2, + DIRECTORY = 4, + BLOCK = 6, + REGULAR = 8, + LINK = 10, + SOCKET = 12, + WHT = 14 ///???? + + //copied from dirent.h -> see man readdir +}; + +typedef std::function fileNameFilter; +template +bool scan(const std::string& path, std::insert_iterator it, bool prefixdir = false, fileNameFilter fnf = fileNameFilter(nullptr)); + } \ No newline at end of file diff --git a/inc/util.h b/inc/util.h index bf00627..9d496d5 100644 --- a/inc/util.h +++ b/inc/util.h @@ -14,7 +14,12 @@ void toLower(std::string& in); //inplace toLower bool endsWith(const std::string& str, const std::string& ending); bool startsWith(const std::string& str, const std::string& start); +//makes sure a string does NOT ends or starts with a specific sub string bool removeEnd(std::string& str, const std::string& ending); //returns true on change (ending = "" -> returns false) bool removeStart(std::string& str, const std::string& start); +//makes sure a string DOES ends or starts with a specific sub string +bool insertEnd(std::string& str, const std::string& ending); +bool insertStart(std::string& str, const std::string& start); + } \ No newline at end of file diff --git a/src/Files.cpp b/src/Files.cpp index 4a6ba04..9c18f27 100644 --- a/src/Files.cpp +++ b/src/Files.cpp @@ -1,5 +1,10 @@ #include "files.h" +#include +#include +#include +#include "util.h" + void mrbesen::Files::parent(const std::string& child, std::string& out) { //letzten path trenner finden size_t pos = child.rfind('/', child.length() -2); //das erste Zeichen überspringen (könnte ein / sein) @@ -35,3 +40,40 @@ void mrbesen::Files::extention(const std::string& path, std::string& ext) { ext = filestr.substr(pos+1); } +template +bool mrbesen::Files::scan(const std::string& path, std::insert_iterator it, bool prefixdir, fileNameFilter fnf) { + std::string path_ = path; + mrbesen::Util::insertEnd(path_, "/"); + + ::DIR* dir = opendir(path_.c_str()); + if(!dir) { + return false; + } + + //read dir + struct ::dirent* entr; + while((entr = readdir(dir))) { + std::string fname = entr->d_name; + FileType type = (FileType) entr->d_type; //DT_BLK DT_CHR DT_DIR DT_FIFO DT_LNK DT_REG DT_SOCK DT_UNKNOWN (dirent.h, man readdir) + if(fnf) { + if(!fnf(fname, type)) { + continue; + } + } + if(prefixdir) + fname = path_ + fname; + it = fname; + + } + + closedir(dir); + + return true; +} + +//curently only these are supported, because iterators may break on others upon insertion +template bool mrbesen::Files::scan>(const std::string&, std::insert_iterator>, bool, fileNameFilter); +template bool mrbesen::Files::scan>(const std::string&, std::insert_iterator>, bool, fileNameFilter); +template bool mrbesen::Files::scan>(const std::string&, std::insert_iterator>, bool, fileNameFilter); + + diff --git a/src/Util.cpp b/src/Util.cpp index 328d145..dda8cb9 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -90,3 +90,21 @@ bool mrbesen::Util::removeStart(std::string& str, const std::string& start) { } return false; } + +bool mrbesen::Util::insertEnd(std::string& str, const std::string& ending) { + if(ending.empty()) return false; + + if(endsWith(str, ending)) return false; + + str.append(ending); + return true; +} + +bool mrbesen::Util::insertStart(std::string& str, const std::string& start) { + if(start.empty()) return false; + + if(startsWith(str, start)) return false; + + str = start + str; + return true; +} \ No newline at end of file diff --git a/tests/filestests.cpp b/tests/filestests.cpp index b4b9377..9e59a1b 100644 --- a/tests/filestests.cpp +++ b/tests/filestests.cpp @@ -1,6 +1,9 @@ #include "test.h" #include "files.h" +#include "util.h" +#include +#include #include using namespace mrbesen; @@ -99,3 +102,22 @@ int testFiles_extention() { return TESTGOOD; } + + +int testFiles_scan() { + std::string path = "./tests"; + std::list out, out2; + + ASSERT(Files::scan(path, std::inserter(out, out.begin()), false), ""); + ASSERT(Files::scan(path, std::inserter(out2, out2.begin()), true), ""); + + ASSERT(out.size() == out2.size(), out.size() << " " << out2.size()); + + std::set out3; + ASSERT(Files::scan(path, std::inserter(out3, out3.begin()), false, [](const std::string& str, Files::FileType t){ return mrbesen::Util::startsWith(str, "."); }), ""); + ASSERT(out3.size() == 2, out3.size()); + ASSERT(out3.find(".") != out3.end(), ""); + ASSERT(out3.find("..") != out3.end(), ""); + + return TESTGOOD; +} diff --git a/tests/main.cpp b/tests/main.cpp index 252f875..6b9fd3e 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -5,14 +5,16 @@ int testFiles_parent(); int testFiles_file(); int testFiles_extention(); +int testFiles_scan(); int testUtil_Count(); int testUtil_equalsIgnoreCase(); int testUtil_toLower(); int testUtil_start_endWith(); int testUtil_removeStart_End(); +int testUtil_insertStart_End(); -test_t tests[] = {testFiles_parent, testFiles_file, testFiles_extention, testUtil_Count, testUtil_equalsIgnoreCase, testUtil_toLower, testUtil_start_endWith, testUtil_removeStart_End, NULL}; +test_t tests[] = {testFiles_parent, testFiles_file, testFiles_extention, testFiles_scan, testUtil_Count, testUtil_equalsIgnoreCase, testUtil_toLower, testUtil_start_endWith, testUtil_removeStart_End, testUtil_insertStart_End, NULL}; int main(int argc, char** argv) { diff --git a/tests/utilstest.cpp b/tests/utilstest.cpp index ec480cd..246011a 100644 --- a/tests/utilstest.cpp +++ b/tests/utilstest.cpp @@ -116,5 +116,35 @@ int testUtil_removeStart_End() { ASSERT(removeEnd(a, "e"), ""); ASSERT(a == "", ""); + return TESTGOOD; +} + +int testUtil_insertStart_End() { + std::string a = ""; + + ASSERT(!insertStart(a, ""), ""); + ASSERT(a == "", a); + + ASSERT(insertStart(a, "abc"), ""); + ASSERT(a == "abc", a); + + ASSERT(!insertStart(a, "a"), ""); + ASSERT(a == "abc", a); + + ASSERT(insertStart(a, "bc"), ""); + ASSERT(a == "bcabc", a); + + ASSERT(!insertStart(a, ""), ""); + ASSERT(a == "bcabc", a); + + ASSERT(!insertEnd(a, ""), ""); + ASSERT(a == "bcabc", a); + + ASSERT(!insertEnd(a, "bc"), ""); + ASSERT(a == "bcabc", a); + + ASSERT(insertEnd(a, "def"), ""); + ASSERT(a == "bcabcdef", a); + return TESTGOOD; } \ No newline at end of file