📄 findfile_sequence.hpp
字号:
m_subpath[0] = '\0';
}
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(class_type const &rhs)
: m_list(rhs.m_list)
, 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();
}
}
template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
#ifndef STLSOFT_COMPILER_IS_WATCOM
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 =(ss_typename_param_k basic_findfile_sequence_const_input_iterator<C, T, V>::class_type const &rhs)
#else /* ? compiler */
inline basic_findfile_sequence_const_input_iterator<C, T, V> &basic_findfile_sequence_const_input_iterator<C, T, V>::operator =(basic_findfile_sequence_const_input_iterator<C, T, V> const &rhs)
#endif /* compiler */
{
WINSTL_MESSAGE_ASSERT("Assigning iterators from separate sequences", m_list == NULL || rhs.m_list == NULL || rhs.m_list); // Should only be comparing iterators from same container
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<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 size_t n = static_cast<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_(stlsoft_ns_qual(c_str_ptr)(search), m_flags, &m_data);
if(INVALID_HANDLE_VALUE != hSrch)
{
// 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 size_t n = static_cast<size_t>(m_pattern1 - m_pattern0);
traits_type::str_n_copy(&m_data.cFileName[0], m_pattern0, n);
m_data.cFileName[n] = '\0';
}
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
try
{
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
m_handle = new shared_handle(hSrch);
if(NULL == m_handle)
{
::FindClose(hSrch);
}
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
}
catch(...)
{
::FindClose(hSrch);
throw;
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
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>
#ifdef STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED
inline ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::bool_type basic_findfile_sequence_const_input_iterator<C, T, V>::equal(ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::class_type const &rhs) const
#else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
inline ws_bool_t basic_findfile_sequence_const_input_iterator<C, T, V>::equal(class_type const &rhs) const
#endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
{
// 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_NAMESP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -