update experimental::filesystem and remove file_iterator

This commit is contained in:
Jinhao
2016-01-19 01:34:07 +08:00
parent 13669f7591
commit 8d2ec2fbd1
22 changed files with 1255 additions and 788 deletions

View File

@@ -51,7 +51,7 @@
<Unit filename="../../source/deploy.cpp" />
<Unit filename="../../source/detail/platform_spec_posix.cpp" />
<Unit filename="../../source/detail/platform_spec_windows.cpp" />
<Unit filename="../../source/filesystem/file_iterator.cpp" />
<Unit filename="../../source/filesystem/filesystem.cpp" />
<Unit filename="../../source/filesystem/fs_utility.cpp" />
<Unit filename="../../source/gui/animation.cpp" />
<Unit filename="../../source/gui/basis.cpp" />

File diff suppressed because it is too large Load Diff

View File

@@ -189,7 +189,6 @@
<ClCompile Include="..\..\source\deploy.cpp" />
<ClCompile Include="..\..\source\detail\platform_spec_windows.cpp" />
<ClCompile Include="..\..\source\filesystem\filesystem.cpp" />
<ClCompile Include="..\..\source\filesystem\file_iterator.cpp" />
<ClCompile Include="..\..\source\filesystem\fs_utility.cpp" />
<ClCompile Include="..\..\source\gui\animation.cpp" />
<ClCompile Include="..\..\source\gui\basis.cpp" />
@@ -275,7 +274,6 @@
<ClInclude Include="..\..\include\nana\detail\linux_X11\platform_spec.hpp" />
<ClInclude Include="..\..\include\nana\detail\win32\platform_spec.hpp" />
<ClInclude Include="..\..\include\nana\filesystem\filesystem.hpp" />
<ClInclude Include="..\..\include\nana\filesystem\file_iterator.hpp" />
<ClInclude Include="..\..\include\nana\filesystem\fs_utility.hpp" />
<ClInclude Include="..\..\include\nana\fwd.hpp" />
<ClInclude Include="..\..\include\nana\gui.hpp" />

View File

@@ -111,9 +111,6 @@
<ClCompile Include="..\..\source\filesystem\filesystem.cpp">
<Filter>Source Files\nana\filesystem</Filter>
</ClCompile>
<ClCompile Include="..\..\source\filesystem\file_iterator.cpp">
<Filter>Source Files\nana\filesystem</Filter>
</ClCompile>
<ClCompile Include="..\..\source\filesystem\fs_utility.cpp">
<Filter>Source Files\nana\filesystem</Filter>
</ClCompile>
@@ -616,9 +613,6 @@
<ClInclude Include="..\..\include\nana\filesystem\filesystem.hpp">
<Filter>Header Files\filesystem</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\filesystem\file_iterator.hpp">
<Filter>Header Files\filesystem</Filter>
</ClInclude>
<ClInclude Include="..\..\include\nana\filesystem\fs_utility.hpp">
<Filter>Header Files\filesystem</Filter>
</ClInclude>

View File

@@ -183,7 +183,6 @@
<ClCompile Include="..\..\source\deploy.cpp" />
<ClCompile Include="..\..\source\detail\platform_spec_windows.cpp" />
<ClCompile Include="..\..\source\filesystem\filesystem.cpp" />
<ClCompile Include="..\..\source\filesystem\file_iterator.cpp" />
<ClCompile Include="..\..\source\filesystem\fs_utility.cpp" />
<ClCompile Include="..\..\source\gui\animation.cpp" />
<ClCompile Include="..\..\source\gui\basis.cpp" />

View File

@@ -84,9 +84,6 @@
<ClCompile Include="..\..\source\audio\player.cpp">
<Filter>Source Files\audio</Filter>
</ClCompile>
<ClCompile Include="..\..\source\filesystem\file_iterator.cpp">
<Filter>Source Files\filesystem</Filter>
</ClCompile>
<ClCompile Include="..\..\source\filesystem\filesystem.cpp">
<Filter>Source Files\filesystem</Filter>
</ClCompile>

View File

