#include "files.h" #include #include #include #include #include #include #include #include #include "util.h" #ifndef PATH_MAX #define PATH_MAX 1024 #endif #if defined(_WIN32) || defined(_WIN64) #include #endif 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) if(pos == std::string::npos) pos = child.rfind('\\'); if(pos != std::string::npos) out = child.substr(0, pos+1); else out = ""; } void mrbesen::files::file(const std::string& path, std::string& out) { //letzten path trenner finden size_t pos = path.rfind('/', path.length() -2); //das erste Zeichen überspringen (könnte ein / sein) if(pos == std::string::npos) pos = path.rfind('\\'); if(pos != std::string::npos) out = path.substr(pos+1); else out = path; } void mrbesen::files::extention(const std::string& path, std::string& ext) { std::string filestr; file(path, filestr); size_t pos = filestr.rfind('.'); if(pos == std::string::npos || pos+1 == filestr.size()) { ext = ""; return; } ext = filestr.substr(pos+1); } bool mrbesen::files::iterateFile(const std::string& filename, fileLineCallback clb, bool ignoreBlanks) { std::ifstream fs(filename); return iterateFile(fs, clb, ignoreBlanks); } bool mrbesen::files::iterateFile(std::istream& file, fileLineCallback clb, bool ignoreBlanks) { if(!clb) return false; if(!file) return false; std::string line; while(std::getline(file, line)) { mrbesen::util::removeEnd(line, "\r"); if(ignoreBlanks && line.empty()) continue; clb(line); } return true; } template bool mrbesen::files::scan(const std::string& path, std::insert_iterator it, bool prefixdir, fileNameFilter fnf) { return scan(path, [&](const std::string& p, FileType t){ it = p; }, prefixdir, fnf); } //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); bool mrbesen::files::scan(const std::string& path, fileCallback clb, bool prefixdir, fileNameFilter fnf) { #if defined(_WIN32) ||defined(_WIN64) return false; #else 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; clb(fname, type); } closedir(dir); return true; #endif } bool mrbesen::files::readFile(const std::string& name, std::ostream& output, unsigned int maxsize) { int fd = open(name.c_str(), O_RDONLY); bool ret = readFile(fd, output, maxsize); close(fd); return ret; } bool mrbesen::files::readFile(int fd, std::ostream& output, unsigned int maxsize) { if(fd < 0) return false; const int BUFFERSIZE = 1024; ssize_t readc; uint32_t readbytes = 0; do { char b[BUFFERSIZE]; readc = read(fd, b, BUFFERSIZE); if(readc == -1) return false; //error output << std::string(b, readc); readbytes += readc; } while(readc == BUFFERSIZE && (readbytes < maxsize || maxsize == 0)); return true; } bool mrbesen::files::copy(int fd_from, int fd_to) { static const uint32_t BUFFERSIZE = 4096; char buf[BUFFERSIZE]; ssize_t rc = -1; while(rc) { rc = read(fd_from, buf, BUFFERSIZE); if(rc < 0) return false; //reading error if(rc > 0) { ssize_t wc = write(fd_to, buf, rc); if(wc != rc) return false; //writing error } } return true; } bool mrbesen::files::copy(const std::string& from, const std::string& to) { int fd1 = open(from.c_str(), O_RDONLY); if(fd1 < 0) return false; struct stat sb; if(fstat(fd1, &sb)) { close(fd1); return false; } int fd2 = open(to.c_str(), O_WRONLY | O_CREAT, sb.st_mode); bool r = false; if(fd2 > -1) r = copy(fd1, fd2); close(fd1); close(fd2); return r; } std::string mrbesen::files::realPath(const std::string& str) { #if defined(_WIN32) ||defined(_WIN64) wchar_t bufferin[PATH_MAX]; for(uint32_t i = 0; i < str.size(); ++i) { bufferin[i] = str[i]; } bufferin[str.size()] = 0; wchar_t bufferA[PATH_MAX]; wchar_t* ret = ::_wfullpath(bufferA, bufferin, PATH_MAX); char buffer[PATH_MAX]; for(uint32_t i = 0; ret[i]; ++i) { buffer[i] = ret[i]; } #else char buffer[PATH_MAX]; char* ret = ::realpath(str.c_str(), buffer); #endif if(ret == nullptr) return ""; return std::string(buffer); }