Util::insertEnd/start, Files::scan

This commit is contained in:
mrbesen 2020-10-02 15:54:12 +02:00
parent fa59de25f7
commit 00a2218d98
Signed by: MrBesen
GPG Key ID: 596B2350DCD67504
7 changed files with 140 additions and 1 deletions

View File

@ -1,5 +1,7 @@
#pragma once
#include <functional>
#include <iterator>
#include <string>
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<bool(const std::string&, FileType type)> fileNameFilter;
template<class Container>
bool scan(const std::string& path, std::insert_iterator<Container> it, bool prefixdir = false, fileNameFilter fnf = fileNameFilter(nullptr));
}

View File

@ -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);
}

View File

@ -1,5 +1,10 @@
#include "files.h"
#include <dirent.h>
#include <list>
#include <set>
#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<class Container>
bool mrbesen::Files::scan(const std::string& path, std::insert_iterator<Container> 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<std::list<std::string>>(const std::string&, std::insert_iterator<std::list<std::string>>, bool, fileNameFilter);
template bool mrbesen::Files::scan<std::set<std::string>>(const std::string&, std::insert_iterator<std::set<std::string>>, bool, fileNameFilter);
template bool mrbesen::Files::scan<std::multiset<std::string>>(const std::string&, std::insert_iterator<std::multiset<std::string>>, bool, fileNameFilter);

View File

@ -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;
}

View File

@ -1,6 +1,9 @@
#include "test.h"
#include "files.h"
#include "util.h"
#include <list>
#include <set>
#include <string>
using namespace mrbesen;
@ -99,3 +102,22 @@ int testFiles_extention() {
return TESTGOOD;
}
int testFiles_scan() {
std::string path = "./tests";
std::list<std::string> 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<std::string> 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;
}

View File

@ -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) {

View File

@ -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;
}