YSTest: FileSystem.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

YSLib/Service/FileSystem.cpp
浏览该文件的文档.
1 /*
2 © 2010-2016 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 #include "YSLib/Service/YModules.h"
29 #include YFM_YSLib_Service_FileSystem
30 #include <ystdex/cstring.h>
31 #include <ystdex/exception.h> // for ystdex::throw_error, system_error;
32 #include YFM_YSLib_Service_File // for OpenFile;
33
34 namespace YSLib
35 {
36
37 using namespace Text;
38
39 namespace IO
40 {
41
42 String
43 Path::GetString(char16_t delimiter) const
44 {
45 const auto res(ystdex::to_string_d(GetBase(), delimiter));
46
47 YAssert(res.empty() || res.back() == delimiter,
48 "Invalid conversion result found.");
49 return res;
50 }
51
52 ypath
53 Path::Parse(const u16string& str)
54 {
55 ypath res;
56
57 ystdex::split(str.cbegin(), str.cend(), [&](char16_t c){
58 return PathTraits::IsDelimiter(c);
59 }, [&](u16string::const_iterator b, u16string::const_iterator e){
60 if(b != e)
61 res.push_back(u16string(b, e));
62 });
63 // NOTE: Fix first component for absolute path beginning with delimiter.
64 if(!res.empty() && IsRelative(res.front()) && IsAbsolute(str.c_str()))
65 res.insert(res.cbegin(), {{}});
66 return res;
67 }
68
69 String
70 Path::Verify(char16_t delimiter) const
71 {
72 auto res(GetString(delimiter));
73
74 if(!(res.empty() || VerifyDirectory(res)))
75 res.pop_back();
76 return res;
77 }
78
79
80 String
81 FetchCurrentWorkingDirectory(size_t len)
82 {
83 u16string str(len, char16_t());
84
85 ugetcwd(&str[0], len);
86 return str;
87 }
88
89 Path
90 MakeNormalizedAbsolute(const Path& pth, size_t len)
91 {
92 Path res(pth);
93
94 if(IsRelative(res))
95 res = Path(FetchCurrentWorkingDirectory(len)) / res;
96 res.Normalize();
97 YTraceDe(Debug, "Converted path is '%s'.", res.VerifyAsMBCS().c_str());
98 YAssert(IsAbsolute(res), "Invalid path converted.");
99 return res;
100 }
101
102
104 namespace
105 {
106
107 template<typename _tChar>
108 YB_NONNULL(1) bool
109 VerifyDirectoryImpl(const _tChar* path)
110 {
111 try
112 {
113 DirectorySession ss(path);
114
115 return true;
116 }
117 CatchIgnore(FileOperationFailure&)
118 return {};
119 }
120
121 } // unnamed namespace;
122
123 bool
124 VerifyDirectory(const char* path)
125 {
126 return VerifyDirectoryImpl(path);
127 }
128 bool
129 VerifyDirectory(const char16_t* path)
130 {
131 return VerifyDirectoryImpl(path);
132 }
133
134 void
135 EnsureDirectory(const Path& pth)
136 {
137 string upath;
138
139 for(const auto& name : pth)
140 {
141 upath += MakeMBCS(name.c_str()) + YCL_PATH_DELIMITER;
142 if(!VerifyDirectory(upath) && !umkdir(upath.c_str()) && errno != EEXIST)
143 {
144 YTraceDe(Err, "Failed making directory path '%s'", upath.c_str());
145 ystdex::throw_error(errno);
146 }
147 }
148 }
149
150
152 namespace
153 {
154
156 YB_NONNULL(1) UniqueFile
157 OpenFileForCopy(const char* src)
158 {
159 return
160 OpenFile(src, omode_convb(std::ios_base::in | std::ios_base::binary));
161 }
162
163 } // unnamed namespace;
164
165 void
166 CopyFile(UniqueFile p_dst, FileDescriptor src_fd)
167 {
168 FileDescriptor::WriteContent(Nonnull(p_dst.get()), Nonnull(src_fd));
169 }
170 void
171 CopyFile(UniqueFile p_dst, const char* src)
172 {
173 CopyFile(std::move(p_dst), OpenFileForCopy(src).get());
174 }
175 void
176 CopyFile(const char* dst, FileDescriptor src_fd, mode_t dst_mode,
177 size_t allowed_links, bool share)
178 {
179 FileDescriptor::WriteContent(EnsureUniqueFile(dst, dst_mode, allowed_links,
180 share).get(), Nonnull(src_fd));
181 }
182 void
183 CopyFile(const char* dst, const char* src, mode_t dst_mode,
184 size_t allowed_links, bool share)
185 {
186 CopyFile(dst, OpenFileForCopy(src).get(), dst_mode, allowed_links, share);
187 }
188 void
189 CopyFile(const char* dst, FileDescriptor src_fd, CopyFileHandler f,
190 mode_t dst_mode, size_t allowed_links, bool share)
191 {
192 const auto p_dst(EnsureUniqueFile(dst, dst_mode, allowed_links,
193 share));
194
195 FileDescriptor::WriteContent(p_dst.get(), Nonnull(src_fd));
196 // NOTE: Guards are not used since the post operations should only be
197 // performed after success copying.
198 f(p_dst.get(), src_fd);
199 }
200 void
201 CopyFile(const char* dst, const char* src, CopyFileHandler f, mode_t dst_mode,
202 size_t allowed_links, bool share)
203 {
204 CopyFile(dst, OpenFileForCopy(src).get(), f, dst_mode, allowed_links,
205 share);
206 }
207
208
209 void
210 ClearTree(const Path& pth)
211 {
212 TraverseChildren(pth, [&](NodeCategory c, NativePathView npv){
213 const auto child(pth / String(npv));
214
215 if(c == NodeCategory::Directory)
216 DeleteTree(child);
217 TryRemove(string(child).c_str());
218 });
219 }
220
221 void
222 ListFiles(const Path& pth, vector<String>& lst)
223 {
224 Traverse(pth, [&](NodeCategory c, NativePathView npv){
225 lst.push_back(!PathTraits::is_parent(npv)
226 && bool(c & NodeCategory::Directory) ? String(npv)
227 + char16_t(YCL_PATH_DELIMITER) : String(npv));
228 });
229 }
230
231
232 NodeCategory
233 ClassifyNode(const Path& pth)
234 {
235 if(pth.empty())
236 return NodeCategory::Empty;
237
238 const auto& fname(pth.back());
239
240 switch(ystdex::classify_path<String, PathTraits>(fname))
241 {
242 case ystdex::path_category::empty:
243 return NodeCategory::Empty;
244 case ystdex::path_category::self:
245 case ystdex::path_category::parent:
246 break;
247 default:
248 return VerifyDirectory(pth) ? NodeCategory::Directory
249 : (ufexists(String(pth).c_str()) ? NodeCategory::Regular
250 : NodeCategory::Missing);
251 // TODO: Implementation for other categories.
252 }
253 return NodeCategory::Unknown;
254 }
255
256 } // namespace IO;
257
258 } // namespace YSLib;
259
YSLib::IO::FetchCurrentWorkingDirectory
String FetchCurrentWorkingDirectory(size_t len)
Definition: YSLib/Service/FileSystem.cpp:81
YSLib::IO::MakeNormalizedAbsolute
YF_API Path MakeNormalizedAbsolute(const Path &, size_t=MaxPathLength)
根据当前工作目录和指定路径取绝对路径。
Definition: YSLib/Service/FileSystem.cpp:90
platform::mode_t
::mode_t mode_t
文件模式类型。
Definition: FileIO.h:108
cstring.h
ISO C 标准字符串扩展。
platform::Nonnull
_type && Nonnull(_type &&p) ynothrow
断言并返回非空指针。
Definition: Debug.h:411
YSLib::IO::Traverse
void Traverse(const string &path, _func f)
Definition: YSLib/Service/FileSystem.h:454
YSLib::IO::CopyFile
void CopyFile(const char *dst, const char *src, CopyFileHandler f, mode_t dst_mode, size_t allowed_links, bool share)
Definition: YSLib/Service/FileSystem.cpp:201
platform::containers::u16string
basic_string< char16_t > u16string
Definition: Container.h:103
NPL::A1::name
ctx const string & name
Definition: NPLA1.h:248
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:45
ystdex::path_category::parent
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:109
YSLib::IO::ypath
ystdex::path< vector< String >, PathTraits > ypath
Definition: YSLib/Service/FileSystem.h:102
platform::NodeCategory
NodeCategory
文件节点类别。
Definition: FileIO.h:117
NPL::SXML::ParseOption::String
YSLib::IO::CopyFileHandler
std::function< void(FileDescriptor, FileDescriptor)> CopyFileHandler
复制文件处理器：通知文件复制事件。
Definition: YSLib/Service/FileSystem.h:534
platform_ex::Windows::Directory
Definition: MinGW32.h:442
YSLib::Text::String
YSLib 标准字符串（使用 UCS-2 作为内部编码）。
Definition: YString.h:46
CHRLib::c
c
Definition: CharacterProcessing.h:81
YSLib::IO::DeleteTree
DeleteTree
Definition: YSLib/Service/FileSystem.h:634
YSLib::IO::EnsureDirectory
void EnsureDirectory(const Path &pth)
Definition: YSLib/Service/FileSystem.cpp:135
platform::ufexists
bool ufexists(const char *filename) ynothrowv
Definition: FileIO.cpp:875
CHRLib::char16_t
char16_t((*c_ptr<< CHAR_BIT)|c_ptr[1])) inline PDefH(char16_t
取 c_ptr 指向的小端序双字节字符。
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:305
CatchIgnore
#define CatchIgnore(_ex)
指定异常处理器忽略指定异常。
Definition: YBaseMacro.h:133
platform::UniqueFile
unique_ptr_from< FileDescriptor::Deleter > UniqueFile
Definition: FileIO.h:427
YSLib::IO::PathTraits::is_parent
static yconstfn bool is_parent(const _tString &str) ynothrow
Definition: YSLib/Service/FileSystem.h:74
YSLib::IO::OpenFile
UniqueFile OpenFile(const char *filename, int omode, mode_t pmode)
Definition: File.cpp:38
NPL::dst
YF_API const char src const string const char * dst
Definition: Dependency.h:93
YModules.h
ystdex::throw_error
void throw_error(std::error_code ec, _tParams &&...args)
抛出错误： std::system_error 或允许相同构造函数参数的异常。
Definition: ystdex/exception.h:162
YSLib::IO::ListFiles
void ListFiles(const Path &pth, vector< String > &lst)
Definition: YSLib/Service/FileSystem.cpp:222
platform::umkdir
bool umkdir(const char *path) ynothrowv
Definition: FileIO.cpp:1025
exception.h
YSLib::IO::VerifyDirectory
bool VerifyDirectory(const char16_t *path)
Definition: YSLib/Service/FileSystem.cpp:129
YSLib::IO::ClearTree
YF_API void ClearTree(const Path &)
路径指向的不是一个目录或删除失败。
Definition: YSLib/Service/FileSystem.cpp:210
platform::KeyCodes::Win32::Empty
Definition: Keys.h:279
ystdex::basic_string_view
Definition: string_view.hpp:49
YSLib::YAssert
YAssert(!(v< Deref(a)),"Value less than lower bound found.")
YSLib::path
YF_API const char * path
Definition: Initialization.h:74
IO
platform::DirectorySession
目录会话：表示打开的目录。
Definition: YCLib/FileSystem.h:416
YSLib::Text::str
const char const char * str
Definition: TextFile.h:77
YSLib::IO::TraverseChildren
void TraverseChildren(const string &path, _func f)
Definition: YSLib/Service/FileSystem.h:485
YSLib::IO::ClassifyNode
const Path &pth const string &pth vector< String > &YF_API NodeCategory ClassifyNode(const Path &)
按文件系统节点类别对路径分类。
Definition: YSLib/Service/FileSystem.cpp:233
YSLib::Text::YB_NONNULL
YB_NONNULL(1, 2) PDefH(bool
检查缓冲区是否具有指定的 BOM 。
ystdex::path_category::empty
ystdex::path_category::self
platform::Descriptions::Debug
Definition: YCommon.h:160
Text
platform::omode_convb
std::ios_base::sync_with_stdio(sync)) YF_API YB_STATELESS int omode_conv(std YF_API YB_STATELESS int omode_convb(std::ios_base::openmode) ynothrow
ISO C++ 标准输入输出接口打开模式转换为 POSIX 文件打开模式。
Definition: FileIO.cpp:768
NPL::c_str
YF_API const char src c_str())) YF_API void InstallDirectory(const string &
安装目录：复制目录树。
platform::ugetcwd
char * ugetcwd(char *buf, size_t size) ynothrowv
Definition: FileIO.cpp:939
CHRLib::MakeMBCS
_tDst MakeMBCS(string_view sv, Encoding enc)
Definition: CharacterProcessing.h:603
ystdex::split
void split(_tIn b, _tIn e, _fPred is_delim, _fInsert insert)
以指定分隔符分割序列。
Definition: algorithm.hpp:209
YSLib::IO::Path
路径。
Definition: YSLib/Service/FileSystem.h:109
platform::Descriptions::Err
Definition: YCommon.h:156
YSLib::IO::f
const string &path const String &path _func f
Definition: YSLib/Service/FileSystem.h:430
platform::FileDescriptor::WriteContent
static void WriteContent(FileDescriptor, FileDescriptor, size_t=yimpl(size_t(BUFSIZ<< 4)))
Definition: FileIO.cpp:680
platform::EnsureUniqueFile
UniqueFile EnsureUniqueFile(const char *dst, mode_t mode, size_t allowed_links, bool share)
Definition: FileIO.cpp:1122
platform::bool
std::FILE *fp bool
Definition: FileIO.h:1187
platform::FileDescriptor
文件描述符包装类。
Definition: FileIO.h:171
YSLib::IO::PathTraits::IsDelimiter
static yconstfn bool IsDelimiter(_tChar c) ynothrow
Definition: YSLib/Service/FileSystem.h:67
YSLib::IO::IsAbsolute
IsAbsolute
Definition: YSLib/Service/FileSystem.h:351