📄 operations.hpp
字号:
&& boost::filesystem::is_directory( ph ) )
{
for ( boost::filesystem::basic_directory_iterator<Path> itr( ph );
itr != end_itr; ++itr )
{
count += remove_all_aux( itr->path() );
}
}
boost::filesystem::remove( ph );
return count;
}
// test helper -------------------------------------------------------------//
// not part of the documented interface because false positives are possible;
// there is no law that says that an OS that has large stat.st_size
// actually supports large file sizes.
BOOST_FILESYSTEM_DECL bool possible_large_file_size_support();
// directory_iterator helpers ----------------------------------------------//
// forwarding functions avoid need for BOOST_FILESYSTEM_DECL for class
// basic_directory_iterator, and so avoid iterator_facade DLL template
// problems. They also overload to the proper external path character type.
BOOST_FILESYSTEM_DECL boost::filesystem::system_error_type
dir_itr_first( void *& handle,
#if defined(BOOST_POSIX_API)
void *& buffer,
#endif
const std::string & dir_path,
std::string & target, file_status & fs, file_status & symlink_fs );
// eof: return==0 && handle==0
BOOST_FILESYSTEM_DECL boost::filesystem::system_error_type
dir_itr_increment( void *& handle,
#if defined(BOOST_POSIX_API)
void *& buffer,
#endif
std::string & target, file_status & fs, file_status & symlink_fs );
// eof: return==0 && handle==0
BOOST_FILESYSTEM_DECL boost::filesystem::system_error_type
dir_itr_close( void *& handle
#if defined(BOOST_POSIX_API)
, void *& buffer
#endif
);
// Effects: none if handle==0, otherwise close handle, set handle=0
# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY)
BOOST_FILESYSTEM_DECL boost::filesystem::system_error_type
dir_itr_first( void *& handle, const std::wstring & ph,
std::wstring & target, file_status & fs, file_status & symlink_fs );
BOOST_FILESYSTEM_DECL boost::filesystem::system_error_type
dir_itr_increment( void *& handle, std::wstring & target,
file_status & fs, file_status & symlink_fs );
# endif
template< class Path >
class dir_itr_imp
{
public:
basic_directory_entry<Path> m_directory_entry;
void * m_handle;
# ifdef BOOST_POSIX_API
void * m_buffer; // see dir_itr_increment implementation
# endif
dir_itr_imp() : m_handle(0)
# ifdef BOOST_POSIX_API
, m_buffer(0)
# endif
{}
~dir_itr_imp() { dir_itr_close( m_handle
#if defined(BOOST_POSIX_API)
, m_buffer
#endif
); }
};
BOOST_FILESYSTEM_DECL extern system_error_type not_found_error;
} // namespace detail
// basic_directory_iterator ------------------------------------------------//
template< class Path >
class basic_directory_iterator
: public boost::iterator_facade<
basic_directory_iterator<Path>,
basic_directory_entry<Path>,
boost::single_pass_traversal_tag >
{
public:
typedef Path path_type;
basic_directory_iterator(){} // creates the "end" iterator
explicit basic_directory_iterator( const Path & dir_path );
basic_directory_iterator( const Path & dir_path, system_error_type & ec );
private:
// shared_ptr provides shallow-copy semantics required for InputIterators.
// m_imp.get()==0 indicates the end iterator.
boost::shared_ptr< detail::dir_itr_imp< Path > > m_imp;
friend class boost::iterator_core_access;
typename boost::iterator_facade<
basic_directory_iterator<Path>,
basic_directory_entry<Path>,
boost::single_pass_traversal_tag >::reference dereference() const
{
BOOST_ASSERT( m_imp.get() && "attempt to dereference end iterator" );
return m_imp->m_directory_entry;
}
void increment();
bool equal( const basic_directory_iterator & rhs ) const
{ return m_imp == rhs.m_imp; }
system_error_type m_init( const Path & dir_path );
};
typedef basic_directory_iterator< path > directory_iterator;
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
typedef basic_directory_iterator< wpath > wdirectory_iterator;
# endif
// basic_directory_iterator implementation ---------------------------//
template<class Path>
system_error_type basic_directory_iterator<Path>::m_init(
const Path & dir_path )
{
if ( dir_path.empty() )
{
m_imp.reset();
return detail::not_found_error;
}
system_error_type sys_err;
typename Path::external_string_type name;
file_status fs, symlink_fs;
if ( (sys_err = detail::dir_itr_first( m_imp->m_handle,
#if defined(BOOST_POSIX_API)
m_imp->m_buffer,
#endif
dir_path.external_directory_string(),
name, fs, symlink_fs )) != 0 )
{
m_imp.reset();
return sys_err;
}
if ( m_imp->m_handle == 0 ) m_imp.reset(); // eof, so make end iterator
else // not eof
{
m_imp->m_directory_entry.assign( dir_path
/ Path::traits_type::to_internal( name ), fs, symlink_fs );
if ( name[0] == dot<Path>::value // dot or dot-dot
&& (name.size() == 1
|| (name[1] == dot<Path>::value
&& name.size() == 2)) )
{ increment(); }
}
return 0;
}
template<class Path>
basic_directory_iterator<Path>::basic_directory_iterator(
const Path & dir_path )
: m_imp( new detail::dir_itr_imp<Path> )
{
system_error_type ec( m_init(dir_path) );
if ( ec != 0 )
{
boost::throw_exception( basic_filesystem_error<Path>(
"boost::filesystem::basic_directory_iterator constructor",
dir_path, ec ) );
}
}
template<class Path>
basic_directory_iterator<Path>::basic_directory_iterator(
const Path & dir_path, system_error_type & ec )
: m_imp( new detail::dir_itr_imp<Path> )
{
ec = m_init(dir_path);
}
template<class Path>
void basic_directory_iterator<Path>::increment()
{
BOOST_ASSERT( m_imp.get() && "attempt to increment end iterator" );
BOOST_ASSERT( m_imp->m_handle != 0 && "internal program error" );
system_error_type sys_err(0);
typename Path::external_string_type name;
file_status fs, symlink_fs;
for (;;)
{
if ( (sys_err = detail::dir_itr_increment( m_imp->m_handle,
#if defined(BOOST_POSIX_API)
m_imp->m_buffer,
#endif
name, fs, symlink_fs )) != 0 )
{
boost::throw_exception( basic_filesystem_error<Path>(
"boost::filesystem::basic_directory_iterator increment",
m_imp->m_directory_entry.path().branch_path(), sys_err ) );
}
if ( m_imp->m_handle == 0 ) { m_imp.reset(); return; } // eof, make end
if ( !(name[0] == dot<Path>::value // !(dot or dot-dot)
&& (name.size() == 1
|| (name[1] == dot<Path>::value
&& name.size() == 2))) )
{
m_imp->m_directory_entry.replace_leaf(
Path::traits_type::to_internal( name ), fs, symlink_fs );
return;
}
}
}
// basic_directory_entry -----------------------------------------------//
template<class Path>
class basic_directory_entry
{
public:
typedef Path path_type;
typedef typename Path::string_type string_type;
// compiler generated copy-ctor, copy assignment, and destructor apply
basic_directory_entry() {}
explicit basic_directory_entry( const path_type & p,
file_status st = file_status(), file_status symlink_st=file_status() )
: m_path(p), m_status(st), m_symlink_status(symlink_st)
{}
void assign( const path_type & p,
file_status st, file_status symlink_st )
{ m_path = p; m_status = st; m_symlink_status = symlink_st; }
void replace_leaf( const string_type & s,
file_status st, file_status symlink_st )
{
m_path.remove_leaf();
m_path /= s;
m_status = st;
m_symlink_status = symlink_st;
}
const Path & path() const { return m_path; }
file_status status() const;
file_status status( system_error_type & ec ) const;
file_status symlink_status() const;
file_status symlink_status( system_error_type & ec ) const;
// conversion simplifies the most common use of basic_directory_entry
operator const path_type &() const { return m_path; }
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
// deprecated functions preserve common use cases in legacy code
typename Path::string_type leaf() const
{
return path().leaf();
}
typename Path::string_type string() const
{
return path().string();
}
# endif
private:
path_type m_path;
mutable file_status m_status; // stat()-like
mutable file_status m_symlink_status; // lstat()-like
// note: m_symlink_status is not used by Windows implementation
}; // basic_directory_status
typedef basic_directory_entry<path> directory_entry;
# ifndef BOOST_FILESYSTEM_NARROW_ONLY
typedef basic_directory_entry<wpath> wdirectory_entry;
# endif
// basic_directory_entry implementation --------------------------------//
template<class Path>
file_status
basic_directory_entry<Path>::status() const
{
if ( !status_known( m_status ) )
{
# ifndef BOOST_WINDOWS_API
if ( status_known( m_symlink_status )
&& !is_symlink( m_symlink_status ) )
{ m_status = m_symlink_status; }
else { m_status = boost::filesystem::status( m_path ); }
# else
m_status = boost::filesystem::status( m_path );
# endif
}
return m_status;
}
template<class Path>
file_status
basic_directory_entry<Path>::status( system_error_type & ec ) const
{
if ( !status_known( m_status ) )
{
# ifndef BOOST_WINDOWS_API
if ( status_known( m_symlink_status )
&& !is_symlink( m_symlink_status ) )
{ ec = 0; m_status = m_symlink_status; }
else { m_status = boost::filesystem::status( m_path, ec ); }
# else
m_status = boost::filesystem::status( m_path, ec );
# endif
}
else ec = 0;
return m_status;
}
template<class Path>
file_status
basic_directory_entry<Path>::symlink_status() const
{
# ifndef BOOST_WINDOWS_API
if ( !status_known( m_symlink_status ) )
{ m_symlink_status = boost::filesystem::symlink_status( m_path ); }
return m_symlink_status;
# else
return status();
# endif
}
template<class Path>
file_status
basic_directory_entry<Path>::symlink_status( system_error_type & ec ) const
{
# ifndef BOOST_WINDOWS_API
if ( !status_known( m_symlink_status ) )
{ m_symlink_status = boost::filesystem::symlink_status( m_path, ec ); }
else ec = 0;
return m_symlink_status;
# else
return status( ec );
# endif
}
} // namespace filesystem
} // namespace boost
#undef BOOST_FS_FUNC
#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
#endif // BOOST_FILESYSTEM_OPERATIONS_HPP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -