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

📄 findfile_sequence.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 5 页
字号:

    shared_handle   *this_handle    =   m_handle;

    m_handle        =   rhs.m_handle;
    m_data          =   rhs.m_data;
    m_subpath       =   rhs.m_subpath;
    m_subPathLen    =   rhs.m_subPathLen;
    m_pattern0      =   rhs.m_pattern0;
    m_pattern1      =   rhs.m_pattern1;
    m_delim         =   rhs.m_delim;
    m_flags         =   rhs.m_flags;

    if(NULL != m_handle)
    {
        m_handle->AddRef();
    }

    if(NULL != this_handle)
    {
        this_handle->Release();
    }

    return *this;
}

template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
inline basic_findfile_sequence_const_input_iterator<C, T, V>::~basic_findfile_sequence_const_input_iterator() stlsoft_throw_0()
{
    if(NULL != m_handle)
    {
        m_handle->Release();
    }
}

template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
inline ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::class_type &basic_findfile_sequence_const_input_iterator<C, T, V>::operator ++()
{
    // Pre-condition enforcements
    WINSTL_MESSAGE_ASSERT("Attempting to increment an invalid iterator!", '\0' != *m_pattern0);
    WINSTL_ASSERT(NULL != m_pattern0);
    WINSTL_ASSERT(NULL != m_pattern1);

    enum
    {
#ifdef FILE_ATTRIBUTE_REPARSE_POINT
        reparsePointConstant    =   FILE_ATTRIBUTE_REPARSE_POINT
#else /* ? FILE_ATTRIBUTE_REPARSE_POINT */
        reparsePointConstant    =   0x00000400
#endif /* FILE_ATTRIBUTE_REPARSE_POINT */
    };

    STLSOFT_STATIC_ASSERT(reparsePointConstant); // Suppress silly Borland's warnings

    for(; '\0' != *m_pattern0 || '\0' != *m_pattern1;)
    {
        if(NULL == m_handle)
        {
            // Walk through the patterns

            while(stlsoft_ns_qual(find_next_token)(m_pattern0, m_pattern1, m_delim))
            {
                WINSTL_ASSERT(m_pattern0 <= m_pattern1);

                if(m_pattern1 != m_pattern0)    // Will return m_pattern0 == m_pattern1 for empty tokens
                {
                    // We now have a non-empty pattern, so we need to concatenate
                    // it with the directory to form a search-spec for
                    // FindFirstFile()
                    //
                    // From this path we must also determine the sub-path for any items retrieved from
                    // this search, since WIN32_FIND_DATA will contain only the file-name. Since the
                    // sequence is tolerant of both slashes and backslashes, we need to find the last
                    // of each and take the end-most.

                    file_path_buffer_type_  search; // Buffer in which to prepare the search-spec for FindFirstFile()
                    size_type               cch;    // Used to make the strrchr operations faster

                    if(traits_type::is_path_rooted(m_pattern0))
                    {
                        search[0]   =   '\0';
                        cch         =   0;
                    }
                    else
                    {
                        traits_type::str_n_copy(&search[0], m_list->get_directory(), search.size());
                        cch = traits_type::str_len(&search[0]);
                        WINSTL_ASSERT(cch > 0);
                        --cch; // Directory is always trailing a path name separator
                        traits_type::ensure_dir_end(&search[(cch > 1) ? (cch - 2) : 0]);
                    }
                    traits_type::str_n_cat(&search[0] + cch, m_pattern0, static_cast<ws_size_t>(m_pattern1 - m_pattern0));

                    // Note: At this point, cch may be 1 under, because ensure_dir_end() may have added
                    // a character that we've not counted. But that's ok, because we don't use it as an
                    // exact value, just a minimum value

                    char_type const* slash  =   traits_type::str_rchr(&search[0] + cch, '/');
                    char_type const* bslash =   traits_type::str_rchr(&search[0] + cch, '\\');

                    WINSTL_ASSERT(!traits_type::is_path_rooted(m_pattern0) || ((NULL != slash) || (NULL != bslash)));

                    if( NULL != slash &&
                        slash >= m_pattern1)
                    {
                        slash = NULL;
                    }
                    if( NULL != bslash &&
                        bslash >= m_pattern1)
                    {
                        bslash = NULL;
                    }

                    if( NULL != slash ||
                        NULL != bslash)
                    {
                        if(NULL == slash)
                        {
                            slash = bslash;
                        }
                        else if(NULL != bslash &&
                                slash < bslash)
                        {
                            slash = bslash;
                        }

                        const ws_size_t n   =   static_cast<ws_size_t>(slash - &search[0]);

                        traits_type::str_n_copy(&m_subpath[0], &search[0], n);
                        m_subPathLen = n;
                        m_subpath[n] = '\0';
                    }

                    HANDLE  hSrch = find_first_file_(search.c_str(), m_flags, &m_data);

                    if(INVALID_HANDLE_VALUE != hSrch)
                    {
#if defined(STLSOFT_COMPILER_IS_MSVC) && \
    _MSC_VER < 1200
                        stlsoft_ns_qual(scoped_handle)<HANDLE>  cleanup(hSrch, (void (STLSOFT_STDCALL *)(HANDLE))&::FindClose, INVALID_HANDLE_VALUE);
                            
#else /* ? compiler */
                        stlsoft_ns_qual(scoped_handle)<HANDLE>  cleanup(hSrch, ::FindClose, INVALID_HANDLE_VALUE);
#endif /* compiler */

                        // Special case, where the pattern specified is either "." or ".."
                        // the API will return the directory name, but we want to keep the
                        // dot name.
                        if( '.' == m_pattern0[0] &&
                            (   m_pattern1 == m_pattern0 + 1 ||
                                (   '.' == m_pattern0[1] &&
                                    m_pattern1 == m_pattern0 + 2)))
                        {
                            const ws_size_t n   =   static_cast<ws_size_t>(m_pattern1 - m_pattern0);

                            traits_type::str_n_copy(&m_data.cFileName[0], m_pattern0, n);
                            m_data.cFileName[n] = '\0';
                        }

                        m_handle = new shared_handle(hSrch);

                        if(NULL != m_handle)
                        {
                            cleanup.detach();
                        }

                        return *this;
                    }
                    else
                    {
#ifdef _DEBUG
                        DWORD       dwErr   =   ::GetLastError();

                        STLSOFT_SUPPRESS_UNUSED(dwErr);
#endif /* _DEBUG */
                    }
                }
            }
        }

        if(NULL != m_handle)
        {
            for(; INVALID_HANDLE_VALUE != m_handle->hSrch; )
            {
                if(!traits_type::find_next_file(m_handle->hSrch, &m_data))
                {
                    m_handle->Release();

                    m_handle = NULL;

                    break;
                }
                else
                {
                    if( traits_type::is_file(&m_data) &&
                        (   0 == (m_flags & sequence_type::skipHiddenFiles) ||
                            0 == (m_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)))
                    {
                        // A file, and files requested, so break
                        if(m_flags & sequence_type::files)
                        {
                            return *this;
                        }
                    }
                    else
                    {
                        if( 0 == (m_flags & sequence_type::skipHiddenDirs) ||
                            0 == (m_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
                        {
                            if(traits_type::is_dots(m_data.cFileName))
                            {
                                if(m_flags & sequence_type::includeDots)
                                {
                                    // A dots file, and dots are requested
                                    return *this;
                                }
                            }
                            else if(m_flags & sequence_type::directories)
                            {
                                // A directory, and directories requested
                                if( 0 == (m_flags & sequence_type::skipReparseDirs) ||
                                    0 == (m_data.dwFileAttributes & reparsePointConstant))
                                {
                                    // Either not requested to skip reparse points, or not a reparse point
                                    return *this;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return *this;
}

template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
inline ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::class_type basic_findfile_sequence_const_input_iterator<C, T, V>::operator ++(int)
{
    class_type  ret(*this);

    operator ++();

    return ret;
}

template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
inline const ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::value_type basic_findfile_sequence_const_input_iterator<C, T, V>::operator *() const
{
    WINSTL_MESSAGE_ASSERT("Dereferencing end()-valued iterator", NULL != m_handle);

    WINSTL_ASSERT(m_subPathLen == traits_type::str_len(m_subpath.c_str()));

    if(0 == m_subPathLen)
    {
        return value_type(m_data, m_list->get_directory(), traits_type::str_len(m_list->get_directory()));
    }
    else
    {
        return value_type(m_data, m_subpath.c_str(), m_subPathLen);
    }
}

template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
inline ws_bool_t basic_findfile_sequence_const_input_iterator<C, T, V>::equal(basic_findfile_sequence_const_input_iterator<C, T, V> const& rhs) const
{
    // Should only be comparing iterators from same container
    WINSTL_MESSAGE_ASSERT("Comparing iterators from separate sequences", m_list == rhs.m_list || NULL == m_list || NULL == rhs.m_list);

    return m_handle == rhs.m_handle;
}

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

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

#ifndef _WINSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace winstl
# else
} // namespace winstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_WINSTL_NO_NAMESPACE */

/* /////////////////////////////////////////////////////////////////////////
 * Namespace
 *
 * The string access shims exist either in the stlsoft namespace, or in the
 * global namespace. This is required by the lookup rules.
 *
 */

#ifndef _WINSTL_NO_NAMESPACE
# if !defined(_STLSOFT_NO_NAMESPACE) && \
     !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
namespace stlsoft
{
# else /* ? _STLSOFT_NO_NAMESPACE */
/* There is no stlsoft namespace, so must define in the global namespace */
# endif /* !_STLSOFT_NO_NAMESPACE */

using ::winstl::c_str_len;
using ::winstl::c_str_len_a;
using ::winstl::c_str_len_w;

using ::winstl::c_str_data;
using ::winstl::c_str_data_a;
using ::winstl::c_str_data_w;

using ::winstl::c_str_ptr;
using ::winstl::c_str_ptr_a;
using ::winstl::c_str_ptr_w;

using ::winstl::c_str_ptr_null;
using ::winstl::c_str_ptr_null_a;
using ::winstl::c_str_ptr_null_w;

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION

using ::winstl::is_empty;

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

# if !defined(_STLSOFT_NO_NAMESPACE) && \
     !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace stlsoft
# else /* ? _STLSOFT_NO_NAMESPACE */
/* There is no stlsoft namespace, so must define in the global namespace */
# endif /* !_STLSOFT_NO_NAMESPACE */
#endif /* !_WINSTL_NO_NAMESPACE */

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

#endif /* WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FINDFILE_SEQUENCE */

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

⌨️ 快捷键说明

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