YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
YSLib/Service/FileSystem.cpp
浏览该文件的文档.
1 /*
2  © 2010-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 #include "YSLib/Service/YModules.h"
29 #include YFM_YSLib_Service_FileSystem
30 #include <ystdex/cstring.h>
31 #include <system_error>
32 
33 namespace YSLib
34 {
35 
36 using namespace Text;
37 
38 namespace IO
39 {
40 
41 Path&
42 Path::operator/=(const String& fname)
43 {
44  auto& norm(get_norm());
45 
46  if(norm.is_parent(fname))
47  {
48  if((is_absolute() ? 1 : 0) < size())
49  pop_back();
50  }
51  else if(!norm.is_self(fname))
52  push_back(fname);
53  return *this;
54 }
55 Path&
56 Path::operator/=(const Path& pth)
57 {
58  for(const auto& fname : pth)
59  *this /= fname;
60  return *this;
61 }
62 
63 Path::operator String() const
64 {
65  auto res(GetString());
66 
67  if(!(res.empty() || VerifyDirectory(res)))
68  res.pop_back();
69  return res;
70 }
71 
72 String
73 Path::GetString() const
74 {
75  const auto res(ystdex::to_string_d(static_cast<const ypath&>(*this),
76  YCL_PATH_DELIMITER));
77 
78  YAssert(res.empty() || res.back() == YCL_PATH_DELIMITER,
79  "Invalid conversion result found.");
80  return res;
81 }
82 
83 ypath
84 Path::Parse(const ucs2string& str)
85 {
86  ypath res;
87  auto& norm(res.get_norm());
88 
89  ystdex::split(str, [&](ucs2_t c){
90  return norm.is_delimiter(ucs2string{c});
91  }, [&](ucs2string::const_iterator b, ucs2string::const_iterator e){
92  res.push_back(ucs2string(b, e));
93  });
94  return res;
95 }
96 
97 
98 String
99 GetExtensionOf(const String& fname)
100 {
101  if(!fname.empty())
102  {
103  const auto pos(fname.rfind('.'));
104 
105  if(pos != String::npos)
106  return fname.substr(pos + 1);
107  }
108  return {};
109 }
110 
111 
112 String
114 {
115  ucs2string str(len, ucs2_t());
116 
117  u16getcwd_n(&str[0], len);
118  return str;
119 }
120 
121 
122 bool
123 VerifyDirectory(const char* path)
124 {
125  try
126  {
127  DirectorySession ss(path);
128 
129  return true;
130  }
131  catch(FileOperationFailure&)
132  {}
133  return false;
134 }
135 
136 
137 void
139 {
140  string upath;
141 
142  for(const auto& name : pth)
143  {
144  upath += strdup(name.c_str(), CS_Path) + YCL_PATH_DELIMITER;
145  if(!umkdir(upath.c_str()) && errno != EEXIST)
146  throw std::system_error(errno, std::system_category());
147  }
148  YAssert(VerifyDirectory(pth), "Directory verification failed.");
149 }
150 
151 
152 void
153 ListFiles(const Path& pth, vector<String>& lst)
154 {
155  try
156  {
157  HDirectory dir(string(pth).c_str());
158  PathNorm nm;
159 
160  std::for_each(FileIterator(&dir), FileIterator(),
161  [&](const std::string& name){
162  if(YB_LIKELY(!nm.is_self(name)))
163  lst.push_back(String(!nm.is_parent(name)
164  && dir.GetNodeCategory() == NodeCategory::Directory
165  ? name + YCL_PATH_DELIMITER : name, CS_Path));
166  });
167  }
168  catch(FileOperationFailure&)
169  {}
170 }
171 
172 
174 ClassifyPath(const String& fname, ypath::norm&& norm)
175 {
176  if(YB_UNLIKELY(fname.empty()))
177  return PathCategory::Empty;
178  if(norm.is_self(fname))
179  return PathCategory::Self;
180  if(norm.is_parent(fname))
181  return PathCategory::Parent;
182  return PathCategory::Node;
183 }
184 
186 ClassifyNode(const Path& pth)
187 {
188  if(pth.empty())
189  return NodeCategory::Empty;
190 
191  const auto& fname(pth.back());
192 
193  switch(ClassifyPath(fname, std::move(pth.get_norm())))
194  {
195  case PathCategory::Empty:
196  return NodeCategory::Empty;
197  case PathCategory::Self:
198  case PathCategory::Parent:
199  break;
200  default:
201  if(ufexists(string(pth)))
202  return VerifyDirectory(pth)
203  ? NodeCategory::Directory : NodeCategory::Regular;
204  else
205  return NodeCategory::Missing;
206  // TODO: Implementation for other categories.
207  }
208  return NodeCategory::Unknown;
209 }
210 
211 } // namespace IO;
212 
213 } // namespace YSLib;
214 
char16_t * u16getcwd_n(char16_t *buf, std::size_t size) ynothrow
PathCategory
路径类别。
YF_API std::string strdup(const ucs2_t *, Encoding=CS_Default)
复制 UCS-2 字符串为多字节字符串。
Definition: chrproc.cpp:162
ISO C 标准字符串扩展。
void ListFiles(const Path &pth, vector< String > &lst)
一般路径模板。
Definition: path.hpp:149
YF_API bool ufexists(const char *) ynothrow
判断指定 UTF-8 文件名的文件是否存在。
bool VerifyDirectory(const char *path)
PathCategory ClassifyPath(const String &fname, ypath::norm &&norm)
void split(_tIn b, _tIn e, _fPred is_delim, _fInsert insert)
以指定字符分割字符序列。
Definition: string.hpp:279
String FetchCurrentWorkingDirectory(size_t len)
GSStringTemplate< CHRLib::ucs2_t >::basic_string ucs2string
Definition: ycont.h:167
目录句柄:表示打开的目录和内容迭代状态。
String GetExtensionOf(const String &fname)
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
YSLib 标准字符串(使用 UCS-2 作为内部编码)。
Definition: ystring.h:47
文件路径范式。
yconstfn const string & name
Definition: Loader.h:110
GSStringTemplate< char >::basic_string string
Definition: ycont.h:164
void EnsureDirectory(const Path &pth)
目录会话:表示打开的目录。
NodeCategory GetNodeCategory() const ynothrow
取节点状态信息确定的文件系统节点类别。
ystdex::indirect_input_iterator< HDirectory * > FileIterator
文件迭代器。
YF_API bool umkdir(const char *) ynothrow
按 UTF-8 路径以默认权限新建一个目录。
virtual bool is_self(const value_type &)=0
Path & operator/=(const Path &)
char16_t ucs2_t
UCS-2 字符类型。
Definition: chrdef.h:44
virtual bool is_parent(const value_type &)=0
_tNorm norm
Definition: path.hpp:156
表示文件操作失败的异常。
norm & get_norm() const
Definition: path.hpp:298
#define YB_LIKELY(expr)
Definition: ydef.h:297
NodeCategory
文件系统节点类别。
#define YAssert(_expr, _msg)
Definition: cassert.h:73
YF_API NodeCategory ClassifyNode(const Path &)
按文件系统节点类别对路径分类。