30 #include YFM_YCLib_FileSystem
31 #include YFM_YCLib_NativeAPI
32 #include YFM_CHRLib_CharacterProcessing
38 extern "C" int _EXFUN(fileno, (FILE *));
40 # if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
46 extern "C" _CRTIMP
int __cdecl __MINGW_NOTHROW
49 extern "C" _CRTIMP ::FILE* __cdecl __MINGW_NOTHROW
50 _wfopen(
const wchar_t*,
const wchar_t*);
57 # include <sys/stat.h>
61 using namespace CHRLib;
66 static_assert(std::is_same<CHRLib::ucs2_t, char16_t>::value,
67 "Wrong character type found.");
68 static_assert(std::is_same<CHRLib::ucs4_t, char32_t>::value,
69 "Wrong character type found.");
72 "Wrong character type found.");
74 "Inconsistent alignment between character types found.");
80 #if YCL_DS || YCL_Android
83 u_to_w(
const char* str)
85 return std::wstring(reinterpret_cast<const wchar_t*>(
ucsdup(str).c_str()));
95 WIN32_FIND_DATAW& find_data;
97 DirEnv(std::wstring&, ::WIN32_FIND_DATAW&);
102 DirEnv::DirEnv(std::wstring& dir_name, ::WIN32_FIND_DATAW& win32_fdata)
103 : d_name(), find_data(win32_fdata)
105 yconstraint(!dir_name.empty() && dir_name.back() !=
'\\');
107 const auto r(::GetFileAttributesW(dir_name.c_str()));
109 if(
r != INVALID_FILE_ATTRIBUTES &&
r & FILE_ATTRIBUTE_DIRECTORY)
112 throw FileOperationFailure(
"Opening directory failed.");
119 std::wstring dir_name;
120 ::WIN32_FIND_DATAW find_data;
125 DirectoryData(
const char*);
142 DirectoryData::DirectoryData(const
char*
name)
143 : dir_name(ystdex::
rtrim(u_to_w(
name), L"/\\")),
144 find_data(), h_node(), posix_dir(dir_name, find_data)
146 DirectoryData::~DirectoryData()
155 const auto res(::FindClose(h_node));
157 YAssert(res,
"No valid directory found.");
162 DirectoryData::Read()
168 yassume(dir_name.back() != L
'\\');
169 if((h_node = ::FindFirstFileW(dir_name.c_str(), &find_data))
170 == INVALID_HANDLE_VALUE)
173 else if(!::FindNextFileW(h_node, &find_data))
178 if(h_node && h_node != INVALID_HANDLE_VALUE)
181 posix_dir.d_name = find_data.cFileName;
183 return !h_node ?
nullptr : &posix_dir;
197 # error "Unsupported platform found."
208 return ::open(filename, oflag);
212 return ::_wopen(u_to_w(filename).c_str(), oflag);
224 return ::open(filename, oflag, pmode);
228 return ::_wopen(u_to_w(filename).c_str(), oflag, pmode);
242 return ::open(
strdup(filename).c_str(), oflag);
248 return ::_wopen(reinterpret_cast<const wchar_t*>(filename), oflag);
258 return ::open(
strdup(filename).c_str(), oflag, pmode);
264 return ::_wopen(reinterpret_cast<const wchar_t*>(filename), oflag, pmode);
275 return std::fopen(filename, mode);
279 return ::_wfopen(u_to_w(filename).c_str(), u_to_w(mode).c_str());
295 return std::fopen(
strdup(filename).c_str(),
strdup(mode).c_str());
301 return ::_wfopen(reinterpret_cast<const wchar_t*>(filename),
302 reinterpret_cast<const wchar_t*>(mode));
313 if(
const auto file =
ufopen(filename,
"rb"))
326 if(
const auto file =
ufopen(filename, u
"rb"))
343 using namespace CHRLib;
348 const auto p(static_cast<ucs2_t*>(malloc((size + 1)
354 ::getcwd(reinterpret_cast<char*>(buf), size)));
361 memcpy(buf, p, ++len *
sizeof(
ucs2_t));
368 return reinterpret_cast<ucs2_t*
>(
369 ::_wgetcwd(reinterpret_cast<wchar_t*>(buf), size));
376 #define YCL_FileSystem_ufunc_impl1(_n) \
378 _n(const char* path) ynothrow \
383 # define YCL_FileSystem_ufunc_impl2(_fn, _wfn) \
385 return _fn(path) == 0; \
388 # define YCL_FileSystem_ufunc_impl2(_fn, _wfn) \
392 return _wfn(u_to_w(path).c_str()) == 0; \
401 #define YCL_FileSystem_ufunc_impl(_n, _fn, _wfn) \
402 YCL_FileSystem_ufunc_impl1(_n) \
403 YCL_FileSystem_ufunc_impl2(_fn, _wfn)
409 return ::mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) == 0;
421 #undef YCL_FileSystem_ufunc_impl1
422 #undef YCL_FileSystem_ufunc_impl2
423 #undef YCL_FileSystem_ufunc_impl
429 return ::ftruncate(fileno(
fp), ::off_t(size)) == 0;
431 return ::_chsize(::_fileno(
fp),
long(size)) == 0;
442 if(::fstat(fd, &st) == 0)
448 if(::GetFileSizeEx(::HANDLE(::_get_osfhandle(fd)), &sz) != 0
458 #ifdef YCL_API_FILESYSTEM_POSIX
473 (path && *path !=
'\0' ? path :
".")
482 const auto res(::closedir(
dir));
484 YAssert(res == 0,
"No valid directory found.");
487 delete static_cast<DirectoryData*
>(
dir);
498 static_cast<DirectoryData*
>(
dir)->Rewind();
507 p_dirent = ::readdir(GetNativeHandle());
509 p_dirent =
static_cast<DirectoryData*
>(GetNativeHandle())->Read();
523 return static_cast<DirectoryData*
>(GetNativeHandle())->GetAttributes()
541 utf8_name =
strdup(reinterpret_cast<const char16_t*>(
542 (static_cast<DirEnv*>(
p_dirent))->d_name.c_str()));
543 return &utf8_name[0];
562 const auto p(std::strstr(path,
":/"));
564 return p && p != path && !std::strstr(p,
":/");
568 return !::PathIsRelativeW(u_to_w(path).c_str());
575 const char* p(std::strchr(path,
':'));
577 return !p ? 0 : p - path + 1;
582 namespace platform_ex
589 const std::u16string ustr(str);
591 return ustr == u
"/" || ustr == u
"fat:/" || ustr == u
"sd:/";
char16_t * u16getcwd_n(char16_t *buf, std::size_t size) ynothrow
std::FILE ConversionState fp
YF_API bool IsAbsolute(const char *)
判断指定路径字符串是否表示一个绝对路径。
YF_API std::string strdup(const ucs2_t *, Encoding=CS_Default)
复制 UCS-2 字符串为多字节字符串。
YF_API bool truncate(std::FILE *, std::size_t) ynothrow
截断文件至指定长度。
YF_API std::size_t GetRootNameLength(const char *)
取指定路径的文件系统根节点名称的长度。
DirectorySession(const char *path={})
构造:打开目录路径。
#define yunused(...)
标记未使用的表达式。
GetName()) const char *GetName() const ynothrow
间接操作:取节点名称。
YF_API size_t MBCSToUCS2(ucs2_t *, const char *, Encoding=CS_Default)
按指定编码转换 MBCS 字符串为 UCS-2 字符串,返回转换的串长。
#define YCL_FileSystem_ufunc_impl(_n, _fn, _wfn)
YF_API bool ufexists(const char *) ynothrow
判断指定 UTF-8 文件名的文件是否存在。
#define DefGetter(_q, _t, _n,...)
YF_API std::basic_string< ucs2_t > ucsdup(const char *, Encoding=CS_Default)
复制多字节字符串为 UCS-2 字符串。
std::size_t size ynothrow
YF_API bool uchdir(const char *) ynothrow
切换当前工作路径至指定的 UTF-8 字符串。
YF_API bool urmdir(const char *) ynothrow
按 UTF-8 路径删除一个空目录。
不可复制对象:禁止派生类调用默认原型的复制构造函数和复制赋值操作符。
~DirectorySession()
析构:关闭目录路径。
#define ynothrow
YSLib 无异常抛出保证:若支持 noexcept 关键字, 指定特定的 noexcept 异常规范。
yconstfn const string & name
#define yalignof(_type)
指定特定类型的对齐。
YF_API std::FILE * ufopen(const char *filename, const char *mode) ynothrow
以 UTF-8 文件名打开文件。
#define yconstraint
约束:接口语义。
#define YCL_FileSystem_ufunc_impl2(_fn, _wfn)
NodeCategory GetNodeCategory() const ynothrow
取节点状态信息确定的文件系统节点类别。
if(YB_LIKELY(!error)) if(YB_LIKELY(!(error
YF_API bool uunlink(const char *) ynothrow
按 UTF-8 路径删除一个非目录文件。
YF_API bool uremove(const char *) ynothrow
按 UTF-8 路径删除一个文件。
YF_API bool umkdir(const char *) ynothrow
按 UTF-8 路径以默认权限新建一个目录。
const ynothrow ImplRet this HDirectory & operator++()
迭代:向后遍历。
char16_t FS_IsRoot(const char16_t *)
#define YCL_FileSystem_ufunc_impl1(_n)
char16_t ucs2_t
UCS-2 字符类型。
#define DefGetterMem(_q, _t, _n, _m)
YF_API std::uint64_t GetFileSizeOf(int)
取文件的大小。
bool fexists(const char *)
判断指定路径的文件是否存在。
YF_API int uopen(const char *filename, int oflag) ynothrow
以 UTF-8 文件名无缓冲打开文件。
#define YAssert(_expr, _msg)
_tString && rtrim(_tString &&str, typename string_traits< _tString >::const_pointer t=&to_array< typename string_traits< _tString >::value_type >("\n\r\t\v ")[0])
删除字符串中指定的连续后缀字符。