YSTest  PreAlpha_b400_20130424
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
yfilesys.cpp
浏览该文件的文档.
1 /*
2  Copyright (C) by Franksoft 2010 - 2012.
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/Core/yfilesys.h"
29 #include <ystdex/cstring.h>
30 
31 using namespace ystdex;
32 
34 
35 using namespace Text;
36 
38 
39 const Path Path::Now(FS_Now_X);
40 const Path Path::Parent(FS_Parent_X);
41 
42 
43 Path::iterator&
44 Path::iterator::operator++()
45 {
46  n = n == StringType::npos ? 0
47  : ptr->find_first_not_of(Slash, ptr->find(Slash, n));
48  return *this;
49 }
50 
52 Path::iterator::operator--()
53 {
54  n = n == 0 ? StringType::npos
55  : ptr->rfind(Slash, ptr->find_last_not_of(Slash, n)) + 1;
56  return *this;
57 }
58 
59 Path::iterator::value_type
61 {
62  if(n == StringType::npos)
63  return Path(FS_Now);
64 
65  StringType::size_type p(ptr->find(Slash, n));
66 
67  return ptr->substr(n, p == StringType::npos ? StringType::npos : p - n);
68 }
69 
70 
71 Path&
72 Path::operator/=(const Path& path)
73 {
74  if(path.IsRelative() && path != Now)
75  for(const_iterator i(path.begin()); i != path.end(); ++i)
76  {
77  if(*i == FS_Parent)
78  {
79  erase((--end()).GetPosition());
80  if(empty())
81  *this = GetRootPath();
82  }
83  else
84  {
85  *this += *i;
86  if(IsDirectory())
87  *this += Slash;
88  else
89  break;
90  }
91  }
92  return *this;
93 }
94 
95 bool
97 {
98  return udirexists(GetNativeString().c_str());
99 }
100 
101 //路径分解。
102 Path
103 Path::GetRootName() const
104 {
105  return Path(StringType(c_str(),
106  GetRootNameLength(GetNativeString().c_str())));
107 }
108 Path
109 Path::GetRootDirectory() const
110 {
111  return Path(FS_Seperator);
112 }
113 Path
114 Path::GetRootPath() const
115 {
116  return GetRootName() / GetRootDirectory();
117 }
118 Path
119 Path::GetRelativePath() const
120 {
121  return empty() ? Path() : *begin();
122 }
123 Path
124 Path::GetParentPath() const
125 {
126  return substr(0, (--end()).GetPosition());
127 }
128 Path
129 Path::GetFilename() const
130 {
131  return empty() ? Path() : *--end();
132 }
133 Path
134 Path::GetStem() const
135 {
136  return Path();
137 }
138 Path
139 Path::GetExtension() const
140 {
141  return Path();
142 }
143 
144 Path&
145 Path::MakeAbsolute(const Path&)
146 {
147  // TODO: Implementation.
148  return *this;
149 }
150 
151 bool
152 Path::NormalizeTrailingSlash()
153 {
154  if(YB_UNLIKELY(empty()))
155  return false;
156 
157  const bool has_trailing_slash(back() == Slash);
158 
159  if(has_trailing_slash && size() == 1)
160  return false;
161  if(IsDirectory())
162  {
163  if(has_trailing_slash)
164  return false;
165  push_back(Slash);
166  }
167  else
168  {
169  if(!has_trailing_slash)
170  return false;
171  pop_back();
172  }
173  return true;
174 }
175 
176 Path&
177 Path::RemoveFilename()
178 {
179  // TODO: Implementation;
180  return *this;
181 }
182 
183 Path&
184 Path::ReplaceExtension(const Path& new_extension)
185 {
186 // RemoveExtension();
187  *this += new_extension;
188  return *this;
189 }
190 
191 
192 const char*
194 {
195  if(!path)
196  return nullptr;
197 
198  const char* p(strrchr(path, YCL_PATH_DELIMITER));
199 
200  return p ? (*++p ? p : nullptr) : path;
201 }
202 string
203 GetFileNameOf(const string& path)
204 {
205  const string::size_type p(path.rfind(YCL_PATH_DELIMITER));
206 
207  return p == string::npos ? string(path) : path.substr(p + 1);
208 }
209 
210 string
211 GetDirectoryNameOf(const string& path)
212 {
213  const string::size_type p(path.rfind(YCL_PATH_DELIMITER));
214 
215  return p == string::npos ? string() : path.substr(0, p + 1);
216 }
217 
218 string::size_type
219 SplitPath(const string& path, string& directory, string& file)
220 {
221  const string::size_type p(path.rfind(YCL_PATH_DELIMITER));
222 
223  if(p == string::npos)
224  yunseq((directory = "", file = path));
225  else
226  yunseq((directory = path.substr(0, p + 1),
227  file = path.substr(p + 1)));
228  return p;
229 }
230 
231 string
232 GetStemOf(const string& name)
233 {
234  const string::size_type p(name.rfind('.'));
235 
236  return p == string::npos ? string(name) : name.substr(0, p);
237 }
238 
239 bool
240 IsStemOf(const char* str, const char* name)
241 {
242  size_t t(strlen_n(str));
243 
244  if(t > strlen_n(name))
245  return false;
246  return !strncmp(str, name, strlen_n(str));
247 }
248 bool
249 IsStemOf(const string& str, const string& name)
250 {
251  if(str.length() > name.length())
252  return false;
253  return !name.compare(0, str.length(), str);
254 }
255 
256 bool
257 HaveSameStems(const char* a, const char* b)
258 {
259  const char *pea(GetExtensionOf(a)), *peb(GetExtensionOf(b));
260 
261  if(pea - a != peb - b)
262  return false;
263  while(a < pea)
264  {
265  if(*a != *b)
266  return false;
267  yunseq(++a, ++b);
268  }
269  return true;
270 }
271 bool
272 HaveSameStems(const string& a, const string& b)
273 {
274  return GetStemOf(a) == GetStemOf(b);
275 }
276 
277 const char*
278 GetExtensionOf(const char* name)
279 {
280  if(!name)
281  return nullptr;
282 
283  const char* p(strrchr(name, '.'));
284 
285  return p && *++p ? p : nullptr;
286 }
287 string
288 GetExtensionOf(const string& name)
289 {
290  const string::size_type p(name.rfind('.'));
291 
292  return p == string::npos ? string() : name.substr(p + 1);
293 }
294 
295 bool
296 IsExtensionOf(const char* str, const char* name)
297 {
298  const char* p(GetExtensionOf(name));
299 
300  if(!p)
301  return false;
302  // TODO: Implementation for non-case-sensitive file names.
303  return !strcmp(str, p);
304 }
305 bool
306 IsExtensionOf(const string& str, const string& name)
307 {
308  if(str.length() > name.length())
309  return false;
310  return GetExtensionOf(name) == str;
311 }
312 
313 bool
314 HaveSameExtensions(const char* a, const char* b)
315 {
316  if(!(a && b))
317  return false;
318 
319  const char *pa(GetExtensionOf(a)), *pb(GetExtensionOf(b));
320 
321  if(!(pa && pb))
322  return false;
323  // TODO: Implementation for non-case-sensitive file names.
324  return std::strcmp(pa, pb) != 0;
325 }
326 bool
327 HaveSameExtensions(const string& a, const string& b)
328 {
329  string ea(GetExtensionOf(a)), eb(GetExtensionOf(b));
330 
331  // TODO: for non-case-sensitive file names;
332  return std::strcmp(ea.c_str(), eb.c_str()) != 0;
333 // return ucsicmp(ea.c_str(), eb.c_str());
334 }
335 
336 int
337 ChangeDirectory(const string& path)
338 {
339  if(YB_UNLIKELY(path.length() > YCL_MAX_PATH_LENGTH))
340  return -2;
341 
342  return ChangeDirectory(path.c_str());
343 }
344 #if 0
345 // for String;
346 int
347 ChangeDirectory(const Path& path)
348 {
349  if(YB_UNLIKELY(path.length() > YCL_MAX_PATH_LENGTH))
350  return -2;
351 
352  PATHSTR p;
353 
354  UCS2ToMBCS(p, path.c_str());
355  return ChangeDirectory(p);
356 }
357 #endif
358 
359 String
361 {
363 
364  return u16getcwd_n(buf, YCL_MAX_PATH_LENGTH - 1)
365  ? String(buf) : String();
366 }
367 
368 bool
369 ValidatePath(const string& pathstr)
370 {
371  return bool(HFileNode(pathstr.c_str()));
372 }
373 
374 
375 FileList::FileList(const_path_t path)
376  : Directory((path && *path) ? path : FS_Root), hList(new ListType())
377 {}
378 FileList::FileList(const string& path)
379  : Directory(path.empty() ? FS_Root : path.c_str()), hList(new ListType())
380 {}
381 FileList::FileList(const FileList::ItemType& path)
382  : Directory(path.empty() ? FS_Root : path.GetMBCS(CP_Path).c_str()),
383  hList(new ListType())
384 {}
385 
386 bool
387 FileList::operator=(const Path& d)
388 {
389  if(d.IsDirectory())
390  {
391  (Directory = d).NormalizeTrailingSlash();
392  ListItems();
393  return true;
394  }
395  return false;
396 }
397 bool
398 FileList::operator/=(const Path& d)
399 {
400  return *this = (Directory / d);
401 }
402 
403 
404 FileList::ListType::size_type
405 FileList::ListItems()
406 {
407  HFileNode dir(Directory.GetNativeString().c_str());
408  u32 n(0);
409 
410  if(dir)
411  {
412  YAssert(bool(hList), "Null handle found.");
413 
414  hList->clear();
415  while((++dir).LastError == 0)
416  if(YB_LIKELY(std::strcmp(dir.GetName(), FS_Now) != 0))
417  ++n;
418  hList->reserve(n);
419  dir.Reset();
420  while((++dir).LastError == 0)
421  if(YB_LIKELY(std::strcmp(dir.GetName(), FS_Now) != 0))
422  hList->push_back(std::strcmp(dir.GetName(), FS_Parent)
423  && dir.IsDirectory() ? String(
424  string(dir.GetName()) + FS_Seperator, CP_Path)
425  : String(dir.GetName(), CP_Path));
426  // TODO: Platform-dependent name converting.
427  }
428  return n;
429 }
430 
432 
433 YSL_END
434