YSTest: FileSystem.cpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

YSLib/Service/FileSystem.cpp
浏览该文件的文档.
1 /*
2 © 2010-2016, 2019-2020 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 String
53 Path::Verify(char16_t delimiter) const
54 {
55 return VerifyDirectoryPathTail(GetString(delimiter));
56 }
57
58
59 Path
60 MakeNormalizedAbsolute(const Path& pth, size_t init_size)
61 {
62 Path res(pth);
63
64 if(IsRelative(res))
65 res = Path(FetchCurrentWorkingDirectory<char16_t>(init_size)) / res;
66 res.Normalize();
67 YTraceDe(Debug, "Converted path is '%s'.", res.VerifyAsMBCS().c_str());
68 YAssert(IsAbsolute(res), "Invalid path converted.");
69 return res;
70 }
71
72
74 namespace
75 {
76
77 template<typename _tChar>
78 YB_NONNULL(1) bool
79 VerifyDirectoryImpl(const _tChar* path)
80 {
81 try
82 {
83 DirectorySession ss(path);
84
85 return true;
86 }
87 CatchExpr(std::system_error& e, YTraceDe(Debug,
88 "Directory verfication failed."), ExtractAndTrace(e, Debug))
89 return {};
90 }
91
92 } // unnamed namespace;
93
94 bool
95 VerifyDirectory(const char* path)
96 {
97 return VerifyDirectoryImpl(path);
98 }
99 bool
100 VerifyDirectory(const char16_t* path)
101 {
102 return VerifyDirectoryImpl(path);
103 }
104
105 void
106 EnsureDirectory(const Path& pth)
107 {
108 // NOTE: Similar to %ystdex::to_string_d for %ystdex::path.
109 if(!pth.empty())
110 {
111 auto i(pth.begin());
112 string res(MakeMBCS<string>(*i));
113 const auto delimiter(FetchSeparator<char>());
114 const auto ensure([&]{
115 if(!VerifyDirectory(res) && !umkdir(res.c_str()))
116 {
117 const int err(errno);
118
119 if(err != EEXIST)
120 {
121 YTraceDe(Err, "Failed making directory path '%s'",
122 res.c_str());
123 ystdex::throw_error(err, yfsig);
124 }
125 }
126 });
127
128 if(!PathTraits::has_root_path(res))
129 {
130 res += delimiter;
131 ensure();
132 }
133 while(++i != pth.end())
134 {
135 res += MakeMBCS<string>(*i);
136 res += delimiter;
137 ensure();
138 }
139 }
140 }
141
142
144 namespace
145 {
146
148 YB_NONNULL(1) UniqueFile
149 OpenFileForCopy(const char* src)
150 {
151 return
152 OpenFile(src, omode_convb(std::ios_base::in | std::ios_base::binary));
153 }
154
155 } // unnamed namespace;
156
157 void
158 CopyFile(UniqueFile p_dst, FileDescriptor src_fd)
159 {
160 FileDescriptor::WriteContent(Nonnull(p_dst.get()), Nonnull(src_fd));
161 }
162 void
163 CopyFile(UniqueFile p_dst, const char* src)
164 {
165 CopyFile(std::move(p_dst), OpenFileForCopy(src).get());
166 }
167 void
168 CopyFile(const char* dst, FileDescriptor src_fd, mode_t dst_mode,
169 size_t allowed_links, bool share)
170 {
171 FileDescriptor::WriteContent(EnsureUniqueFile(dst, dst_mode, allowed_links,
172 share).get(), Nonnull(src_fd));
173 }
174 void
175 CopyFile(const char* dst, const char* src, mode_t dst_mode,
176 size_t allowed_links, bool share)
177 {
178 CopyFile(dst, OpenFileForCopy(src).get(), dst_mode, allowed_links, share);
179 }
180 void
181 CopyFile(const char* dst, FileDescriptor src_fd, CopyFileHandler f,
182 mode_t dst_mode, size_t allowed_links, bool share)
183 {
184 const auto p_dst(EnsureUniqueFile(dst, dst_mode, allowed_links,
185 share));
186
187 FileDescriptor::WriteContent(p_dst.get(), Nonnull(src_fd));
188 // NOTE: Guards are not used since the post operations should only be
189 // performed after success copying.
190 f(p_dst.get(), src_fd);
191 }
192 void
193 CopyFile(const char* dst, const char* src, CopyFileHandler f, mode_t dst_mode,
194 size_t allowed_links, bool share)
195 {
196 CopyFile(dst, OpenFileForCopy(src).get(), f, dst_mode, allowed_links,
197 share);
198 }
199
200
201 void
202 ClearTree(const Path& pth)
203 {
204 TraverseChildren(pth, [&](NodeCategory c, NativePathView npv){
205 const auto child(pth / String(npv));
206
207 if(c == NodeCategory::Directory)
208 DeleteTree(child);
209 Remove(string(child).c_str());
210 });
211 }
212
213 void
214 ListFiles(const Path& pth, vector<String>& lst)
215 {
216 Traverse(pth, [&](NodeCategory c, NativePathView npv){
217 lst.push_back(!PathTraits::is_parent(npv)
218 && bool(c & NodeCategory::Directory) ? String(npv)
219 + FetchSeparator<char16_t>() : String(npv));
220 });
221 }
222
223
224 NodeCategory
225 ClassifyNode(const Path& pth)
226 {
227 if(pth.empty())
228 return NodeCategory::Empty;
229
230 const auto& fname(pth.back());
231
232 switch(ystdex::classify_path<String, PathTraits>(fname))
233 {
234 case ystdex::path_category::empty:
235 return NodeCategory::Empty;
236 case ystdex::path_category::self:
237 case ystdex::path_category::parent:
238 break;
239 default:
240 return VerifyDirectory(pth) ? NodeCategory::Directory
241 : (ufexists(String(pth).c_str()) ? NodeCategory::Regular
242 : NodeCategory::Missing);
243 // TODO: Implementation for other categories.
244 }
245 return NodeCategory::Unknown;
246 }
247
248 } // namespace IO;
249
250 } // namespace YSLib;
251
YSLib::IO::Path
路径。
Definition: YSLib/Service/FileSystem.h:217
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:112
Path
IO::Path Path
Definition: Initialization.cpp:116
platform::Nonnull
YB_PURE _type && Nonnull(_type &&p) ynothrowv
断言并返回非空参数。
Definition: Debug.h:518
ystdex::path_traits< void >::is_parent
static bool is_parent(const _tString &str)
Definition: path.hpp:91
CHRLib::c
c
Definition: CharacterProcessing.h:84
platform::mode_t
::mode_t mode_t
文件模式类型。
Definition: FileIO.h:116
NPL::A1::OpenFile
YSLib::unique_ptr< std::istream > OpenFile(const char *filename)
Definition: Dependency.cpp:224
cstring.h
ISO C 标准字符串扩展。
ystdex::cpp2017::basic_string_view
Definition: string_view.hpp:95
YSLib::IO::ClearTree
YF_API void ClearTree(const Path &)
清空参数指定路径的目录树内容。
Definition: YSLib/Service/FileSystem.cpp:202
platform::omode_convb
std::ios_base::sync_with_stdio(sync)) YB_ATTR_nodiscard YF_API YB_STATELESS int omode_conv(std YB_ATTR_nodiscard YF_API YB_STATELESS int omode_convb(std::ios_base::openmode) ynothrow
ISO C++ 标准输入输出接口打开模式转换为 POSIX 文件打开模式。
Definition: FileIO.cpp:839
platform::FileDescriptor
文件描述符包装类。
Definition: FileIO.h:149
YSLib::Text::YB_NONNULL
YB_ATTR_nodiscard YB_PURE YB_NONNULL(1, 2) inline PDefH(bool
检查第一参数是否具有指定的 BOM 。
platform::FileDescriptor::WriteContent
static void WriteContent(FileDescriptor, FileDescriptor, size_t=yimpl(size_t(BUFSIZ<< 4)))
Definition: FileIO.cpp:677
platform::EnsureUniqueFile
UniqueFile EnsureUniqueFile(const char *dst, mode_t mode, size_t allowed_links, bool share)
Definition: FileIO.cpp:1249
platform::DirectorySession
目录会话：表示打开的目录。
Definition: YCLib/FileSystem.h:650
ystdex::path_category::empty
@ empty
CHRLib::f
f(d, s)
YModules.h
YSLib 服务模块配置文件。
YSLib::IO::PathTraits::has_root_path
static yconstfn bool has_root_path(const _tString &str) ynothrow
Definition: YSLib/Service/FileSystem.h:114
platform::UniqueFile
unique_ptr_from< FileDescriptor::Deleter > UniqueFile
Definition: FileIO.h:486
ystdex::path_category::self
@ self
YSLib::YAssert
YAssert(!(v< Deref(a)), "Value less than lower bound found.")
YSLib::IO::EnsureDirectory
EnsureDirectory
Definition: YSLib/Service/FileSystem.h:558
YSLib::Drawing::src
src
Definition: YGDI.h:442
YSLib::Text::String
YSLib 标准字符串（使用 UCS-2 作为内部编码）。
Definition: YString.h:47
YSLib::ExtractAndTrace
YF_API void ExtractAndTrace(const std::exception &, RecordLevel=Err) ynothrow
使用 TraceException 展开和跟踪异常类型和信息。
YSLib::IO::MakeNormalizedAbsolute
Path MakeNormalizedAbsolute(const Path &pth, size_t init_size)
Definition: YSLib/Service/FileSystem.cpp:60
YSLib::i
return i
Definition: YCoreUtilities.h:177
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:407
YSLib::IO::VerifyDirectory
bool VerifyDirectory(const char16_t *path)
Definition: YSLib/Service/FileSystem.cpp:100
platform_ex::Windows::Directory
@ Directory
Definition: Win32/include/YCLib/MinGW32.h:466
platform::containers::vector
std::vector< _type, _tAlloc > vector
Definition: Container.h:102
YSLib::path
YB_ATTR_nodiscard YF_API const char * path
Definition: Initialization.h:116
CatchExpr
#define CatchExpr(_ex,...)
指定表达式作为异常处理器。
Definition: YBaseMacro.h:129
YSLib::IO::ListFiles
void ListFiles(const Path &pth, vector< String > &lst)
Definition: YSLib/Service/FileSystem.cpp:214
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:46
exception.h
标准库异常扩展接口。
platform::ufexists
bool ufexists(const char *filename) ynothrowv
Definition: FileIO.cpp:947
platform::umkdir
bool umkdir(const char *path) ynothrowv
Definition: FileIO.cpp:1111
CHRLib::char16_t
YB_ATTR_nodiscard YB_PURE char16_t((*c_ptr<< CHAR_BIT)|c_ptr[1])) YB_ATTR_nodiscard YB_PURE inline PDefH(char16_t
取 c_ptr 指向的小端序双字节字符。
NPL::SXML::ParseOption::String
@ String
YSLib::IO::IsAbsolute
IsAbsolute
Definition: YSLib/Service/FileSystem.h:62
ystdex::to_string_d
_tSeqCon::value_type to_string_d(const path< _tSeqCon, _tTraits > &pth, typename string_traits< typename _tSeqCon::value_type >::value_type delimiter='/')
取以分隔符结束的字符串表示。
Definition: path.hpp:705
YSLib::IO::DeleteTree
DeleteTree
Definition: YSLib/Service/FileSystem.h:845
platform::KeyCodes::Win32::Empty
@ Empty
Definition: Keys.h:282
NPL::c_str
YF_API const char src c_str())) YF_API void InstallDirectory(const string &
安装目录：复制目录树。
Definition: Dependency.h:140
YSLib::IO::CopyFileHandler
function< void(FileDescriptor, FileDescriptor)> CopyFileHandler
复制文件处理器：通知文件复制事件。
Definition: YSLib/Service/FileSystem.h:740
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
platform::bool
YB_ATTR_nodiscard std::FILE *fp bool
Definition: FileIO.h:1271
NPL::dst
YF_API const char src const string const char * dst
Definition: Dependency.h:96
ystdex::path_category::parent
@ parent
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:193
NPL::get
PDefH(void, LiftTermRef, TermNode &term, const TermNode &tm) ImplExpr(NPL ref get()
Definition: NPLA.h:1737
YSLib::IO::ClassifyNode
const Path &pth const string &pth vector< String > &YF_API NodeCategory ClassifyNode(const Path &)
按文件系统节点类别对路径分类。
Definition: YSLib/Service/FileSystem.cpp:225
platform::Descriptions::Debug
@ Debug
Definition: YCommon.h:186