@@ -1,7 +1,7 @@
/**
* Nana Configuration
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -137,10 +137,10 @@
#if !defined( USE_github_com_meganz_mingw_std_threads )
//#define USE_github_com_meganz_mingw_std_threads
#endif
#if !defined(STD_make_unique_NOT_SUPPORTED)
#define STD_make_unique_NOT_SUPPORTED
#endif //STD_make_unique_NOT_SUPPORTED
#endif
#if (__GNUC_MINOR__ < 9)
#define STD_MAKE_UNIQUE_NOT_SUPPORTED
#endif
#if defined(NANA_MINGW)

View File

@@ -1,7 +1,7 @@
/*
* The Deploy Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -154,7 +154,7 @@ namespace nana
#define NANA_RGB(a) (((DWORD)(a) & 0xFF)<<16) | ((DWORD)(a) & 0xFF00) | (((DWORD)(a) & 0xFF0000) >> 16 )
#if defined(STD_make_unique_NOT_SUPPORTED)
#ifdef STD_MAKE_UNIQUE_NOT_SUPPORTED
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm
#include <cstddef>

View File

@@ -1,254 +0,0 @@
/*
* A File Iterator Implementation
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: filesystem/file_iterator.hpp
* @description:
* file_iterator is a toolkit for applying each file and directory in a
* specified path.
*/
#ifndef NANA_FILESYSTEM_FILE_ITERATOR_HPP
#define NANA_FILESYSTEM_FILE_ITERATOR_HPP
#include <iterator>
#include <memory>
#include <nana/deploy.hpp>
#ifdef NANA_WINDOWS
#include <windows.h>
typedef HANDLE find_handle_t;
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
typedef DIR* find_handle_t;
#endif
namespace nana
{
namespace filesystem
{
struct fileinfo
{
fileinfo();
#ifdef NANA_WINDOWS
fileinfo(const WIN32_FIND_DATA& wfd);
#elif defined(NANA_POSIX)
fileinfo(const std::string& filename, const struct stat &);
#endif
::std::string name;
unsigned long size;
bool directory;
};
template<typename FileInfo>
class basic_file_iterator
:public std::iterator<std::input_iterator_tag, FileInfo>
{
public:
typedef FileInfo value_type;
basic_file_iterator():end_(true), handle_(nullptr){}
basic_file_iterator(const std::string& file_path)
:end_(false), handle_(nullptr)
{
_m_prepare(file_path);
}
const value_type&
operator*() const { return value_; }
const value_type*
operator->() const { return &(operator*()); }
basic_file_iterator& operator++()
{ _m_read(); return *this; }
basic_file_iterator operator++(int)
{
basic_file_iterator tmp = *this;
_m_read();
return tmp;
}
bool equal(const basic_file_iterator& x) const
{
if(end_ && (end_ == x.end_)) return true;
return (value_.name == x.value_.name);
}
private:
template<typename Char>
static bool _m_ignore(const Char * p)
{
while(*p == '.')
++p;
return (*p == 0);
}
void _m_prepare(const std::string& file_path)
{
#if defined(NANA_WINDOWS)
auto pat = utf8_cast(file_path);
DWORD attr = ::GetFileAttributes(pat.data());
if((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY))
pat += L"\\*";
::HANDLE handle = ::FindFirstFile(pat.data(), &wfd_);
if(handle == INVALID_HANDLE_VALUE)
{
end_ = true;
return;
}
while(_m_ignore(wfd_.cFileName))
{
if(::FindNextFile(handle, &wfd_) == 0)
{
end_ = true;
::FindClose(handle);
return;
}
}
value_ = value_type(wfd_);
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
path_ = file_path;
if(path_.size() && path_.back() != '/')
path_ += '/';
auto handle = opendir(path_.c_str());
end_ = true;
if(handle)
{
struct dirent * dnt = readdir(handle);
if(dnt)
{
while(_m_ignore(dnt->d_name))
{
dnt = readdir(handle);
if(dnt == 0)
{
closedir(handle);
return;
}
}
struct stat fst;
if(stat((path_ + dnt->d_name).c_str(), &fst) == 0)
{
value_ = value_type(dnt->d_name, fst);
}
else
{
value_.name = nana::charset(dnt->d_name);
value_.size = 0;
value_.directory = false;
}
end_ = false;
}
}
#endif
if(false == end_)
{
find_ptr_ = std::shared_ptr<find_handle_t>(new find_handle_t(handle), inner_handle_deleter());
handle_ = handle;
}
}
void _m_read()
{
if(handle_)
{
#if defined(NANA_WINDOWS)
if(::FindNextFile(handle_, &wfd_) != 0)
{
while(_m_ignore(wfd_.cFileName))
{
if(::FindNextFile(handle_, &wfd_) == 0)
{
end_ = true;
return;
}
}
value_ = value_type(wfd_);
}
else
end_ = true;
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
struct dirent * dnt = readdir(handle_);
if(dnt)
{
while(_m_ignore(dnt->d_name))
{
dnt = readdir(handle_);
if(dnt == 0)
{
end_ = true;
return;
}
}
struct stat fst;
if(stat((path_ + "/" + dnt->d_name).c_str(), &fst) == 0)
value_ = value_type(nana::charset(dnt->d_name), fst);
else
value_.name = nana::charset(dnt->d_name);
}
else
end_ = true;
#endif
}
}
private:
struct inner_handle_deleter
{
void operator()(find_handle_t * handle)
{
if(handle && *handle)
{
#if defined(NANA_WINDOWS)
::FindClose(*handle);
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
::closedir(*handle);
#endif
}
delete handle;
}
};
private:
bool end_;
#if defined(NANA_WINDOWS)
WIN32_FIND_DATA wfd_;
#else
std::string path_;
#endif
std::shared_ptr<find_handle_t> find_ptr_;
find_handle_t handle_;
value_type value_;
};
template<typename Value_Type>
inline bool operator==(const basic_file_iterator<Value_Type> & x, const basic_file_iterator<Value_Type> & y)
{
return x.equal(y);
}
template<typename Value_Type>
inline bool operator!=(const basic_file_iterator<Value_Type> & x, const basic_file_iterator<Value_Type> & y)
{
return !x.equal(y);
}
typedef basic_file_iterator<fileinfo> file_iterator;
}//end namespace filesystem
}//end namespace nana
#endif

