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

@@ -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
@@ -134,13 +134,13 @@
//but if USE_github_com_meganz_mingw_std_threads is enabled,
//boost.thread will be replaced with meganz's mingw-std-threads.
// https://github.com/meganz/mingw-std-threads
#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
#if !defined( USE_github_com_meganz_mingw_std_threads )
//#define USE_github_com_meganz_mingw_std_threads
#endif
#endif
#if (__GNUC_MINOR__ < 9)
#define STD_MAKE_UNIQUE_NOT_SUPPORTED
#endif
#if defined(NANA_MINGW)
@@ -218,4 +218,4 @@
#endif
#endif // NANA_CONFIG_HPP
#endif // NANA_CONFIG_HPP

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++();
directory_iterator operator++(int);
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());
}
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)