YSTest: FileSystem.cpp 源文件

YSTest PreAlpha_b400_20130424 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
FileSystem.cpp
浏览该文件的文档.
1 ﻿/*
2 Copyright by FrankHB 2012 - 2013.
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 "YCLib/FileSystem.h"
29 #include "YCLib/NativeAPI.h"
30 #include "CHRLib/chrproc.h"
31 #include <cstring> // for std::strcpy, std::strchr;
32 #if YCL_DS
33 # include <fcntl.h>
34
36 extern "C" int _EXFUN(fileno, (FILE *));
37 #elif YCL_MINGW32
38 # include <Shlwapi.h> // for ::PathIsRelativeW;
39
41
42 extern "C"
43 {
44
45 struct _WDIR;
46 struct _wdirent;
47
48 struct _WDIR* __cdecl __MINGW_NOTHROW
49 _wopendir(const wchar_t*);
50 struct _wdirent* __cdecl __MINGW_NOTHROW
51 _wreaddir(_WDIR*);
52 int __cdecl __MINGW_NOTHROW
53 _wclosedir(_WDIR*);
54
55 } // extern "C";
57 #endif
58
59 namespace platform
60 {
61
62 static_assert(std::is_same<CHRLib::ucs2_t, char16_t>::value,
63 "Wrong character type!");
64 static_assert(std::is_same<CHRLib::ucs4_t, char32_t>::value,
65 "Wrong character type!");
66 #if YCL_MINGW32
67 static_assert(sizeof(wchar_t) == sizeof(CHRLib::ucs2_t),
68 "Wrong character type!");
69 static_assert(yalignof(wchar_t) == yalignof(CHRLib::ucs2_t),
70 "Inconsist alignment between character types!");
71 #endif
72
73 namespace
74 {
75
76 #if YCL_DS
77 std::string
78 u16_to_u(const char16_t* u16str)
79 {
80 yconstraint(u16str);
81
82 static char* tstr;
83 std::string str;
84
85 str = std::string(tstr = CHRLib::strdup(u16str));
86 std::free(tstr);
87 return std::move(str);
88 }
89 #elif YCL_MINGW32
90 std::wstring
91 u_to_w(const char* str)
92 {
93 yconstraint(str);
94
95 static CHRLib::ucs2_t* tstr;
96 std::wstring wstr;
97
98 wstr = std::wstring(reinterpret_cast<const wchar_t*>(
99 tstr = CHRLib::ucsdup(str)));
100 std::free(tstr);
101 return std::move(wstr);
102 }
103 #else
104 # error Unsupported platform found!
105 #endif
106
107 } // unnamed namespace;
108
109
110 int
111 uopen(const char* filename, int oflag) ynothrow
112 {
113 yconstraint(filename);
114
115 #if YCL_DS
116 return ::open(filename, oflag);
117 #elif YCL_MINGW32
118 try
119 {
120 return ::_wopen(u_to_w(filename).c_str(), oflag);
121 }
122 catch(...)
123 {}
124 return -1;
125 #else
126 # error Unsupported platform found!
127 #endif
128 }
129 int
130 uopen(const char* filename, int oflag, int pmode) ynothrow
131 {
132 yconstraint(filename);
133
134 #if YCL_DS
135 return ::open(filename, oflag, pmode);
136 #elif YCL_MINGW32
137 try
138 {
139 return ::_wopen(u_to_w(filename).c_str(), oflag, pmode);
140 }
141 catch(...)
142 {}
143 return -1;
144 #else
145 # error Unsupported platform found!
146 #endif
147 }
148 int
149 uopen(const char16_t* filename, int oflag) ynothrow
150 {
151 yconstraint(filename);
152
153 #if YCL_DS
154 try
155 {
156 return ::open(u16_to_u(filename).c_str(), oflag);
157 }
158 catch(...)
159 {}
160 return -1;
161 #elif YCL_MINGW32
162 return ::_wopen(reinterpret_cast<const wchar_t*>(filename), oflag);
163 #else
164 # error Unsupported platform found!
165 #endif
166 }
167 int
168 uopen(const char16_t* filename, int oflag, int pmode) ynothrow
169 {
170 yconstraint(filename);
171
172 #if YCL_DS
173 try
174 {
175 return ::open(u16_to_u(filename).c_str(), oflag, pmode);
176 }
177 catch(...)
178 {}
179 return -1;
180 #elif YCL_MINGW32
181 return ::_wopen(reinterpret_cast<const wchar_t*>(filename), oflag, pmode);
182 #else
183 # error Unsupported platform found!
184 #endif
185 }
186
187 std::FILE*
188 ufopen(const char* filename, const char* mode) ynothrow
189 {
190 yconstraint(filename),
191 yconstraint(mode);
192 yconstraint(*mode != char());
193
194 #if YCL_DS
195 return std::fopen(filename, mode);
196 #elif YCL_MINGW32
197 try
198 {
199 return ::_wfopen(u_to_w(filename).c_str(), u_to_w(mode).c_str());
200 }
201 catch(...)
202 {}
203 return nullptr;
204 #else
205 # error Unsupported platform found!
206 #endif
207 }
208 std::FILE*
209 ufopen(const char16_t* filename, const char16_t* mode) ynothrow
210 {
211 yconstraint(filename),
212 yconstraint(mode);
213 yconstraint(*mode != char());
214
215 #if YCL_DS
216 try
217 {
218 return std::fopen(u16_to_u(filename).c_str(), u16_to_u(mode).c_str());
219 }
220 catch(...)
221 {}
222 return nullptr;
223 #elif YCL_MINGW32
224 return ::_wfopen(reinterpret_cast<const wchar_t*>(filename),
225 reinterpret_cast<const wchar_t*>(mode));
226 #else
227 # error Unsupported platform found!
228 #endif
229 }
230
231 bool
232 ufexists(const char* filename) ynothrow
233 {
234 #if YCL_DS
235 return ystdex::fexists(filename);
236 #elif YCL_MINGW32
237 yconstraint(filename);
238
239 if(const auto file = ufopen(filename, "rb"))
240 {
241 std::fclose(file);
242 return true;
243 }
244 return false;
245 #else
246 # error Unsupported platform found!
247 #endif
248 }
249 bool
250 ufexists(const char16_t* filename) ynothrow
251 {
252 yconstraint(filename);
253
254 if(const auto file = ufopen(filename, u"rb"))
255 {
256 std::fclose(file);
257 return true;
258 }
259 return false;
260 }
261
262 bool
263 direxists(const_path_t path) ynothrow
264 {
265 const auto dir(::opendir(path));
266
267 ::closedir(dir);
268 return dir;
269 }
270
271 bool
272 udirexists(const_path_t path) ynothrow
273 {
274 #if YCL_MINGW32
275 using namespace CHRLib;
276
277 if(path)
278 try
279 {
280 const auto dir(::_wopendir(u_to_w(path).c_str()));
281
282 ::_wclosedir(dir);
283 return dir;
284 }
285 catch(...)
286 {}
287 return false;
288 #else
289 return direxists(path);
290 #endif
291 }
292
293 char*
294 getcwd_n(char* buf, std::size_t size) ynothrow
295 {
296 if(YB_LIKELY(buf))
297 return ::getcwd(buf, size);
298 return nullptr;
299 }
300
301 char16_t*
302 u16getcwd_n(char16_t* buf, std::size_t size) ynothrow
303 {
304 if(size == 0)
305 // last_err = EINVAL;
306 ;
307 else
308 {
309 using namespace std;
310 using namespace CHRLib;
311
312 if(YB_LIKELY(buf))
313 #if YCL_DS
314 {
315 const auto p(static_cast<ucs2_t*>(malloc((size + 1)
316 * sizeof(ucs2_t))));
317
318 if(YB_LIKELY(p))
319 {
320 auto len(MBCSToUCS2(p,
321 ::getcwd(reinterpret_cast<char*>(buf), size)));
322
323 if(size < len + 1)
324 {
325 // last_err = ERANGE;
326 return nullptr;
327 }
328 memcpy(buf, p, ++len * sizeof(ucs2_t));
329 return buf;
330 }
331 // else
332 // last_err = ENOMEM;
333 }
334 #elif YCL_MINGW32
335 return reinterpret_cast< ucs2_t*>(
336 ::_wgetcwd(reinterpret_cast<wchar_t*>(buf), size));
337 #else
338 # error Unsupported platform found!
339 #endif
340 }
341 return nullptr;
342 }
343
344 int
345 uchdir(const_path_t path) ynothrow
346 {
347 #if YCL_DS
348 return ::chdir(path);
349 #elif YCL_MINGW32
350 try
351 {
352 return path ? ::_wchdir(u_to_w(path).c_str()) : -1;
353 }
354 catch(...)
355 {}
356 return -1;
357 #else
358 # error Unsupported platform found!
359 #endif
360 }
361
362 bool
363 mkdirs(const_path_t cpath) ynothrow
364 {
365 PATHSTR path;
366
367 std::strcpy(path, cpath);
368 for(char* slash(path); (slash = strchr(slash, YCL_PATH_DELIMITER));
369 ++slash)
370 {
371 *slash = char();
372 ::mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO);
373 *slash = '/';
374 }
375 //新建目录成功或目标路径已存在时返回 true 。
376 return ::mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) == 0
377 || errno == EEXIST;
378 }
379
380 bool
381 truncate(std::FILE* fp, std::size_t size) ynothrow
382 {
383 #if YCL_DS
384 return ::ftruncate(fileno(fp), ::off_t(size)) != 0;
385 #elif YCL_MINGW32
386 return ::_chsize(_fileno(fp), long(size));
387 #else
388 # error Unsupported platform found!
389 #endif
390 }
391
392
393 int HFileNode::LastError(0);
394
395 HFileNode&
396 HFileNode::operator++() ynothrow
397 {
398 LastError = 0;
399 if(YB_LIKELY(*this))
400 {
401 if(!(p_dirent = ::readdir(dir)))
402 LastError = 2;
403 }
404 else
405 LastError = 1;
406 return *this;
407 }
408
409 bool
410 HFileNode::IsDirectory() const ynothrow
411 {
412 #if YCL_DS || YCL_MINGW32
413 return p_dirent && platform_ex::IsDirectory(*p_dirent);
414 #else
415 # error Unsupported platform found!
416 #endif
417 }
418
419 const char*
420 HFileNode::GetName() const ynothrow
421 {
422 return p_dirent ? p_dirent->d_name : ".";
423 }
424
425 void
426 HFileNode::Open(const_path_t path) ynothrow
427 {
428 dir = path ? ::opendir(path) : nullptr;
429 }
430
431 void
432 HFileNode::Close() ynothrow
433 {
434 LastError = *this ? ::closedir(dir) : 1;
435 dir = nullptr;
436 }
437
438 void
439 HFileNode::Reset() ynothrow
440 {
441 ::rewinddir(dir);
442 }
443
444
445 bool
446 IsAbsolute(const_path_t path)
447 {
448 #if YCL_DS
449 if(path)
450 {
451 if(*path == '/')
452 return true;
453
454 const auto p(std::strstr(path, ":/"));
455
456 return p && p != path && !std::strstr(p, ":/");
457 }
458 return false;
459 #elif YCL_MINGW32
460 return !::PathIsRelativeW(u_to_w(path).c_str());
461 #else
462 # error Unsupported platform found!
463 #endif
464 }
465
466 std::size_t
467 GetRootNameLength(const_path_t path)
468 {
469 const char* p(std::strchr(path, ':'));
470
471 return !p ? 0 : p - path + 1;
472 }
473
474 }
475
476 namespace platform_ex
477 {
478
479 }
480