View File

@@ -8,9 +8,6 @@
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/filesystem/filesystem.hpp
* @description:
* file_iterator is a toolkit for applying each file and directory in a
* specified path.
* Modiffied by Ariel Vina-Rodriguez:
* Now mimic std::experimental::filesystem::v1 (boost v3)
* and need VC2015 or a C++11 compiler. With a few correction will be compiler by VC2013
@@ -32,6 +29,8 @@
#ifndef NANA_FILESYSTEM_HPP
#define NANA_FILESYSTEM_HPP
#include <string>
#include <system_error>
#include <iterator>
#include <memory>
#include <chrono>
@@ -40,16 +39,6 @@
#include <nana/deploy.hpp>
#ifdef NANA_WINDOWS
#include <windows.h>
typedef HANDLE find_handle_t;
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
typedef DIR* find_handle_t;
#endif
// namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
namespace nana { namespace experimental
@@ -80,19 +69,6 @@ namespace filesystem
//enum class copy_options;
//enum class directory_options;
// class filesystem_error;
enum class error { none = 0 }; // deprecate ??
struct attribute // deprecate ??
{
uintmax_t size {};
bool directory{};
tm modified {};
attribute() {} ;
attribute( uintmax_t size, bool is_directory) :size{size}, directory{is_directory} {}
};
struct space_info
{
uintmax_t capacity;
@@ -141,7 +117,7 @@ namespace filesystem
#endif
using string_type = std::basic_string<value_type>;
path();
path() = default;
template<typename Source>
path(const Source& source)
@@ -149,6 +125,7 @@ namespace filesystem
_m_assign(source);
}
int compare(const path& other) const;
bool empty() const;
@@ -157,8 +134,14 @@ namespace filesystem
path parent_path() const;
file_type what() const;
//decomposition
path filename() const;
//modifiers
path& remove_filename();
const value_type*c_str() const;
const string_type& native() const;
operator string_type() const;
@@ -166,6 +149,23 @@ namespace filesystem
std::string string() const;
std::wstring wstring() const;
std::string u8string() const;
//appends
path& operator/=(const path& other);
template<typename Source>
path& operator/=(const Source& source)
{
path other(source);
return this->operator/=(other);
}
template<typename Source>
path& append(const Source& source)
{
path other(source);
return this->operator/=(other);
}
private:
void _m_assign(const std::string& source_utf8);
void _m_assign(const std::wstring& source);
@@ -177,35 +177,49 @@ namespace filesystem
bool operator!=(const path& lhs, const path& rhs);
bool operator<(const path& lhs, const path& rhs);
bool operator>(const path& lhs, const path& rhs);
path operator/(const path& lhs, const path& rhs);
struct directory_entry
class filesystem_error
: public std::system_error
{
using path_type = filesystem::path;
path_type m_path;
public:
explicit filesystem_error(const std::string& msg, std::error_code);
attribute attr{};
//file_status m_status;
filesystem_error(const std::string& msg, const path& path1, std::error_code err);
filesystem_error(const std::string& msg, const path& path1, const path& path2, std::error_code err);
directory_entry(){}
directory_entry(const path_type& p, bool is_directory, uintmax_t size)
:m_path{p}, attr{size, is_directory}
{}
const path& path1() const; //noexcept
const path& path2() const; //noexcept
private:
path path1_;
path path2_;
};
void assign (const path_type& p){ m_path=p;}
void replace_filename(const path_type& p){ m_path=p;}
//file_status status() const;
class directory_entry
{
public:
directory_entry() = default;
explicit directory_entry(const path&);
operator const path_type&() const {return m_path;};
const path_type& path() const {return m_path;}
//modifiers
void assign(const path&);
void replace_filename(const path&);
//observers
file_status status() const;
operator const filesystem::path&() const;
const filesystem::path& path() const;
private:
filesystem::path path_;
};
/// an iterator for a sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator
//template<typename FileInfo>
class directory_iterator :public std::iterator<std::input_iterator_tag, directory_entry>
{
using find_handle = void*;
public:
using value_type = directory_entry ;
typedef ptrdiff_t difference_type;
@@ -213,35 +227,20 @@ namespace filesystem
typedef const directory_entry& reference;
typedef std::input_iterator_tag iterator_category;
directory_iterator():end_(true), handle_(nullptr){}
directory_iterator(const path& file_path) { _m_prepare(file_path); }
directory_iterator();
directory_iterator(const path& file_path);
const value_type&
operator*() const { return value_; }
const value_type& operator*() const;
const value_type* operator->() const;
const value_type*
operator->() const { return &(operator*()); }
directory_iterator& operator++()
{ _m_read(); return *this; }
directory_iterator operator++(int)
{
directory_iterator tmp = *this;
_m_read();
return tmp;
}
bool equal(const directory_iterator& x) const
{
if(end_ && (end_ == x.end_)) return true;
return (value_.path().filename() == x.value_.path().filename());
}
directory_iterator& operator++();
directory_iterator operator++(int);
bool equal(const directory_iterator& x) const;
// enable directory_iterator range-based for statements
directory_iterator begin( ) { return *this; }
directory_iterator end( ) { return {}; }
directory_iterator begin();
directory_iterator end();
private:
template<typename Char>
@@ -252,150 +251,14 @@ namespace filesystem
return (*p == 0);
}
void _m_prepare(const path& file_path)
{
auto path_ = file_path.native();
#if defined(NANA_WINDOWS)
auto pat = path_;
DWORD attr = ::GetFileAttributes(pat.data());
if((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY))
pat += L"\\*";
::HANDLE handle = ::FindFirstFile(pat.data(), &wfd_);
if(handle == INVALID_HANDLE_VALUE)
{
end_ = true;
return;
}
while(_m_ignore(wfd_.cFileName))
{
if(::FindNextFile(handle, &wfd_) == 0)
{
end_ = true;
::FindClose(handle);
return;
}
}
value_ = value_type(path(wfd_.cFileName),
(FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
wfd_.nFileSizeLow);
#elif defined(NANA_POSIX)
if(path_.size() && (path_[path_.size() - 1] != '/'))
path_ += '/';
find_handle_t handle = opendir(path_.c_str());
end_ = true;
if(handle)
{
struct dirent * dnt = readdir(handle);
if(dnt)
{
while(_m_ignore(dnt->d_name))
{
dnt = readdir(handle);
if(dnt == 0)
{
closedir(handle);
return;
}
}
struct stat fst;
bool is_directory = false;
unsigned size = 0;
if(stat((path_ + dnt->d_name).c_str(), &fst) == 0)
{
is_directory = (0 != S_ISDIR(fst.st_mode));
size = fst.st_size;
}
value_ = value_type(static_cast<std::wstring>(nana::charset(dnt->d_name)), is_directory, size);
end_ = false;
}
}
#endif
if(false == end_)
{
find_ptr_ = std::shared_ptr<find_handle_t>(new find_handle_t(handle), inner_handle_deleter());
handle_ = handle;
}
}
void _m_read()
{
if(handle_)
{
#if defined(NANA_WINDOWS)
if(::FindNextFile(handle_, &wfd_) != 0)
{
while(_m_ignore(wfd_.cFileName))
{
if(::FindNextFile(handle_, &wfd_) == 0)
{
end_ = true;
return;
}
}
value_ = value_type(path(wfd_.cFileName),
(FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
wfd_.nFileSizeLow);
}
else
end_ = true;
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
struct dirent * dnt = readdir(handle_);
if(dnt)
{
while(_m_ignore(dnt->d_name))
{
dnt = readdir(handle_);
if(dnt == 0)
{
end_ = true;
return;
}
}
std::wstring d_name = nana::charset(dnt->d_name, nana::unicode::utf8);
struct stat fst;
if(stat((path_ + "/" + dnt->d_name).c_str(), &fst) == 0)
value_ = value_type(std::move(d_name), (0 != S_ISDIR(fst.st_mode)), fst.st_size);
else
value_.m_path = path(std::move(d_name));
}
else
end_ = true;
#endif
}
}
private:
struct inner_handle_deleter
{
void operator()(find_handle_t * handle)
{
if(handle && *handle)
{
#if defined(NANA_WINDOWS)
::FindClose(*handle);
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
::closedir(*handle);
#endif
}
delete handle;
}
};
void _m_prepare(const path& file_path);
void _m_read();
private:
bool end_{false};
#if defined(NANA_WINDOWS)
WIN32_FIND_DATA wfd_;
#endif
path::string_type path_;
std::shared_ptr<find_handle_t> find_ptr_;
find_handle_t handle_{nullptr};
std::shared_ptr<find_handle> find_ptr_;
find_handle handle_{nullptr};
value_type value_;
};
@@ -420,24 +283,30 @@ namespace filesystem
file_status status(const path& p);
std::uintmax_t file_size(const path& p);
//uintmax_t file_size(const path& p, error_code& ec) noexcept;
inline bool is_directory(file_status s) { return s.type() == file_type::directory ;}
bool is_directory(const path& p);
inline bool is_directory(const directory_entry& d) { return d.attr.directory; }
inline bool is_directory(const directory_entry& d)
{
return is_directory(d.status());
}
//bool is_directory(const path& p, error_code& ec) noexcept;
//bool is_regular_file(file_status s) noexcept;
inline bool is_empty(const path& p)
{
directory_iterator d(p) ;
return d->attr.directory ? d == directory_iterator()
: d->attr.size == 0;
auto fs = status(p);
if (is_directory(fs))
return (directory_iterator() == directory_iterator(p));
return (file_size(p) == 0);
}
//bool is_empty(const path& p, error_code& ec) noexcept;
std::uintmax_t file_size(const path& p);
//uintmax_t file_size(const path& p, error_code& ec) noexcept;
bool create_directories(const path& p);
//bool create_directories(const path& p, error_code& ec) noexcept;

View File

@@ -26,11 +26,9 @@ namespace filesystem
bool modified_file_time(const ::std::string& file, struct tm&);
std::wstring path_user();
std::string path_user();
bool rmfile(const char* file_utf8);
bool rmdir(const char* dir, bool fails_if_not_empty);
}//end namespace filesystem
}//end namespace nana

