⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directory_functions.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 2 页
字号:
/* /////////////////////////////////////////////////////////////////////////
 * File:        unixstl/filesystem/directory_functions.hpp
 *
 * Purpose:     Functions for manipulating directories.
 *
 * Created:     7th February 2002
 * Updated:     12th March 2007
 *
 * Home:        http://stlsoft.org/
 *
 * Copyright (c) 2002-2007, Matthew Wilson and Synesis Software
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
 *   any contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * ////////////////////////////////////////////////////////////////////// */


/** \file unixstl/filesystem/directory_functions.hpp
 *
 * \brief [C++ only] Functions for manipulating directories
 *   (\ref group__library__filesystem "File System" Library).
 */

#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_DIRECTORY_FUNCTIONS
#define UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_DIRECTORY_FUNCTIONS

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_DIRECTORY_FUNCTIONS_MAJOR       3
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_DIRECTORY_FUNCTIONS_MINOR       0
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_DIRECTORY_FUNCTIONS_REVISION    4
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_DIRECTORY_FUNCTIONS_EDIT        37
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* /////////////////////////////////////////////////////////////////////////
 * Compatibility
 */

/*
[Incompatibilies-start]
STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
[Incompatibilies-end]
 */

/* /////////////////////////////////////////////////////////////////////////
 * Includes
 */

#ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
# include <unixstl/unixstl.h>
#endif /* !UNIXSTL_INCL_UNIXSTL_H_UNIXSTL */
#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
# include <unixstl/filesystem/filesystem_traits.hpp>
#endif /* !UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS */
#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER
# include <unixstl/filesystem/file_path_buffer.hpp>
#endif /* !UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER */

/* /////////////////////////////////////////////////////////////////////////
 * Namespace
 */

#ifndef _UNIXSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
/* There is no stlsoft namespace, so must define ::unixstl */
namespace unixstl
{
# else
/* Define stlsoft::unixstl_project */

namespace stlsoft
{

namespace unixstl_project
{

# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_UNIXSTL_NO_NAMESPACE */

/* /////////////////////////////////////////////////////////////////////////
 * Helper functions
 */

template <ss_typename_param_k C>
inline C *find_last_path_name_separator_(C const* s)
{
    typedef filesystem_traits<C>    traits_t;

    ss_typename_type_k traits_t::char_type const    *slash  =   traits_t::str_rchr(s, '/');
#ifdef _WIN32
    ss_typename_type_k traits_t::char_type const    *bslash =   traits_t::str_rchr(s, '\\');

    if(NULL == slash)
    {
        slash = bslash;
    }
    else if(NULL != bslash)
    {
        if(slash < bslash)
        {
            slash = bslash;
        }
    }
#endif /* _WIN32 */

    return const_cast<C*>(slash);
}

template <ss_typename_param_k C>
inline us_bool_t create_directory_recurse_impl(C const* dir, unsigned short mode)
{
    typedef C                                   char_type;
    typedef filesystem_traits<C>                traits_t;
    typedef basic_file_path_buffer<char_type>   file_path_buffer_t;

    us_bool_t    bRet;

    if( NULL == dir ||
        '\0' == *dir)
    {
        traits_t::set_last_error(ENOTDIR);

        bRet = false;
    }
    else
    {
        if(traits_t::file_exists(dir))
        {
            if(traits_t::is_directory(dir))
            {
                traits_t::set_last_error(EISDIR);

                bRet = true;
            }
            else
            {
                traits_t::set_last_error(EEXIST);

                bRet = false;
            }
        }
        else
        {
            file_path_buffer_t  sz;
            file_path_buffer_t  szParent;

            // May be being compiled absent exception support, so need to check the
            // file path buffers. (This _could_ be done with a compile-time #ifdef,
            // but it's best not, since some translators support exceptions but yet
            // don't throw on mem exhaustion, and in any case a user could change
            // ::new)
            if( 0 == sz.size() ||
                0 == szParent.size())
            {
                bRet = false;
            }
            else
            {
                traits_t::str_copy(&sz[0], dir);
                traits_t::remove_dir_end(&sz[0]);

                if( traits_t::create_directory(sz.c_str(), mode) ||
                    EEXIST == traits_t::get_last_error())
                {
                    traits_t::set_last_error(0);

                    bRet = true;
                }
                else
                {
                    // Trim previous directory
                    traits_t::str_copy(&szParent[0], sz.c_str());

                    char_type   *pszSlash = find_last_path_name_separator_(szParent.c_str());
                    if(pszSlash == NULL)
                    {
                        traits_t::set_last_error(ENOTDIR);

                        bRet = false;
                    }
                    else
                    {
                        *pszSlash = '\0';   // Will always have enough room for two bytes

                        // If second character is ':', and total lengths is less than four,
                        // or the recurse create fails, then return false;
                        if( (   szParent[1] == ':' &&
                                (traits_t::set_last_error(EACCES), traits_t::str_len(szParent.c_str()) < 4)) ||
                            !create_directory_recurse(szParent.c_str(), mode))
                        {
                            bRet = false;
                        }
                        else
                        {
                            bRet = traits_t::create_directory(sz.c_str(), mode) || EEXIST == traits_t::get_last_error();
                        }
                    }
                }
            }
        }
    }

    return bRet;
}

template<   ss_typename_param_k C
        ,   ss_typename_param_k FD  // This is need because VC++6 cannot deduce filesystem_traits<C>::find_data_type
        >
inline us_int_t remove_directory_recurse_impl(C const* dir, us_int_t (*pfn)(void* param, C const* subDir, FD const* st, struct dirent const* de, int err), void* param)
{
    typedef C                                   char_type;
    typedef filesystem_traits<C>                traits_t;
    typedef basic_file_path_buffer<char_type>   file_path_buffer_t;
    us_int_t                                    dwRet;

    if(NULL != pfn)
    {
        (void)(*pfn)(param, dir, NULL, NULL, ~0);   // Entering
    }

    if( NULL == dir ||
        '\0' == *dir)
    {
        dwRet = ENOTDIR;

        if(NULL != pfn)
        {
            (void)(*pfn)(param, dir, NULL, NULL, dwRet);
        }
    }
    else
    {
        if(!traits_t::file_exists(dir))
        {
            // The given path does not exist, so this is treated as success, but
            // reporting ENOENT

            dwRet = ENOENT;

            if(NULL != pfn)
            {
                (void)(*pfn)(param, dir, NULL, NULL, dwRet);
            }
        }
        else
        {
            if(traits_t::is_file(dir))
            {
                // The given path exists as a file. This is failure
                dwRet = EEXIST;

                if(NULL != pfn)
                {
                    (void)(*pfn)(param, dir, NULL, NULL, dwRet);
                }
            }
            else
            {
                // Otherwise, we attempt to remove it
                if(traits_t::remove_directory(dir))
                {
                    dwRet = 0;

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

                    if(ENOTEMPTY != removeError)
                    {
                        dwRet = removeError;

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

⌨️ 快捷键说明

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