Listing 6 findfile_sequence
// Extract from winstl_findfile_sequence.h
template< ws_typename_param_k C
, ws_typename_param_k T = findfile_sequence_traits<C>
>
class basic_findfile_sequence
{
public:
typedef C char_type;
typedef T traits_type;
typedef basic_findfile_sequence<C, T> class_type;
typedef basic_findfile_sequence_value_type<C, T> value_type;
typedef basic_findfile_sequence_const_iterator<C, T, value_type>
const_iterator;
typedef value_type &reference;
typedef value_type const &const_reference;
typedef ws_typename_type_k traits_type::find_data_type
find_data_type;
typedef ws_size_t size_type;
enum
{
includeDots = 0x0008
, directories = 0x0010
, files = 0x0020
};
// Construction
public:
ws_explicit_k basic_findfile_sequence(char_type const *searchSpec,
ws_int_t flags = directories | files);
basic_findfile_sequence(char_type const *directory,
char_type const *searchSpec,
ws_int_t flags = directories | files);
// Iteration
public:
const_iterator begin() const;
const_iterator end() const;
// State
public:
size_type size() const;
ws_bool_t empty() const;
static size_type max_size();
// Members
private:
friend class basic_findfile_sequence_value_type<C, T>;
friend class basic_findfile_sequence_const_iterator<C, T, value_type>;
char_type m_directory[_MAX_DIR + 1];
char_type m_subpath[_MAX_PATH + 1];
char_type m_search[_MAX_PATH + 1];
ws_int_t m_flags;
// Implementation
protected:
static ws_int_t _validate_flags(ws_int_t flags);
static void _extract_subpath(char_type *dest,
char_type const *searchSpec);
HANDLE _begin(find_data_type &findData) const;
// Not to be implemented
private:
basic_findfile_sequence(class_type const &);
basic_findfile_sequence const &operator =(class_type const &);
};
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline HANDLE basic_findfile_sequence<C, T>::
_begin(find_data_type &findData) const
{
HANDLE hSrch = traits_type::find_first_file(m_search, &findData);
if(hSrch != INVALID_HANDLE_VALUE)
{
// Now need to validate against the flags
for(; hSrch != INVALID_HANDLE_VALUE; )
{
if((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
// A file, and files requested, so break
if(m_flags & files)
{
break;
}
}
else
{
if(traits_type::is_dots(findData.cFileName))
{
if(m_flags & includeDots)
{
// A dots file, and dots are requested
break;
}
}
else if(m_flags & directories)
{
// A directory, and directories requested
break;
}
}
if(!traits_type::find_next_file(hSrch, &findData))
{
::FindClose(hSrch);
hSrch = INVALID_HANDLE_VALUE;
break;
}
}
}
return hSrch;
}
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline ws_int_t basic_findfile_sequence<C, T>::
_validate_flags(ws_int_t flags)
{
return (flags & (directories | files)) == 0
? (flags | (directories | files)) : flags;
}
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline void basic_findfile_sequence<C, T>::
_extract_subpath(char_type *dest, char_type const *searchSpec)
{
char_type *pFile;
traits_type::get_full_path_name(searchSpec, _MAX_PATH, dest, &pFile);
if(pFile != 0)
{
*pFile = '\0';
}
}
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline basic_findfile_sequence<C, T>::
basic_findfile_sequence(char_type const *searchSpec,
ws_int_t flags /* = directories | files */)
: m_flags(_validate_flags(flags))
{
m_directory[0] = '\0';
traits_type::str_copy(m_search, searchSpec);
_extract_subpath(m_subpath, searchSpec);
}
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline basic_findfile_sequence::
basic_findfile_sequence(char_type const *directory,
char_type const * searchSpec,
ws_int_t flags /* = directories | files */)
: m_flags(_validate_flags(flags))
{
traits_type::str_copy(m_directory, directory);
traits_type::str_copy(m_search, directory);
traits_type::ensure_dir_end(m_search);
traits_type::str_cat(m_search, searchSpec);
_extract_subpath(m_subpath, m_search);
}
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline ws_typename_type_k const_iterator
basic_findfile_sequence<C, T>::begin() const
{
ws_typename_type_k traits_type::find_data_type findData;
HANDLE hSrch = _begin(findData);
if(hSrch == INVALID_HANDLE_VALUE)
{
return const_iterator(*this);
}
else
{
return const_iterator(*this, hSrch, findData);
}
}
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline ws_typename_type_k const_iterator
basic_findfile_sequence<C, T>::end() const
{
return const_iterator(*this);
}
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline ws_typename_type_k size_type
basic_findfile_sequence<C, T>::size() const
{
const_iterator b = begin();
const_iterator e = end();
size_type c = 0;
for(; begin != end; ++begin)
{
++c;
}
return c;
}
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline ws_bool_t basic_findfile_sequence::empty() const
{
return begin() == end();
}
template< ws_typename_param_k C
, ws_typename_param_k T
>
inline ws_typename_type_k size_type
basic_findfile_sequence<C, T>::max_size()
{
return static_cast<size_type>(-1);
}