View File

@@ -1,7 +1,7 @@
/*
* Filebox
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -313,9 +313,6 @@ namespace API
void eat_tabstop(window, bool);
window move_tabstop(window, bool next); ///< Sets the focus to the window which tabstop is near to the specified window.
//bool glass_window(window); //deprecated
//bool glass_window(window, bool); //deprecated
/// Sets the window active state. If a window active state is false, the window will not obtain the focus when a mouse clicks on it wich will be obteined by take_if_has_active_false.
void take_active(window, bool has_active, window take_if_has_active_false);

View File

@@ -1,7 +1,7 @@
/*
* An Implementation of i18n
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -123,7 +123,7 @@ namespace nana
std::string eval() const override
{
std::wstringstream ss;
std::stringstream ss;
ss << fn_();
return ss.str();
}

View File

@@ -15,7 +15,8 @@
#define NANA_PAINT_IMAGE_HPP
#include "graphics.hpp"
#include "../filesystem/filesystem.hpp"
#include <nana/filesystem/filesystem.hpp>
namespace nana
{

View File

@@ -1,6 +1,6 @@
/*
* Operation System Shared Linkage Library Wrapper Implementation
* Copyright(C) 2003 Jinhao
* Copyright(C) 2003-2016 Jinhao
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,7 +13,7 @@
#define NANA_SYSTEM_SHARED_WRAPPER_HPP
#include <nana/deploy.hpp>
#include <nana/traits.hpp>
#include <type_traits>
#include <stdexcept>
@@ -69,7 +69,8 @@ namespace system
{
typedef typename function_ptr<Function>::type fptr_type;
if(nana::traits::is_function_pointer<fptr_type>::value == false)
//if(nana::traits::is_function_pointer<fptr_type>::value == false)
if (::std::is_function<typename std::remove_pointer<fptr_type>::type>::value == false)
throw std::invalid_argument("shared_wrapper::symbols, template<_Function> is not a function type or a function pointer type");
if(symbol == 0)

View File

@@ -1,41 +0,0 @@
/*
* A File Iterator Implementation
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/filesystem/file_iterator.cpp
* @description:
* file_iterator is a toolkit for applying each file and directory in a
* specified path.
*/
#include <nana/filesystem/file_iterator.hpp>
namespace nana
{
namespace filesystem
{
//struct fileinfo
fileinfo::fileinfo()
:size(0), directory(false)
{}
#if defined(NANA_WINDOWS)
fileinfo::fileinfo(const WIN32_FIND_DATA& wfd)
: name(utf8_cast(wfd.cFileName)), size(wfd.nFileSizeLow),
directory((FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY)
{
}
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
fileinfo::fileinfo(const ::std::string& name, const struct stat& fst)
:name(name), size(fst.st_size), directory(0 != S_ISDIR(fst.st_mode))
{
}
#endif
//end struct fileinfo
}//end namespace filesystem
}//end namespace nana

View File

@@ -24,7 +24,7 @@
#include <shlobj.h>
#include <nana/datetime.hpp>
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
#elif defined(NANA_POSIX)
#include <nana/charset.hpp>
#include <sys/stat.h>
#include <sys/types.h>
@@ -36,9 +36,38 @@
#include <stdlib.h>
#endif
namespace nana { namespace experimental {
namespace filesystem
{
//class filesystem_error
filesystem_error::filesystem_error(const std::string& msg, std::error_code err)
: std::system_error(err, msg)
{}
filesystem_error::filesystem_error(const std::string& msg, const path& path1, std::error_code err)
: std::system_error(err, msg),
path1_(path1)
{}
filesystem_error::filesystem_error(const std::string& msg, const path& path1, const path& path2, std::error_code err)
: std::system_error(err, msg),
path1_(path1),
path2_(path2)
{}
const path& filesystem_error::path1() const
{
return path1_;
}
const path&filesystem_error::path2() const
{
return path2_;
}
//end class filesystem_error
//Because of No wide character version of POSIX
#if defined(NANA_LINUX) || defined(NANA_MACOS)
const char* splstr = "/";
@@ -73,8 +102,6 @@ namespace nana { namespace experimental {
//end filestatus
//class path
path::path() {}
int path::compare(const path& p) const
{
return pathstr_.compare(p.pathstr_);
@@ -158,6 +185,41 @@ namespace nana { namespace experimental {
return{ pathstr_ };
}
path& path::remove_filename()
{
#ifdef NANA_WINDOWS
wchar_t seps[] = L"/\\";
#else
char seps[] = "/\\";
#endif
auto pos = pathstr_.find_last_of(seps);
if (pos != pathstr_.npos)
{
pos = pathstr_.find_last_not_of(seps, pos);
if (pos != pathstr_.npos)
{
#ifdef NANA_WINDOWS
if (pathstr_[pos] == L':')
{
pathstr_.erase(pos + 1);
pathstr_ += L'\\';
return *this;
}
#endif
++pos;
}
else
pos = 0;
}
else
pos = 0;
pathstr_.erase(pos);
return *this;
}
const path::value_type* path::c_str() const
{
return native().c_str();
@@ -188,6 +250,36 @@ namespace nana { namespace experimental {
return to_utf8(pathstr_);
}
path & path::operator/=(const path& p)
{
if (p.empty())
return *this;
if (this == &p)
{
auto other = p.pathstr_;
if ((other.front() != '/') && (other.front() == path::preferred_separator))
{
if (!this->pathstr_.empty() && (pathstr_.back() != '/' && pathstr_.back() == path::preferred_separator))
pathstr_.append(path::preferred_separator, 1);
}
pathstr_ += other;
}
else
{
auto & other = p.pathstr_;
if ((other.front() != '/') && (other.front() == path::preferred_separator))
{
if (!this->pathstr_.empty() && (pathstr_.back() != '/' && pathstr_.back() == path::preferred_separator))
pathstr_.append(path::preferred_separator, 1);
}
pathstr_ += p.pathstr_;
}
return *this;
}
void path::_m_assign(const std::string& source_utf8)
{
#if defined(NANA_WINDOWS)
@@ -227,6 +319,205 @@ namespace nana { namespace experimental {
return (rhs.compare(lhs) < 0);
}
path operator/(const path& lhs, const path& rhs)
{
auto path = lhs;
return (path /= rhs);
}
//class directory_entry
directory_entry::directory_entry(const filesystem::path& p)
:path_{ p }
{}
//modifiers
void directory_entry::assign(const filesystem::path& p)
{
path_ = p;
}
void directory_entry::replace_filename(const filesystem::path& p)
{
path_ = path_.parent_path() / p;
}
//observers
file_status directory_entry::status() const
{
return filesystem::status(path_);
}
directory_entry::operator const filesystem::path&() const
{
return path_;
}
const path& directory_entry::path() const
{
return path_;
}
//end class directory_entry
//class directory_iterator
struct inner_handle_deleter
{
void operator()(void** handle)
{
#if defined(NANA_WINDOWS)
::FindClose(*handle);
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
::closedir(*reinterpret_cast<DIR**>(handle));
#endif
}
};
directory_iterator::directory_iterator()
: end_(true),
handle_(nullptr)
{}
directory_iterator::directory_iterator(const path& file_path)
{
_m_prepare(file_path);
}
const directory_iterator::value_type& directory_iterator::operator*() const { return value_; }
const directory_iterator::value_type*
directory_iterator::operator->() const { return &(operator*()); }
directory_iterator& directory_iterator::operator++()
{
_m_read(); return *this;
}
directory_iterator directory_iterator::operator++(int)
{
directory_iterator tmp = *this;
_m_read();
return tmp;
}
bool directory_iterator::equal(const directory_iterator& x) const
{
if (end_ && (end_ == x.end_)) return true;
return (value_.path().filename() == x.value_.path().filename());
}
// enable directory_iterator range-based for statements
directory_iterator directory_iterator::begin() { return *this; }
directory_iterator directory_iterator::end() { return{}; }
void directory_iterator::_m_prepare(const path& file_path)
{
path_ = file_path.native();
#if defined(NANA_WINDOWS)
if (!path_.empty() && (path_.back() != L'/' && path_.back() != L'\\'))
path_ += L'\\';
auto pat = path_;
DWORD attr = ::GetFileAttributes(pat.data());
if ((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY))
pat += L"*";
WIN32_FIND_DATAW wfd;
::HANDLE handle = ::FindFirstFile(pat.data(), &wfd);
if (handle == INVALID_HANDLE_VALUE)
{
end_ = true;
return;
}
while (_m_ignore(wfd.cFileName))
{
if (::FindNextFile(handle, &wfd) == 0)
{
end_ = true;
::FindClose(handle);
return;
}
}
value_ = value_type(path(path_ + wfd.cFileName));
#elif defined(NANA_POSIX)
if (path_.size() && (path_.back() != '/'))
path_ += '/';
auto handle = opendir(path_.c_str());
end_ = true;
if (handle)
{
struct dirent * dnt = readdir(handle);
if (dnt)
{
while (_m_ignore(dnt->d_name))
{
dnt = readdir(handle);
if (dnt == 0)
{
closedir(handle);
return;
}
}
value_ = value_type(path_ + dnt->d_name);
end_ = false;
}
}
#endif
if (false == end_)
{
find_ptr_ = std::shared_ptr<find_handle>(new find_handle(handle), inner_handle_deleter());
handle_ = handle;
}
}
void directory_iterator::_m_read()
{
if (handle_)
{
#if defined(NANA_WINDOWS)
WIN32_FIND_DATAW wfd;
if (::FindNextFile(handle_, &wfd) != 0)
{
while (_m_ignore(wfd.cFileName))
{
if (::FindNextFile(handle_, &wfd) == 0)
{
end_ = true;
return;
}
}
value_ = value_type(path(path_ + wfd.cFileName));
}
else
end_ = true;
#elif defined(NANA_POSIX)
struct dirent * dnt = readdir(reinterpret_cast<DIR*>(handle_));
if (dnt)
{
while (_m_ignore(dnt->d_name))
{
dnt = readdir(reinterpret_cast<DIR*>(handle_));
if (!dnt)
{
end_ = true;
return;
}
}
value_ = value_type(path(path_ + dnt->d_name));
}
else
end_ = true;
#endif
}
}
//end class directory_iterator
namespace detail
{
//rm_dir_recursive
@@ -243,12 +534,12 @@ namespace nana { namespace experimental {
for (auto & f : files)
{
auto subpath = path + f.path().filename().native();
if (f.attr.directory)
if (is_directory(f))
rm_dir_recursive(subpath.c_str());
else
rmfile(subpath.c_str());
}
return rmdir(dir, true);
}

View File

@@ -1,6 +1,6 @@
/*
* A FileSystem Utility Implementation
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,7 +12,6 @@
*/
#include <nana/filesystem/fs_utility.hpp>
#include <nana/filesystem/file_iterator.hpp>
#include <nana/deploy.hpp>
#include <vector>
#if defined(NANA_WINDOWS)
@@ -53,27 +52,6 @@ namespace filesystem
namespace detail
{
//rm_dir_recursive
//@brief: remove a directory, if it is not empty, recursively remove it's subfiles and sub directories
bool rm_dir_recursive(std::string&& dir)
{
std::vector<file_iterator::value_type> files;
auto path = dir;
path += '\\';
std::copy(file_iterator(dir), file_iterator(), std::back_inserter(files));
for(auto & f : files)
{
if(f.directory)
rm_dir_recursive(path + f.name);
else
rmfile((path + f.name).c_str());
}
return rmdir(dir.c_str(), true);
}
#if defined(NANA_WINDOWS)
void filetime_to_c_tm(FILETIME& ft, struct tm& t)
{
@@ -150,41 +128,18 @@ namespace filesystem
#endif
}
bool rmdir(const char* dir, bool fails_if_not_empty)
{
bool ret = false;
if(dir)
{
#if defined(NANA_WINDOWS)
ret = (::RemoveDirectory(utf8_cast(dir).c_str()) == TRUE);
if(!fails_if_not_empty && (::GetLastError() == ERROR_DIR_NOT_EMPTY))
ret = detail::rm_dir_recursive(dir);
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
std::string mbstr = nana::charset(dir);
if(::rmdir(mbstr.c_str()))
{
if(!fails_if_not_empty && (errno == EEXIST || errno == ENOTEMPTY))
ret = detail::rm_dir_recursive(dir);
}
else
ret = true;
#endif
}
return ret;
}
std::wstring path_user()
std::string path_user()
{
#if defined(NANA_WINDOWS)
wchar_t path[MAX_PATH];
if(SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, path)))
return path;
return to_utf8(path);
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
const char * s = ::getenv("HOME");
if(s)
return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8);
return s;
#endif
return std::wstring();
return std::string();
}
}//end namespace filesystem
}//end namespace nana

View File

@@ -1226,7 +1226,7 @@ namespace nana{
auto prev = ::SetParent(reinterpret_cast<HWND>(child), reinterpret_cast<HWND>(new_parent));
if (prev)
::PostMessage(prev, WM_CHANGEUISTATE, UIS_INITIALIZE, NULL);
::PostMessage(prev, /*WM_CHANGEUISTATE*/0x0127, /*UIS_INITIALIZE*/ 3, 0);
::SetWindowPos(reinterpret_cast<HWND>(child), NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);

View File

@@ -1,7 +1,7 @@
/*
* Filebox
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,7 +17,7 @@
#if defined(NANA_WINDOWS)
#include <windows.h>
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
#elif defined(NANA_POSIX)
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/widgets/button.hpp>
#include <nana/gui/widgets/listbox.hpp>
@@ -25,7 +25,7 @@
#include <nana/gui/widgets/textbox.hpp>
#include <nana/gui/widgets/treebox.hpp>
#include <nana/gui/widgets/combox.hpp>
#include <nana/filesystem/file_iterator.hpp>
#include <nana/filesystem/filesystem.hpp>
#include <nana/gui/place.hpp>
#include <stdexcept>
#include <algorithm>
@@ -33,7 +33,7 @@
namespace nana
{
#if defined(NANA_LINUX) || defined(NANA_MACOS)
#if defined(NANA_POSIX)
class filebox_implement
: public form
{
@@ -421,8 +421,6 @@ namespace nana
void _m_init_tree()
{
using namespace nana::filesystem;
//The path in linux is starting with the character '/', the name of root key should be
//"FS.HOME", "FS.ROOT". Because a key of the tree widget should not be '/'
nodes_.home = tree_.insert("FS.HOME", "Home");
@@ -430,29 +428,28 @@ namespace nana
nodes_.filesystem = tree_.insert("FS.ROOT", "Filesystem");
nodes_.filesystem.value(kind::filesystem);
file_iterator end;
for(file_iterator i(to_nstring(path_user())); i != end; ++i)
{
if((false == i->directory) || (i->name.size() && i->name[0] == '.')) continue;
namespace fs = ::nana::experimental::filesystem;
item_proxy node = tree_.insert(nodes_.home, i->name, i->name);
if(false == node.empty())
std::vector<std::string> paths;
paths.emplace_back(nana::filesystem::path_user());
paths.emplace_back("/");
fs::directory_iterator end;
for (auto & p : paths)
{
for (fs::directory_iterator i(p); i != end; ++i)
{
auto name = i->path().filename().native();
if (!is_directory(i->status()) || (name.size() && name[0] == '.'))
continue;
item_proxy node = tree_.insert(nodes_.filesystem, name, name);
if (false == node.empty())
{
node.value(kind::filesystem);
break;
}
}
for(file_iterator i("/"); i != end; ++i)
{
if((false == i->directory) || (i->name.size() && i->name[0] == '.')) continue;
item_proxy node = tree_.insert(nodes_.filesystem, i->name, i->name);
if(false == node.empty())
{
node.value(kind::filesystem);
break;
}
}
tree_.events().expanded.connect_unignorable([this](const arg_treebox& arg)
@@ -494,29 +491,31 @@ namespace nana
file_container_.clear();
using namespace nana::filesystem;
file_iterator end;
for(file_iterator i(path); i != end; ++i)
{
if((i->name.size() == 0) || (i->name[0] == '.'))
continue;
item_fs m;
m.name = i->name;
namespace fs = ::nana::experimental::filesystem;
fs::directory_iterator end;
for(fs::directory_iterator i(path); i != end; ++i)
{
auto name = i->path().filename().native();
if(name.empty() || (name.front() == '.'))
continue;
item_fs m;
m.name = name;
auto fattr = fs::status(path + m.name);
if(fattr.type() != fs::file_type::not_found && fattr.type() != fs::file_type::unknown)
{
m.bytes = fs::file_size(path + m.name);
m.directory = fs::is_directory(fattr);
modified_file_time(path + m.name, m.modified_time);
::nana::filesystem::modified_file_time(path + m.name, m.modified_time);
}
else
{
m.bytes = 0;
m.directory = i->directory;
modified_file_time(path + i->name, m.modified_time);
m.directory = fs::is_directory(*i);
::nana::filesystem::modified_file_time(path + i->path().filename().native(), m.modified_time);
}
file_container_.push_back(m);
@@ -554,11 +553,13 @@ namespace nana
if(head.size() == 0 || head[head.size() - 1] != '/')
head += '/';
nana::filesystem::file_iterator end;
for(nana::filesystem::file_iterator i(head); i != end; ++i)
namespace fs = ::nana::experimental::filesystem;
fs::directory_iterator end;
for(fs::directory_iterator i(head); i != end; ++i)
{
if(i->directory)
path_.childset(i->name, 0);
if(is_directory(*i))
path_.childset(i->path().filename().native(), 0);
}
auto cat_path = path_.caption();
if(cat_path.size() && cat_path[cat_path.size() - 1] != '/')
@@ -574,10 +575,10 @@ namespace nana
(head += folder) += '/';
path_.caption(cat_path);
for(nana::filesystem::file_iterator i(head); i != end; ++i)
for(fs::directory_iterator i(head); i != end; ++i)
{
if(i->directory)
path_.childset(i->name, 0);
if (is_directory(*i))
path_.childset(i->path().filename().native(), 0);
}
if(pos == path.npos)
@@ -809,18 +810,25 @@ namespace nana
auto path = tree_.make_key_path(node, "/") + "/";
_m_resolute_path(path);
nana::filesystem::file_iterator end;
for(nana::filesystem::file_iterator i(path); i != end; ++i)
namespace fs = ::nana::experimental::filesystem;
fs::directory_iterator end;
for (fs::directory_iterator i{path}; i != end; ++i)
{
if((false == i->directory) || (i->name.size() && i->name[0] == '.')) continue;
auto child = node.append(i->name, i->name, kind::filesystem);
auto name = i->path().filename().native();
if((!is_directory(*i)) || (name.size() && name[0] == '.'))
continue;
auto child = node.append(name, name, kind::filesystem);
if(!child.empty())
{
for(nana::filesystem::file_iterator u(path + i->name); u != end; ++u)
for(fs::directory_iterator u(i->path()); u != end; ++u)
{
if(false == u->directory || (u->name.size() && u->name[0] == '.')) continue;
auto uname = i->path().filename().native();
if ((!is_directory(*i)) || (uname.size() && uname[0] == '.'))
continue;
child.append(u->name, u->name, kind::filesystem);
child.append(uname, uname, kind::filesystem);
break;
}
}
@@ -1047,7 +1055,7 @@ namespace nana
wfile.resize(std::wcslen(wfile.data()));
impl_->file = utf8_cast(wfile);
#elif defined(NANA_LINUX) || defined(NANA_MACOS)
#elif defined(NANA_POSIX)
filebox_implement fb(impl_->owner, impl_->open_or_save, impl_->title);
if(impl_->filters.size())

View File

@@ -1168,24 +1168,6 @@ namespace API
return reinterpret_cast<window>(ts_wd);
}
/*
//glass_window deprecated
//@brief: Test a window whether it is a glass attribute.
bool glass_window(window wd)
{
return (bground_mode::basic == effects_bground_mode(wd));
}
bool glass_window(window wd, bool isglass) //deprecated
{
if(isglass)
effects_bground(wd, effects::bground_transparent(0), 0);
else
effects_bground_remove(wd);
return true;
}
*/
void take_active(window wd, bool active, window take_if_active_false)
{
auto const iwd = reinterpret_cast<basic_window*>(wd);