directory_functions.hpp

来自「用STL的方式封装了WindowsAPI、COM调用、ACE、ATL、MFC、W」· HPP 代码 · 共 597 行 · 第 1/2 页

HPP
597
字号
                        if(NULL != pfn)
                        {
                            (void)(*pfn)(param, dir, NULL, NULL, dwRet);
                        }
                    }
                    else
                    {
                        // It has some contents, so we need to remove them

                        file_path_buffer_t          sz;
                        DIR                         *hSrch;
                        size_t                      n;

                        traits_t::str_copy(&sz[0], dir);
                        traits_t::ensure_dir_end(&sz[0]);
                        n = traits_t::str_len(sz.c_str());

                        hSrch = traits_t::open_dir(sz.c_str());
                        if(NULL == hSrch)
                        {
                            dwRet = traits_t::get_last_error();
                        }
                        else
                        {
                            dwRet = 0;

                            for(struct dirent const *de; 0 == dwRet && NULL != (de = traits_t::read_dir(hSrch)); )
                            {
                                if(!traits_t::is_dots(de->d_name))
                                {
                                    ss_typename_type_k traits_t::stat_data_type st;

                                    traits_t::str_copy(&sz[0] + n, de->d_name);
                                    if(!traits_t::stat(sz.c_str(), &st))
                                    {
                                        dwRet = traits_t::get_last_error();

                                        if(NULL != pfn)
                                        {
                                            (void)(*pfn)(param, dir, NULL, de, dwRet);
                                        }
                                    }
                                    else
                                    {
                                        if(traits_t::is_file(&st))
                                        {
                                            // If it's a file, the pfn must be consulted, otherwise
                                            // it's an automatic failure

                                            if( NULL == pfn ||
                                                !(*pfn)(param, dir, &st, de, 0))
                                            {
                                                dwRet = ENOTEMPTY;

                                                if(NULL != pfn)
                                                {
                                                    (void)(*pfn)(param, dir, &st, de, dwRet);
                                                }

                                                break;
                                            }
                                            else
                                            {
                                                if(!traits_t::delete_file(sz.c_str()))
                                                {
                                                    dwRet = traits_t::get_last_error();

                                                    if(NULL != pfn)
                                                    {
                                                        (void)(*pfn)(param, dir, &st, de, dwRet);
                                                    }

                                                    break;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            // If it's a directory, then pfn is consulted, otherwise
                                            // it's an automatic attempt to recursively delete
                                            if( NULL != pfn &&
                                                !(*pfn)(param, dir, &st, de, 0))
                                            {
                                                dwRet = ENOTEMPTY;

                                                if(NULL != pfn)
                                                {
                                                    (void)(*pfn)(param, dir, &st, de, dwRet);
                                                }

                                                break;
                                            }
                                            else
                                            {
                                                dwRet = remove_directory_recurse_impl(sz.c_str(), pfn, param);
                                            }
                                        }
                                    }
                                }
                            }

                            traits_t::close_dir(hSrch);

                            if(0 == dwRet)
                            {
                                if(traits_t::remove_directory(dir))
                                {
                                    if(NULL != pfn)
                                    {
                                        (void)(*pfn)(param, dir, NULL, NULL, 0); // Deleted
                                    }
                                }
                                else
                                {
                                    dwRet = traits_t::get_last_error();
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return dwRet;
}

/* /////////////////////////////////////////////////////////////////////////
 * Functions
 */

/// \brief Creates the given directory, including all its parent directories, applying
/// the given mode.
///
/// \ingroup group__library__file_system
///
/// \param dir The path of the directory to create
/// \param mode The permissions with which each directory is to be created
inline us_bool_t create_directory_recurse(us_char_a_t const *dir, unsigned short mode = 0755)
{
    return create_directory_recurse_impl(dir, mode);
}

#if 0
/// \brief Creates the given directory, including all its parent directories, applying
/// the given mode.
///
/// \ingroup group__library__file_system
///
/// \param dir The path of the directory to create
/// \param mode The permissions with which each directory is to be created
inline us_bool_t create_directory_recurse(us_char_w_t const *dir, unsigned short mode = 0755)
{
    return create_directory_recurse_impl(dir, mode);
}
#endif /* 0 */

/// \brief Creates the given directory, including all its parent directories, applying
/// the given mode.
///
/// \ingroup group__library__file_system
///
/// \param dir The path of the directory to create
/// \param mode The permissions with which each directory is to be created
template <ss_typename_param_k S>
inline us_bool_t create_directory_recurse(S const &dir, unsigned short mode = 0755)
{
    return create_directory_recurse(stlsoft_ns_qual(c_str_ptr)(dir), mode);
}

/// \brief Removes the given directory, and all its subdirectories.
///
/// \ingroup group__library__file_system
///
/// \param dir The path of the directory to remove
/// \param pfn Pointer to a callback function, which will receive notifications
///         and requests for file/directory deletion. The semantics of the
///         parameters are specified in the note below
/// \param param Caller-supplied parameter, passed through to the callback
///         function
///
/// \note If no callback function is specified, then the function will remove
///        only empty subdirectories, i.e. no files will be removed. To remove
///        files, a function must be
///
/// \note The semantics of the callback function's parameters are as follows:
/// \par If the err param is ~0 (-1 on UNIX), then the dir param specifies
///       the name of the current directory being traversed. All other params
///       are unspecified. The return value is ignored.
/// \par If the err param is 0 and the st param is NULL, then dir specifies
///       the name of a directory that has been successfully removed. All
///       other params are unspecified. The return value is ignored.
/// \par If the err param is 0 and the st param is not NULL, then dir specifies
///       the name of the currently traversing directory, st specifies the
///       stat information for the entry to be deleted, and de specifies the
///       name of the entry within directory dir that is a candidate for
///       removal. Return true to enable removal of this entry, or false to
///       prevent removal (and cancel the overall operation). All
///       other params are unspecified. The return value is ignored.
/// \par If the err param is any other value, and the st param is NULL, then
///       the dir param specifies the name of a directory that could not be
///       deleted and err specifies the errno value associated with the failure.
///       All other params are unspecified. The return value is ignored.
/// \par If the err param is any other value, and the st param is not NULL, then
///       the dir param specifies the name of a directory within which an entry
///       could not be deleted, st specifies the stat information of the entry
///       that could not be deleted, de specifies the name of the entry that
///       could not be deleted, and err specifies the errno value associated
///       with the failure. All other params are unspecified. The return value
///       is ignored.
inline us_bool_t remove_directory_recurse(  us_char_a_t const   *dir
                                        ,   us_int_t            (*pfn)(void *param, us_char_a_t const *subDir, struct stat const *st, struct dirent const *de, int err)
                                        ,   void                *param)
{
    typedef filesystem_traits<us_char_a_t>  traits_t;

    us_int_t  dwRet   =   remove_directory_recurse_impl<us_char_a_t, struct stat>(dir, pfn, param);

    traits_t::set_last_error(dwRet);

    return 0 == dwRet;
}

/// \brief 
///
/// \ingroup group__library__file_system
inline us_bool_t remove_directory_recurse(us_char_a_t const *dir)
{
    return remove_directory_recurse(dir, NULL, NULL);
}

#if 0
/// \brief 
///
/// \ingroup group__library__file_system
inline us_bool_t remove_directory_recurse(  us_char_w_t const   *dir
                                        ,   us_int_t            (*pfn)(void *param, us_char_w_t const *subDir, struct stat const *st, struct dirent const *de, int err)
                                        ,   void                *param)
{
    typedef filesystem_traits<us_char_w_t>  traits_t;

    us_int_t  dwRet   =   remove_directory_recurse_impl<us_char_w_t, struct stat>(dir, pfn, param);

    traits_t::set_last_error(dwRet);

    return 0 == dwRet;
}

/// \brief 
///
/// \ingroup group__library__file_system
inline us_bool_t remove_directory_recurse(us_char_w_t const *dir)
{
    return remove_directory_recurse(dir, NULL, NULL);
}
#endif /* 0 */

/// \brief 
///
/// \ingroup group__library__file_system
template <ss_typename_param_k S>
inline us_bool_t remove_directory_recurse(S const &dir)
{
    typedef filesystem_traits<us_char_a_t>  traits_t;

    us_int_t  dwRet   =   remove_directory_recurse(stlsoft_ns_qual(c_str_ptr)(dir), NULL, NULL);

    traits_t::set_last_error(dwRet);

    return 0 == dwRet;
}

/* /////////////////////////////////////////////////////////////////////////
 * Unit-testing
 */

#ifdef STLSOFT_UNITTEST
# include "./unittest/directory_functions_unittest_.h"
#endif /* STLSOFT_UNITTEST */

/* ////////////////////////////////////////////////////////////////////// */

#ifndef _UNIXSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace unixstl
# else
} // namespace unixstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_UNIXSTL_NO_NAMESPACE */

/* ////////////////////////////////////////////////////////////////////// */

#endif /* UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_DIRECTORY_FUNCTIONS */

/* ////////////////////////////////////////////////////////////////////// */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?