#pragma once #include #include #include #if defined(_PLATFORM_WINDOWS_) #include #include #include #include // file path splitter #define PATH_SEPARATOR_CHAR '\\' // file search struct file_search_t { HANDLE handle; WIN32_FIND_DATA data; }; // module handle typedef HMODULE dll_handle_t; // dll后缀 #define DLL_POSTFIX "dll" #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ #include #include #include #include #include #include #include #include #include #include #include // file path splitter #define PATH_SEPARATOR_CHAR '/' // file search struct file_search_t { DIR* pdir; dirent* pent; char strpath[256]; char strext[16]; }; // module handle typedef void* dll_handle_t; // dll后缀 #define DLL_POSTFIX "so" #ifndef defmax #define defmax(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef defmin #define defmin(a,b) (((a) < (b)) ? (a) : (b)) #endif #elif defined(_PLATFORM_APPLE_) // end of _PLATFORM_LINUX_ #include #include #include #include #include #include #include #include #include #include #include // file path splitter #define PATH_SEPARATOR_CHAR '/' // file search struct file_search_t { DIR* pdir; dirent* pent; char strpath[256]; char strext[16]; }; // module handle typedef void* dll_handle_t; // dll后缀 #define DLL_POSTFIX "dylib" #ifndef defmax #define defmax(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef defmin #define defmin(a,b) (((a) < (b)) ? (a) : (b)) #endif #endif // end of _PLATFORM_APPLE_ namespace disk_file { FORCE_INLINE const char* get_standard_path(const char* path, char* buffer, size_t size) { #if defined(_PLATFORM_WINDOWS_) bool slash = false; const char* src = path; char* dst = buffer; char* dst_end = buffer + size - 1; while (*src) { if (dst >= dst_end) { break; } if ((*src == '/') || (*src == '\\')) { if (slash) { ++src; continue; } else { slash = true; } *dst = '\\'; } else { *dst = *src; slash = false; } ++dst; ++src; } *dst = 0; return buffer; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ bool slash = false; const char* src = path; char* dst = buffer; char* dst_end = buffer + size - 1; while (*src) { if (dst >= dst_end) { break; } if ((*src == '/') || (*src == '\\')) { if (slash) { ++src; continue; } else { slash = true; } *dst = '/'; } else { // 本来为了linux下大小写路径不混乱,全用小写,但是宝将规定了特定的环境路径,所以去掉吧 //*dst = tolower(*src); *dst = *src; slash = false; } ++dst; ++src; } *dst = 0; return buffer; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE int get_full_pathname(const char* file_name, char* buffer, size_t size, char** file_part) { #if defined(_PLATFORM_WINDOWS_) DWORD res = GetFullPathName(file_name, (DWORD)size, buffer, file_part); if (0 == res) { buffer[0] = 0; return 0; } if (size_t(res) >= size) { buffer[0] = 0; return res; } return (int)res; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ memset(buffer, 0, size); // 消除前面的空格 const char* first = file_name; while ((*first == ' ') || (*first == '\t')) { ++first; } // 是否已经包含完整的路径 if (*first == '/') { size_t file_name_len = strlen(first); if (file_name_len >= size) { // 缓冲区不够 return 0; } memcpy(buffer, first, file_name_len + 1); } else { // 获取当前目录 char cur_dir[512] = { 0 }; if (getcwd(cur_dir, sizeof(cur_dir) - 1) == NULL) { return 0; } // 解析相对路径 const char* p = first; while (*p) { if (*p == '.') { // (.\)当前目录 if ((p[1] == '\\') || (p[1] == '/')) { p += 2; continue; } if (p[1] != '.') { break; } if ((p[2] != '\\') && (p[2] != '/')) { break; } // (..\)取上一级目录 char* prev = strrchr(cur_dir, '/'); if (prev) { *prev = 0; } p += 3; } else { break; } } if (strlen(cur_dir) + strlen(p) >= size) { return 0; } strcat(cur_dir, "/"); strcpy(buffer, cur_dir); strcat(buffer, p); } if (file_part) { // 分割路径和文件名 char* separator = strrchr(buffer, '/'); if (separator) { *file_part = separator + 1; } else { // 文件名中没有包含路径 *file_part = buffer; } } return strlen(buffer); #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool get_current_dir(char* buffer, size_t size) { #if defined(_PLATFORM_WINDOWS_) DWORD res = GetCurrentDirectory((DWORD)size, buffer); if (0 == res) { buffer[0] = 0; return false; } if (size_t(res) >= size) { buffer[0] = 0; return false; } return true; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char* res = getcwd(buffer, size); if (NULL == res) { buffer[0] = 0; return false; } return true; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool set_current_dir(const char* dir_name) { #if defined(_PLATFORM_WINDOWS_) return SetCurrentDirectory(dir_name) == TRUE; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ return chdir(dir_name) == 0; #endif // end of _PLATFORM_LINUX_ } // directory exist? FORCE_INLINE bool dir_exists(const char* dir_name) { #if defined(_PLATFORM_WINDOWS_) DWORD res = GetFileAttributes(dir_name); if (res == DWORD(-1)) { return false; } return (res & FILE_ATTRIBUTE_DIRECTORY) != 0; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(dir_name, sname, sizeof(sname)); struct stat st; if (stat(sname, &st) == -1) { return false; } return (st.st_mode & S_IFMT) == S_IFDIR; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool dir_create(const char* dir_name) { #if defined(_PLATFORM_WINDOWS_) return CreateDirectory(dir_name, NULL) == TRUE; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(dir_name, sname, sizeof(sname)); return mkdir(sname, 0700) == 0; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool dir_delete(const char* dir_name) { #if defined(_PLATFORM_WINDOWS_) return RemoveDirectory(dir_name) == TRUE; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(dir_name, sname, sizeof(sname)); return rmdir(sname) == 0; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool file_exists(const char* file_name) { #if defined(_PLATFORM_WINDOWS_) DWORD res = GetFileAttributes(file_name); if (res == DWORD(-1)) { return false; } return (res & FILE_ATTRIBUTE_DIRECTORY) == 0; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(file_name, sname, sizeof(sname)); struct stat st; if (stat(sname, &st) == -1) { return false; } return (st.st_mode & S_IFMT) == S_IFREG; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE FILE* file_open(const char* file_name, const char* mode) { #if defined(_PLATFORM_WINDOWS_) return fopen(file_name, mode); #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(file_name, sname, sizeof(sname)); return fopen(sname, mode); #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool file_delete(const char* file_name) { #if defined(_PLATFORM_WINDOWS_) return DeleteFile(file_name) == TRUE; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(file_name, sname, sizeof(sname)); return unlink(sname) == 0; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool file_close(FILE* fp) { return fclose(fp) == 0; } FORCE_INLINE int file_seek(FILE* fp, int offset, int where) { return fseek(fp, offset, where); } FORCE_INLINE int file_tell(FILE* fp) { return ftell(fp); } FORCE_INLINE size_t get_file_size(const char* file_name) { #if defined(_PLATFORM_WINDOWS_) HANDLE fp = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == fp) { return 0; } DWORD size_high; DWORD size_low = GetFileSize(fp, &size_high); CloseHandle(fp); size_t file_size = 0; #if defined(_PLATFORM_X64_) file_size = (size_t)size_high << 32; #endif file_size |= size_low; return file_size; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(file_name, sname, sizeof(sname)); struct stat st; if (stat(sname, &st) == -1) { return false; } return st.st_size; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool get_file_time(const char* file_name, file_time_t* file_time) { #if defined(_PLATFORM_WINDOWS_) HANDLE fp = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == fp) { return false; } FILETIME ft; if (!GetFileTime(fp, NULL, NULL, &ft)) { CloseHandle(fp); return false; } CloseHandle(fp); SYSTEMTIME st; FileTimeToSystemTime(&ft, &st); file_time->nyear = st.wYear; file_time->nmonth = st.wMonth; file_time->nday = st.wDay; file_time->nhour = st.wHour; file_time->nminute = st.wMinute; file_time->nsecond = st.wSecond; return true; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(file_name, sname, sizeof(sname)); struct stat st; if (stat(sname, &st) == -1) { return false; } tm* pt = gmtime(&st.st_mtime); file_time->nyear = pt->tm_year + 1900; file_time->nmonth = pt->tm_mon + 1; file_time->nday = pt->tm_mday; file_time->nhour = pt->tm_hour; file_time->nminute = pt->tm_min; file_time->nsecond = pt->tm_sec; return true; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool set_file_time(const char* file_name, const file_time_t* file_time) { #if defined(_PLATFORM_WINDOWS_) HANDLE handle = CreateFile(file_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == handle) { return false; } SYSTEMTIME st; FILETIME ft; memset(&st, 0, sizeof(st)); st.wYear = (WORD)file_time->nyear; st.wMonth = (WORD)file_time->nmonth; st.wDay = (WORD)file_time->nday; st.wHour = (WORD)file_time->nhour; st.wMinute = (WORD)file_time->nminute; st.wSecond = (WORD)file_time->nsecond; SystemTimeToFileTime(&st, &ft); if (!SetFileTime(handle, &ft, &ft, &ft)) { CloseHandle(handle); return false; } CloseHandle(handle); return true; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(file_name, sname, sizeof(sname)); struct utimbuf ut; struct tm tm1; memset(&tm1, 0, sizeof(tm1)); tm1.tm_year = file_time->nyear; tm1.tm_mon = file_time->nmonth; tm1.tm_mday = file_time->nday; tm1.tm_hour = file_time->nhour; tm1.tm_min = file_time->nminute; tm1.tm_sec = file_time->nsecond; ut.actime = mktime(&tm1); ut.modtime = ut.actime; return utime(sname, &ut) == 0; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool enable_file_modify(const char* file_name) { #if defined(_PLATFORM_WINDOWS_) return SetFileAttributes(file_name, FILE_ATTRIBUTE_ARCHIVE) == TRUE; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(sname, sname, sizeof(sname)); return chmod(sname, 0777) == 0; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE const char* dll_name(const char* name, char* buf, size_t size) { #if defined(_PLATFORM_WINDOWS_) size_t name_size = strlen(name) + 1; if (name_size > size) { memcpy(buf, name, size - 1); buf[size - 1] = 0; } else { memcpy(buf, name, name_size); } return buf; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char* p = buf; bool has_path = (strchr(name, '/') != NULL) || (strchr(name, '\\') != NULL); if (!has_path) { // current dir flag *p++ = '.'; *p++ = '/'; size -= 2; } size_t ext_len = strlen(DLL_POSTFIX); size -= ext_len; size_t name_size = strlen(name) + 1; if (name_size > size) { memcpy(p, name, size - 1); p[size - 1] = 0; } else { memcpy(p, name, name_size); } if (ext_len > 0) { char* dot = strrchr(p, '.'); if (dot) { // change file ext memcpy(dot + 1, DLL_POSTFIX, ext_len + 1); } } return buf; #endif // end of _PLATFORM_LINUX_ } // @brief 读取文件 FORCE_INLINE size_t file_read(void* buf, size_t buf_len, FILE* fp) { return fread(buf, 1, buf_len, fp); } // @brief 写入文件 FORCE_INLINE size_t file_write(const void* buf, size_t buf_len, FILE* fp) { return fwrite(buf, 1, buf_len, fp); } // @brief 写入文件 FORCE_INLINE int file_printf(FILE* fp, const char* format, ...) { va_list args; va_start(args, format); int res = vfprintf(fp, format, args); va_end(args); return res; } // @brief 刷新文件 FORCE_INLINE int file_flush(FILE* fp) { return fflush(fp); } // @brief 刷新文件 FORCE_INLINE bool file_eof(FILE* fp) { return feof(fp) != 0; } // @brief 读取文件到缓冲区中 FORCE_INLINE size_t file_readstring(const char* name, char* buffer, size_t buf_len) { FILE* fp = file_open(name, "rb"); if (nullptr == fp) return 0; size_t read_len = file_read(buffer, buf_len, fp); file_close(fp); return read_len; } FORCE_INLINE dll_handle_t dll_open(const char* file_name) { #if defined(_PLATFORM_WINDOWS_) return LoadLibraryA(file_name); #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(file_name, sname, sizeof(sname)); return dlopen(sname, RTLD_NOW); #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE const char* dll_error(char* buffer, size_t size) { #if defined(_PLATFORM_WINDOWS_) if (NULL == buffer) { return NULL; } DWORD err = GetLastError(); if (0 == err) { return NULL; } wchar_t _temp[128]; if (FormatMessageW( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, _temp, (DWORD)128, NULL) == 0) { return NULL; } //widestr_to_utf8(_temp, buffer, size); return buffer; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char* err = dlerror(); if (NULL == buffer) { return NULL; } if (NULL == err) { return NULL; } size_t err_len = strlen(err); if (err_len >= size) { memcpy(buffer, err, size - 1); buffer[size - 1] = 0; } else { memcpy(buffer, err, err_len + 1); } return buffer; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE void* dll_symbol(dll_handle_t handle, const char* name) { #if defined(_PLATFORM_WINDOWS_) return GetProcAddress(handle, name); #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ dlerror(); void* addr = dlsym(handle, name); char* err = dlerror(); if (err) { return NULL; } return addr; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool dll_close(dll_handle_t handle) { #if defined(_PLATFORM_WINDOWS_) return FreeLibrary(handle) == TRUE; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ return dlclose(handle) == 0; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE file_search_t* find_open() { file_search_t* find_ = new file_search_t; memset(find_, 0, sizeof(file_search_t)); return find_; } FORCE_INLINE bool find_first(file_search_t* file_search, const char* path, const char* name) { #if defined(_PLATFORM_WINDOWS_) file_search->handle = INVALID_HANDLE_VALUE; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ file_search->pdir = NULL; file_search->pent = NULL; file_search->strpath[0] = 0; file_search->strext[0] = 0; #endif // end of _PLATFORM_LINUX_ #if defined(_PLATFORM_WINDOWS_) char fname[512]; if (name[0] == 0) { // search all file _snprintf(fname, sizeof(fname) - 1, "%s*.*", path); fname[sizeof(fname) - 1] = 0; } else { if (strchr(name, '.') != NULL) { // match symbol _snprintf(fname, sizeof(fname) - 1, "%s%s", path, name); fname[sizeof(fname) - 1] = 0; } else { // extend file name _snprintf(fname, sizeof(fname) - 1, "%s*.%s", path, name); fname[sizeof(fname) - 1] = 0; } } file_search->handle = FindFirstFile(fname, &file_search->data); if (INVALID_HANDLE_VALUE == file_search->handle) { return false; } while (true) { const char* _file_name = file_search->data.cFileName; if ((strcmp(_file_name, ".") == 0) || (strcmp(_file_name, "..") == 0)) { // 剔除父目录和当前目录(win下隐藏文件和普通文件一样遍历) if (FindNextFile(file_search->handle, &file_search->data) != TRUE) { return false; } continue; } break; } return true; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ char sname[512]; get_standard_path(path, sname, sizeof(sname)); size_t path_len = strlen(sname); if (path_len >= sizeof(file_search->strpath)) { return false; } const char* nameDummy = name; { char buf[512]; const char* tok1 = strrchr(name, '/'); const char* tok2 = strrchr(name, '\\'); const char* tok = defmax(tok1, tok2); if (tok > name) { memcpy(buf, name, tok - name); buf[tok - name] = 0; strcat(sname, "/"); strcat(sname, buf); get_standard_path(sname, buf, sizeof(buf)); strcpy(sname, buf); nameDummy = tok + 1; } } // 文件扩展名,只支持(*.*)或(*.xxx)的格式 const char* ext = nameDummy; const char* name_dot = strchr(nameDummy, '.'); if (name_dot) { if (*(name_dot + 1) == '*') { // 认为是(*.*) ext = ""; } else { // (*.xxx) ext = name_dot + 1; } } size_t ext_len = strlen(ext); if (ext_len >= sizeof(file_search->strext)) { return false; } DIR* pDir = opendir(sname); if (NULL == pDir) { return false; } dirent* pEnt = readdir(pDir); if (ext[0] != 0) { while (pEnt) { if (strcasecmp(pEnt->d_name, ".") == 0 || strcasecmp(pEnt->d_name, "..") == 0) { // 剔除父目录和当前目录(注意并没有剔除隐藏文件,需要自己剔除) // 读取下一个 pEnt = readdir(pDir); continue; } const char* dot = strchr(pEnt->d_name, '.'); if (dot) { if (strcasecmp(ext, dot + 1) == 0) { // 文件扩展名匹配 break; } } // 读取下一个 pEnt = readdir(pDir); } } else { while (pEnt) { if (strcasecmp(pEnt->d_name, ".") == 0 || strcasecmp(pEnt->d_name, "..") == 0) { // 剔除父目录和当前目录(注意并没有剔除隐藏文件,需要自己剔除) // 读取下一个 pEnt = readdir(pDir); } else { break; } } } if (NULL == pEnt) { closedir(pDir); return false; } file_search->pdir = pDir; file_search->pent = pEnt; memcpy(file_search->strpath, path, path_len + 1); memcpy(file_search->strext, ext, ext_len + 1); return true; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE const char* get_find_name(file_search_t* file_search) { #if defined(_PLATFORM_WINDOWS_) return file_search->data.cFileName; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ return file_search->pent->d_name; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool find_is_file(file_search_t* file_search) { #if defined(_PLATFORM_WINDOWS_) return (file_search->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ std::string fname(file_search->strpath); fname += "/"; fname += file_search->pent->d_name; struct stat st; if (stat(fname.c_str(), &st) == -1) { return false; } return (st.st_mode & S_IFMT) == S_IFREG; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool find_is_dir(file_search_t* file_search) { #if defined(_PLATFORM_WINDOWS_) return (file_search->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ std::string fname(file_search->strpath); fname += "/"; fname += file_search->pent->d_name; struct stat st; if (stat(fname.c_str(), &st) == -1) { return false; } return (st.st_mode & S_IFMT) == S_IFDIR; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool find_next(file_search_t* file_search) { #if defined(_PLATFORM_WINDOWS_) if (FindNextFile(file_search->handle, &file_search->data) != TRUE) { return false; } while (true) { const char* _file_name = file_search->data.cFileName; if ((strcmp(_file_name, ".") == 0) || (strcmp(_file_name, "..") == 0)) { // 剔除父目录和当前目录(win下隐藏文件和普通文件一样遍历) if (FindNextFile(file_search->handle, &file_search->data) != TRUE) { return false; } continue; } break; } return true; #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ dirent* pEnt = readdir(file_search->pdir); const char* ext = file_search->strext; if (ext[0] != 0) { while (pEnt) { if (strcasecmp(pEnt->d_name, ".") == 0 || strcasecmp(pEnt->d_name, "..") == 0) { // 剔除父目录和当前目录(注意并没有剔除隐藏文件,需要自己剔除) // 读取下一个 pEnt = readdir(file_search->pdir); continue; } const char* dot = strchr(pEnt->d_name, '.'); if (dot) { if (strcasecmp(ext, dot + 1) == 0) { // match file ext break; } } // next pEnt = readdir(file_search->pdir); } } else { while (pEnt) { if (strcasecmp(pEnt->d_name, ".") == 0 || strcasecmp(pEnt->d_name, "..") == 0) { // 剔除父目录和当前目录(注意并没有剔除隐藏文件,需要自己剔除) // 读取下一个 pEnt = readdir(file_search->pdir); } else { break; } } } if (NULL == pEnt) { return false; } file_search->pent = pEnt; return true; #endif // end of _PLATFORM_LINUX_ } FORCE_INLINE bool find_close(file_search_t* file_search) { #if defined(_PLATFORM_WINDOWS_) if (file_search->handle != INVALID_HANDLE_VALUE) { if (FindClose(file_search->handle) != TRUE) { delete file_search; return false; } } #elif defined(_PLATFORM_LINUX_) // end of _PLATFORM_WINDOWS_ if (file_search->pdir != NULL) { if (closedir(file_search->pdir) != 0) { delete file_search; return false; } } #endif // end of _PLATFORM_LINUX_ delete file_search; return true; } }