YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
YCLib/FileSystem.h
浏览该文件的文档.
1 /*
2  © 2012-2014 FrankHB.
3 
4  This file is part of the YSLib project, and may only be used,
5  modified, and distributed under the terms of the YSLib project
6  license, LICENSE.TXT. By continuing to use, modify, or distribute
7  this file you indicate that you have read the license and
8  understand and accept it fully.
9 */
10 
28 #ifndef YCL_INC_FileSystem_h_
29 #define YCL_INC_FileSystem_h_ 1
30 
31 #include "YModules.h"
32 #include YFM_YCLib_YCommon
33 #include <ystdex/utility.hpp> // for std::is_array, std::is_integral,
34 // ystdex::remove_reference_t, ystdex::arrlen;
35 #include <ystdex/cstring.h> // for ystdex::is_null;
36 #include <ystdex/string.hpp> // for ystdex::string_length, std::string;
37 #include "CHRLib/encoding.h"
38 #if YCL_DS || YCL_MinGW32 || YCL_Android
39 #include <dirent.h>
40 #endif
41 #include <ystdex/iterator.hpp> // for ystdex::indirect_input_iterator;
42 
43 namespace platform
44 {
45 
46 //平台相关的全局常量。
47 
48 /*
49 \brief 判断字符串是否是当前路径。
50 \since build 409
51 */
52 #define YCL_FS_StringIsCurrent(_s, _p) \
53  (ystdex::string_length(_s) == 1 && _s[0] == YPP_Concat(_p, '.'))
54 
55 /*
56 \brief 判断字符串是否是父目录。
57 \since build 409
58 */
59 #define YCL_FS_StringIsParent(_s, _p) \
60  (ystdex::string_length(_s) == 2 \
61  && _s[0] == YPP_Concat(_p, '.') && _s[1] == YPP_Concat(_p, '.'))
62 
63 /*
64 \def YCL_FS_CharIsDelimiter
65 \brief 判断字符是否路径分隔符。
66 \since build 409
67 */
68 
69 /*
70 \def YCL_FS_StringIsRoot
71 \brief 判断字符是否表示根目录路径。
72 \since build 409
73 */
74 
75 #ifdef YCL_API_FILESYSTEM_POSIX
76 
80 # define YCL_PATH_DELIMITER '/'
81 
85 # define YCL_PATH_SEPARATOR "/"
86 
89 # define YCL_PATH_ROOT YCL_PATH_SEPARATOR
90 
95 using NativePathCharType = char;
96 
97 # define YCL_FS_CharIsDelimiter(_c, _p) \
98  (_c == YPP_Join(_p, YCL_PATH_DELIMITER))
99 # define YCL_FS_StringIsRoot(_s, _p) (platform_ex::FS_IsRoot(&_s[0]))
100 
106 #elif YCL_Win32
107 
111 # define YCL_PATH_DELIMITER '\\'
112 // #define YCL_PATH_DELIMITER L'\\'
117 # define YCL_PATH_SEPARATOR "\\"
118 // #define YCL_PATH_SEPARATOR L"\\"
123 # define YCL_PATH_ROOT YCL_PATH_SEPARATOR
124 
129 // using NativePathCharType = wchar_t;
130 using NativePathCharType = char;
131 
132 # define YCL_FS_CharIsDelimiter(_c, _p) \
133  (_c == YPP_Concat(_p, '/') || _c == YPP_Concat(_p, '\\'))
134 # define YCL_FS_StringIsRoot(_s, _p) \
135  (ystdex::string_length(_s) == 3 \
136  && _s[1] == ':' && YCL_FS_CharIsDelimiter(_s[2], _p))
137 
143 #else
144 # error "Unsupported platform found."
145 #endif
146 
148 
149 static_assert(std::is_integral<decltype(YCL_PATH_DELIMITER)>::value,
150  "Illegal type of delimiter found.");
151 static_assert(std::is_array<ystdex::remove_reference_t<decltype(
152  YCL_PATH_SEPARATOR)>>::value, "Non-array type of separator found.");
154 #if YB_HAS_CONSTEXPR
155 static_assert(ystdex::arrlen(YCL_PATH_SEPARATOR) == 2,
156  "Wrong length of separator found.");
157 static_assert(YCL_PATH_SEPARATOR[0] == YCL_PATH_DELIMITER,
158  "Mismatched path delimiter and separator found.");
159 static_assert(ystdex::is_null(YCL_PATH_SEPARATOR[1]),
160  "Non-null-terminator as end of separator.");
161 #endif
162 
163 
164 
172 YF_API int
173 uopen(const char* filename, int oflag) ynothrow;
182 YF_API int
183 uopen(const char* filename, int oflag, int pmode) ynothrow;
191 YF_API int
192 uopen(const char16_t* filename, int oflag) ynothrow;
201 YF_API int
202 uopen(const char16_t* filename, int oflag, int pmode) ynothrow;
203 
211 YF_API std::FILE*
212 ufopen(const char* filename, const char* mode) ynothrow;
220 YF_API std::FILE*
221 ufopen(const char16_t* filename, const char16_t* mode) ynothrow;
222 
229 YF_API bool
230 ufexists(const char*) ynothrow;
237 YF_API bool
238 ufexists(const char16_t*) ynothrow;
244 template<class _tString>
245 inline PDefH(bool, ufexists, const _tString& str) ynothrow
246  ImplRet(ufexists(str.c_str()))
247 
255 YF_API char16_t*
256 u16getcwd_n(char16_t* buf, std::size_t size) ynothrow;
257 
258 /*
259 \pre 断言:参数非空。
260 \return 操作是否成功。
261 \note <tt>errno</tt> 在出错时会被设置,具体值由实现定义。
262 \note DS 使用 newlib 实现。 MinGW32 使用 MSVCRT 实现。
263 */
265 
269 YF_API bool
270 uchdir(const char*) ynothrow;
271 
277 YF_API bool
278 umkdir(const char*) ynothrow;
279 
284 YF_API bool
285 urmdir(const char*) ynothrow;
286 
291 YF_API bool
292 uunlink(const char*) ynothrow;
293 
298 YF_API bool
299 uremove(const char*) ynothrow;
300 
309 YF_API bool
310 truncate(std::FILE*, std::size_t) ynothrow;
312 
313 
323 YF_API std::uint64_t
324 GetFileSizeOf(int);
326 YF_API std::uint64_t
327 GetFileSizeOf(std::FILE*);
329 
330 
332 
333 enum class PathCategory : yimpl(std::uint32_t)
335 {
336  Empty,
337  Self,
338  Parent,
339  Node
340 };
341 
343 enum class NodeCategory : ystdex::underlying_type_t<PathCategory>
344 {
348 
349  Missing,
350  Invalid,
351  Regular,
353  Directory,
360 
362  Device = 0x1000,
363  Block,
364  Character,
365  yimpl()
366  Communicator = 0x2000,
367  FIFO,
368  Socket,
369  yimpl()
370  Link = 0x3000,
372  SymbolicLink,
373  HardLink,
375 
376  Junction,
377  Special = 0x4000,
378  Reparse
379  yimpl()
381 
382 };
384 
385 
390 class YF_API FileOperationFailure : public std::runtime_error
391 {
392 public:
395  : runtime_error(msg)
396  {}
397 };
398 
399 
406 {
407 public:
408 #if !YCL_Win32
409  using NativeHandle = ::DIR*;
410 #else
411  using NativeHandle = void*;
412 #endif
413 
414 private:
416 
417 public:
426  explicit
427  DirectorySession(const char* path = {});
429  : dir(h.dir)
430  {
431  h.dir = {};
432  }
437  ~DirectorySession();
438 
440  DefGetter(const ynothrow, NativeHandle, NativeHandle, dir)
441 
442 
443  void
444  Rewind() ynothrow;
445 };
446 
447 
452 class YF_API HDirectory final : private DirectorySession
453 {
454 private:
455 #if !YCL_Win32
456 
460  ::dirent* p_dirent;
461 #else
462 
466  void* p_dirent;
467 
472  mutable std::string utf8_name;
473 #endif
474 
475 public:
477  explicit
478  HDirectory(const char* path) ynothrow
479  : DirectorySession(path)
480  {}
481 
488  PDefHOp(HDirectory&, *, ) ynothrow
489  ImplRet(*this)
490  PDefHOp(const HDirectory&, *, ) const ynothrow
491  ImplRet(*this)
493 
499  HDirectory&
500  operator++();
502 
507  explicit DefCvt(const ynothrow, bool, p_dirent)
508 
510  DefCvt(const, std::string, GetName())
511 
518  const char*
519  GetName() const ynothrow;
520 
528  GetNodeCategory() const ynothrow;
529 
531  using DirectorySession::Rewind;
532 };
533 
534 
539 using FileIterator = ystdex::indirect_input_iterator<HDirectory*>;
540 
541 
546 YF_API bool
547 IsAbsolute(const char*);
548 
553 YF_API std::size_t
554 GetRootNameLength(const char*);
555 
556 } // namespace platform;
557 
558 namespace platform_ex
559 {
560 
561 #if !YCL_Win32
562 char16_t
564 FS_IsRoot(const char16_t*);
565 #endif
566 
567 } // namespace platform_ex;
568 
569 #endif
570 
char16_t * u16getcwd_n(char16_t *buf, std::size_t size) ynothrow
实用设施。
ISO C++ 标准字符串扩展。
DirectorySession(DirectorySession &&h)
PathCategory
路径类别。
YF_API bool IsAbsolute(const char *)
判断指定路径字符串是否表示一个绝对路径。
间接输入迭代器。
Definition: iterator.hpp:1023
ISO C 标准字符串扩展。
YF_API bool truncate(std::FILE *, std::size_t) ynothrow
截断文件至指定长度。
YF_API std::size_t GetRootNameLength(const char *)
取指定路径的文件系统根节点名称的长度。
typename remove_reference< _type >::type remove_reference_t
Definition: type_op.hpp:234
size_t arrlen(_type(&)[_vN])
计算指定数组类型对象的长度。
Definition: utility.hpp:196
YF_API bool ufexists(const char *) ynothrow
判断指定 UTF-8 文件名的文件是否存在。
#define YF_API
Definition: Platform.h:64
HDirectory(const char *path) ynothrow
构造:使用目录路径。
typename underlying_type< _type >::type underlying_type_t
Definition: type_op.hpp:283
目录句柄:表示打开的目录和内容迭代状态。
yconstfn Integer &Trait::AMask Trait::XYZBitsN yconstfn DefGetter(const ynothrow, typename Trait::BType, B, Integer &Trait::XMask) yconstfn DefGetter(const ynothrow
yconstfn DefCvt(const ynothrow, typename Trait::IntegerType, Integer) yconstfn DefGetter(const ynothrow
std::size_t size ynothrow
YF_API bool uchdir(const char *) ynothrow
切换当前工作路径至指定的 UTF-8 字符串。
YF_API bool urmdir(const char *) ynothrow
按 UTF-8 路径删除一个空目录。
通用迭代器。
GSStringTemplate< char >::basic_string string
Definition: ycont.h:164
::dirent * p_dirent
节点信息。
YF_API std::FILE * ufopen(const char *filename, const char *mode) ynothrow
以 UTF-8 文件名打开文件。
目录会话:表示打开的目录。
YF_API bool uunlink(const char *) ynothrow
按 UTF-8 路径删除一个非目录文件。
yconstexpr const KeyInput KeyIndex ynothrow ImplRet(char()) namespace KeyCodes
本机按键编码。
Definition: Keys.h:191
YF_API bool uremove(const char *) ynothrow
按 UTF-8 路径删除一个文件。
YF_API bool umkdir(const char *) ynothrow
按 UTF-8 路径以默认权限新建一个目录。
char16_t FS_IsRoot(const char16_t *)
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:462
表示文件操作失败的异常。
YF_API std::uint64_t GetFileSizeOf(int)
取文件的大小。
bool is_null(_tChar c)
使用 std::char_traits::eq 判断是否为空字符。
Definition: cstring.h:86
yconstexpr Encoding UTF_8(csUTF8)
FileOperationFailure(const std::string &msg="") ynothrow
YF_API int uopen(const char *filename, int oflag) ynothrow
以 UTF-8 文件名无缓冲打开文件。
NodeCategory
文件系统节点类别。
字符编码定义。
PDefH(bool, ufexists, const _tString &str) ynothrow ImplRet(ufexists(str.c_str())) YF_API char16_t *u16getcwd_n(char16_t *buf
判断指定字符串为文件名的文件是否存在。