From 65b9f06319cb5f4122a0a45aed6a183bd6f779d8 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Fri, 31 Dec 2021 14:10:26 +0800 Subject: [PATCH] Add listdir to fileop --- fileop.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fileop.h | 9 +++++++ str_util.cpp | 16 +++++++++++ str_util.h | 8 ++++++ 4 files changed, 109 insertions(+) diff --git a/fileop.cpp b/fileop.cpp index 995a9fa..7935f53 100644 --- a/fileop.cpp +++ b/fileop.cpp @@ -12,12 +12,14 @@ #include #include #else +#include #include #include #endif #include #include #include "err.h" +#include "str_util.h" #include "wchar_util.h" #include "time_util.h" #include @@ -85,6 +87,29 @@ HANDLE get_file_size_internal(wchar_t* fn) { return CreateFileW(fn, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); } +bool listdir_internal(wchar_t* fn, std::list& list, bool ignore_hidden_file) { + std::list li; + WIN32_FIND_DATAW data; + HANDLE re = FindFirstFileW(fn, &data); + if (re == INVALID_HANDLE_VALUE) return false; + std::string tfn; + do { + if (!wchar_util::wstr_to_str(tfn, data.cFileName, CP_UTF8)) { + FindClose(re); + return false; + } + if ((ignore_hidden_file && tfn.find(".") != 0) || (!ignore_hidden_file && tfn != "." && tfn != "..")) li.push_back(tfn); + BOOL r = FindNextFileW(re, &data); + if (!r) { + FindClose(re); + if (GetLastError() == ERROR_NO_MORE_FILES) break; + return false; + } + } while (1); + list = li; + return true; +} + template T fileop_internal(const char* fname, UINT codePage, T(*callback)(wchar_t* fn, Args... args), T failed, Args... args) { int wlen; @@ -454,3 +479,54 @@ int64_t fileop::ftell(FILE* f) { #endif #endif } + +bool fileop::listdir(std::string path, std::list& filelist, bool ignore_hidden_file) { +#if _WIN32 + if (!path.length()) path = "."; + path = str_util::str_replace(path, "/", "\\"); + path = join(path, "*"); + UINT cp[] = { CP_UTF8, CP_OEMCP, CP_ACP }; + int i; + std::list li; + for (i = 0; i < 3; i++) { + if (fileop_internal&, bool>(path.c_str(), cp[i], &listdir_internal, false, li, ignore_hidden_file)) { + filelist = li; + return true; + } + } + WIN32_FIND_DATAA data; + HANDLE re = FindFirstFileA(path.c_str(), &data); + if (re == INVALID_HANDLE_VALUE) return false; + std::string tfn; + do { + tfn = data.cFileName; + if ((ignore_hidden_file && tfn.find(".") != 0) || (!ignore_hidden_file && tfn != "." && tfn != "..")) li.push_back(tfn); + BOOL r = FindNextFileA(re, &data); + if (!r) { + FindClose(re); + if (GetLastError() == ERROR_NO_MORE_FILES) break; + return false; + } + } while (1); + filelist = li; + return true; +#else + DIR* dir = opendir(path.c_str()); + if (!dir) return false; + struct dirent* d = readdir(dir); + std::list li; + std::string tfn; + while (d) { + tfn = d->d_name; + if ((ignore_hidden_file && tfn.find(".") != 0) || (!ignore_hidden_file && tfn != "." && tfn != "..")) li.push_back(tfn); + d = readdir(dir); + } + if (errno) { + closedir(dir); + return false; + } + closedir(dir); + filelist = li; + return true; +#endif +} diff --git a/fileop.h b/fileop.h index 175dbf4..5fc7c44 100644 --- a/fileop.h +++ b/fileop.h @@ -1,5 +1,6 @@ #ifndef _UTIL_FILEOP_H #define _UTIL_FILEOP_H +#include #include #include #include @@ -154,5 +155,13 @@ namespace fileop { * @return The current position */ int64_t ftell(FILE* f); + /** + * @brief List content of a directory. + * @param path The path of directory + * @param filelist Result + * @param ignore_hidden_file Ignore name starts with `.` + * @return true if successed. + */ + bool listdir(std::string path, std::list& filelist, bool ignore_hidden_file = true); } #endif diff --git a/str_util.cpp b/str_util.cpp index e03ae98..eebea22 100644 --- a/str_util.cpp +++ b/str_util.cpp @@ -2,6 +2,10 @@ #include "cstr_util.h" #include +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + bool str_util::tolowercase(std::string ori, std::string& result) { char* tmp = nullptr; auto re = cstr_tolowercase(ori.c_str(), ori.length(), &tmp); @@ -13,3 +17,15 @@ bool str_util::tolowercase(std::string ori, std::string& result) { return false; } } + +std::string str_util::str_replace(std::string input, std::string pattern, std::string new_content) { + auto loc = input.find(pattern, 0); + auto len = pattern.length(); + auto len2 = new_content.length(); + while (loc != -1) { + input.replace(loc, len, new_content); + if (loc + len2 < input.length()) loc = input.find(pattern, max(0, loc + len2)); + else break; + } + return input; +} \ No newline at end of file diff --git a/str_util.h b/str_util.h index 79443e6..b831a2c 100644 --- a/str_util.h +++ b/str_util.h @@ -9,5 +9,13 @@ namespace str_util { * @return true if successed. */ bool tolowercase(std::string ori, std::string& result); + /** + * @brief Replace all pattern to new_content + * @param input Input string + * @param pattern Pattern + * @param new_content New content + * @return Result string + */ + std::string str_replace(std::string input, std::string pattern, std::string new_content); } #endif