filesystem to experimental to avoid conflicts with fs_utillity

This commit is contained in:
qPCR4vir 2015-05-22 23:21:01 +02:00
parent 59f0ace353
commit f55c54f7b4
2 changed files with 366 additions and 363 deletions

View File

@ -46,7 +46,7 @@
// namespace std { namespace experimental { namespace filesystem { inline namespace v1 { // namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
namespace nana namespace nana { namespace experimental
{ {
namespace filesystem namespace filesystem
{ {
@ -73,7 +73,7 @@ namespace filesystem
//enum class directory_options; //enum class directory_options;
// class filesystem_error; // class filesystem_error;
enum class error { none = 0 }; enum class error { none = 0 }; // deprecate ??
struct attribute // deprecate ?? struct attribute // deprecate ??
{ {
@ -449,6 +449,7 @@ namespace filesystem
}//end namespace filesystem }//end namespace filesystem
} //end namespace experimental
}//end namespace nana }//end namespace nana
#endif #endif

View File

@ -36,11 +36,12 @@
#include <stdlib.h> #include <stdlib.h>
#endif #endif
namespace nana namespace nana {
{ namespace experimental
namespace filesystem {
{ namespace filesystem
//Because of No wide character version of POSIX {
//Because of No wide character version of POSIX
#if defined(NANA_LINUX) #if defined(NANA_LINUX)
typedef std::string string_t; typedef std::string string_t;
const char* splstr = "/\\"; const char* splstr = "/\\";
@ -49,18 +50,18 @@ namespace filesystem
const nana::char_t* splstr = STR("/\\"); const nana::char_t* splstr = STR("/\\");
#endif #endif
//class path //class path
path::path(){} path::path() {}
path::path(const nana::string& text) path::path(const nana::string& text)
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
:text_(text) : text_(text)
{ {
#else #else
:text_(nana::charset(text)) :text_(nana::charset(text))
{ {
#endif #endif
auto pos = text_.find_last_of(splstr); auto pos = text_.find_last_of(splstr);
for(; (pos != string_t::npos) && (pos + 1 == text_.size()); pos = text_.find_last_of(splstr)) for (; (pos != string_t::npos) && (pos + 1 == text_.size()); pos = text_.find_last_of(splstr))
text_.erase(pos); text_.erase(pos);
} }
@ -76,33 +77,33 @@ namespace filesystem
path path::root() const path path::root() const
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
return path(filesystem::root(text_)); return path(filesystem::root(text_));
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
return path(filesystem::root(nana::charset(text_))); return path(filesystem::root(nana::charset(text_)));
#endif #endif
} }
file_type path::what() const file_type path::what() const
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
unsigned long attr = ::GetFileAttributes(text_.c_str()); unsigned long attr = ::GetFileAttributes(text_.c_str());
if(INVALID_FILE_ATTRIBUTES == attr) if (INVALID_FILE_ATTRIBUTES == attr)
return file_type:: not_found ; //?? return file_type::not_found; //??
if(FILE_ATTRIBUTE_DIRECTORY & attr) if (FILE_ATTRIBUTE_DIRECTORY & attr)
return file_type::directory; return file_type::directory;
return file_type::regular; return file_type::regular;
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
struct stat sta; struct stat sta;
if(-1 == ::stat(text_.c_str(), &sta)) if (-1 == ::stat(text_.c_str(), &sta))
return file_type:: not_found ; //?? return file_type::not_found; //??
if((S_IFDIR & sta.st_mode) == S_IFDIR) if ((S_IFDIR & sta.st_mode) == S_IFDIR)
return file_type::directory; return file_type::directory;
if((S_IFREG & sta.st_mode) == S_IFREG) if ((S_IFREG & sta.st_mode) == S_IFREG)
return file_type::regular; return file_type::regular;
return file_type::none; return file_type::none;
@ -132,9 +133,9 @@ namespace filesystem
std::copy(directory_iterator(dir), directory_iterator(), std::back_inserter(files)); std::copy(directory_iterator(dir), directory_iterator(), std::back_inserter(files));
for(auto & f : files) for (auto & f : files)
{ {
if(f.attr.directory) if (f.attr.directory)
rm_dir_recursive(path + f.path().name()); rm_dir_recursive(path + f.path().name());
else else
rmfile((path + f.path().name()).c_str()); rmfile((path + f.path().name()).c_str());
@ -146,7 +147,7 @@ namespace filesystem
bool mkdir_helper(const nana::string& dir, bool & if_exist) bool mkdir_helper(const nana::string& dir, bool & if_exist)
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
if(::CreateDirectory(dir.c_str(), 0)) if (::CreateDirectory(dir.c_str(), 0))
{ {
if_exist = false; if_exist = false;
return true; return true;
@ -154,7 +155,7 @@ namespace filesystem
if_exist = (::GetLastError() == ERROR_ALREADY_EXISTS); if_exist = (::GetLastError() == ERROR_ALREADY_EXISTS);
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
if(0 == ::mkdir(static_cast<std::string>(nana::charset(dir)).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) if (0 == ::mkdir(static_cast<std::string>(nana::charset(dir)).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
{ {
if_exist = false; if_exist = false;
return true; return true;
@ -169,7 +170,7 @@ namespace filesystem
void filetime_to_c_tm(FILETIME& ft, struct tm& t) void filetime_to_c_tm(FILETIME& ft, struct tm& t)
{ {
FILETIME local_file_time; FILETIME local_file_time;
if(::FileTimeToLocalFileTime(&ft, &local_file_time)) if (::FileTimeToLocalFileTime(&ft, &local_file_time))
{ {
SYSTEMTIME st; SYSTEMTIME st;
::FileTimeToSystemTime(&local_file_time, &st); ::FileTimeToSystemTime(&local_file_time, &st);
@ -191,7 +192,7 @@ namespace filesystem
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
WIN32_FILE_ATTRIBUTE_DATA fad; WIN32_FILE_ATTRIBUTE_DATA fad;
if(::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &fad)) if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &fad))
{ {
LARGE_INTEGER li; LARGE_INTEGER li;
li.u.LowPart = fad.nFileSizeLow; li.u.LowPart = fad.nFileSizeLow;
@ -203,7 +204,7 @@ namespace filesystem
} }
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
struct stat fst; struct stat fst;
if(0 == ::stat(static_cast<std::string>(nana::charset(file)).c_str(), &fst)) if (0 == ::stat(static_cast<std::string>(nana::charset(file)).c_str(), &fst))
{ {
attr.bytes = fst.st_size; attr.bytes = fst.st_size;
attr.is_directory = (0 != (040000 & fst.st_mode)); attr.is_directory = (0 != (040000 & fst.st_mode));
@ -218,15 +219,15 @@ namespace filesystem
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
//Some compilation environment may fail to link to GetFileSizeEx //Some compilation environment may fail to link to GetFileSizeEx
typedef BOOL (__stdcall *GetFileSizeEx_fptr_t)(HANDLE, PLARGE_INTEGER); typedef BOOL(__stdcall *GetFileSizeEx_fptr_t)(HANDLE, PLARGE_INTEGER);
GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast<GetFileSizeEx_fptr_t>(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx")); GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast<GetFileSizeEx_fptr_t>(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx"));
if(get_file_size_ex) if (get_file_size_ex)
{ {
HANDLE handle = ::CreateFile(file.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); HANDLE handle = ::CreateFile(file.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(INVALID_HANDLE_VALUE != handle) if (INVALID_HANDLE_VALUE != handle)
{ {
LARGE_INTEGER li; LARGE_INTEGER li;
if(!get_file_size_ex(handle, &li)) if (!get_file_size_ex(handle, &li))
li.QuadPart = 0; li.QuadPart = 0;
::CloseHandle(handle); ::CloseHandle(handle);
@ -237,7 +238,7 @@ namespace filesystem
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
FILE * stream = ::fopen(static_cast<std::string>(nana::charset(file)).c_str(), "rb"); FILE * stream = ::fopen(static_cast<std::string>(nana::charset(file)).c_str(), "rb");
long long size = 0; long long size = 0;
if(stream) if (stream)
{ {
fseeko64(stream, 0, SEEK_END); fseeko64(stream, 0, SEEK_END);
size = ftello64(stream); size = ftello64(stream);
@ -251,10 +252,10 @@ namespace filesystem
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
WIN32_FILE_ATTRIBUTE_DATA attr; WIN32_FILE_ATTRIBUTE_DATA attr;
if(::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &attr)) if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &attr))
{ {
FILETIME local_file_time; FILETIME local_file_time;
if(::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time)) if (::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time))
{ {
SYSTEMTIME st; SYSTEMTIME st;
::FileTimeToSystemTime(&local_file_time, &st); ::FileTimeToSystemTime(&local_file_time, &st);
@ -272,7 +273,7 @@ namespace filesystem
} }
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
struct stat attr; struct stat attr;
if(0 == ::stat(static_cast<std::string>(nana::charset(file)).c_str(), &attr)) if (0 == ::stat(static_cast<std::string>(nana::charset(file)).c_str(), &attr))
{ {
t = *(::localtime(&attr.st_ctime)); t = *(::localtime(&attr.st_ctime));
return true; return true;
@ -284,32 +285,32 @@ namespace filesystem
bool create_directory(const nana::string& path, bool & if_exist) bool create_directory(const nana::string& path, bool & if_exist)
{ {
if_exist = false; if_exist = false;
if(path.size() == 0) return false; if (path.size() == 0) return false;
nana::string root; nana::string root;
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
if(path.size() > 3 && path[1] == STR(':')) if (path.size() > 3 && path[1] == STR(':'))
root = path.substr(0, 3); root = path.substr(0, 3);
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
if(path[0] == STR('/')) if (path[0] == STR('/'))
root = '/'; root = '/';
#endif #endif
bool mkstat = false; bool mkstat = false;
std::size_t beg = root.size(); std::size_t beg = root.size();
while(true) while (true)
{ {
beg = path.find_first_not_of(STR("/\\"), beg); beg = path.find_first_not_of(STR("/\\"), beg);
if(beg == path.npos) if (beg == path.npos)
break; break;
std::size_t pos = path.find_first_of(STR("/\\"), beg + 1); std::size_t pos = path.find_first_of(STR("/\\"), beg + 1);
if(pos != path.npos) if (pos != path.npos)
{ {
root += path.substr(beg, pos - beg); root += path.substr(beg, pos - beg);
mkstat = detail::mkdir_helper(root, if_exist); mkstat = detail::mkdir_helper(root, if_exist);
if(mkstat == false && if_exist == false) if (mkstat == false && if_exist == false)
return false; return false;
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
@ -320,7 +321,7 @@ namespace filesystem
} }
else else
{ {
if(beg + 1 < path.size()) if (beg + 1 < path.size())
{ {
root += path.substr(beg); root += path.substr(beg);
mkstat = detail::mkdir_helper(root, if_exist); mkstat = detail::mkdir_helper(root, if_exist);
@ -336,16 +337,16 @@ namespace filesystem
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
bool ret = false; bool ret = false;
if(file) if (file)
{ {
ret = (::DeleteFile(file) == TRUE); ret = (::DeleteFile(file) == TRUE);
if(!ret) if (!ret)
ret = (ERROR_FILE_NOT_FOUND == ::GetLastError()); ret = (ERROR_FILE_NOT_FOUND == ::GetLastError());
} }
return ret; return ret;
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
if(std::remove(static_cast<std::string>(nana::charset(file)).c_str())) if (std::remove(static_cast<std::string>(nana::charset(file)).c_str()))
return (errno == ENOENT); return (errno == ENOENT);
return true; return true;
#endif #endif
@ -354,17 +355,17 @@ namespace filesystem
bool rmdir(const nana::char_t* dir, bool fails_if_not_empty) bool rmdir(const nana::char_t* dir, bool fails_if_not_empty)
{ {
bool ret = false; bool ret = false;
if(dir) if (dir)
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
ret = (::RemoveDirectory(dir) == TRUE); ret = (::RemoveDirectory(dir) == TRUE);
if(!fails_if_not_empty && (::GetLastError() == ERROR_DIR_NOT_EMPTY)) if (!fails_if_not_empty && (::GetLastError() == ERROR_DIR_NOT_EMPTY))
ret = detail::rm_dir_recursive(dir); ret = detail::rm_dir_recursive(dir);
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
std::string mbstr = nana::charset(dir); std::string mbstr = nana::charset(dir);
if(::rmdir(mbstr.c_str())) if (::rmdir(mbstr.c_str()))
{ {
if(!fails_if_not_empty && (errno == EEXIST || errno == ENOTEMPTY)) if (!fails_if_not_empty && (errno == EEXIST || errno == ENOTEMPTY))
ret = detail::rm_dir_recursive(dir); ret = detail::rm_dir_recursive(dir);
} }
else else
@ -378,37 +379,37 @@ namespace filesystem
{ {
std::size_t index = path.size(); std::size_t index = path.size();
if(index) if (index)
{ {
const nana::char_t * str = path.c_str(); const nana::char_t * str = path.c_str();
for(--index; index > 0; --index) for (--index; index > 0; --index)
{ {
nana::char_t c = str[index]; nana::char_t c = str[index];
if(c != '\\' && c != '/') if (c != '\\' && c != '/')
break; break;
} }
for(--index; index > 0; --index) for (--index; index > 0; --index)
{ {
nana::char_t c = str[index]; nana::char_t c = str[index];
if(c == '\\' || c == '/') if (c == '\\' || c == '/')
break; break;
} }
} }
return index?path.substr(0, index + 1):nana::string(); return index ? path.substr(0, index + 1) : nana::string();
} }
nana::string path_user() nana::string path_user()
{ {
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
nana::char_t path[MAX_PATH]; nana::char_t path[MAX_PATH];
if(SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, path))) if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, path)))
return path; return path;
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
const char * s = ::getenv("HOME"); const char * s = ::getenv("HOME");
if(s) if (s)
return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8); return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8);
#endif #endif
return nana::string(); return nana::string();
@ -419,24 +420,25 @@ namespace filesystem
#if defined(NANA_WINDOWS) #if defined(NANA_WINDOWS)
nana::char_t buf[MAX_PATH]; nana::char_t buf[MAX_PATH];
DWORD len = ::GetCurrentDirectory(MAX_PATH, buf); DWORD len = ::GetCurrentDirectory(MAX_PATH, buf);
if(len) if (len)
{ {
if(len > MAX_PATH) if (len > MAX_PATH)
{ {
nana::char_t * p = new nana::char_t[len + 1]; nana::char_t * p = new nana::char_t[len + 1];
::GetCurrentDirectory(len + 1, p); ::GetCurrentDirectory(len + 1, p);
nana::string s = p; nana::string s = p;
delete [] p; delete[] p;
return s; return s;
} }
return buf; return buf;
} }
#elif defined(NANA_LINUX) #elif defined(NANA_LINUX)
const char * s = ::getenv("PWD"); const char * s = ::getenv("PWD");
if(s) if (s)
return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8); return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8);
#endif #endif
return nana::string(); return nana::string();
} }
}//end namespace filesystem }//end namespace filesystem
} //end namespace experimental
}//end namespace nana }//end namespace nana