00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00066 #ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FINDFILE_SEQUENCE
00067 #define WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FINDFILE_SEQUENCE
00068
00069 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00070 # define WINSTL_VER_WINSTL_FILESYSTEM_HPP_FINDFILE_SEQUENCE_MAJOR 4
00071 # define WINSTL_VER_WINSTL_FILESYSTEM_HPP_FINDFILE_SEQUENCE_MINOR 8
00072 # define WINSTL_VER_WINSTL_FILESYSTEM_HPP_FINDFILE_SEQUENCE_REVISION 1
00073 # define WINSTL_VER_WINSTL_FILESYSTEM_HPP_FINDFILE_SEQUENCE_EDIT 216
00074 #endif
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00091 # include <winstl/winstl.h>
00092 #endif
00093
00094 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00095 _MSC_VER < 1100
00096 # error winstl/findfile_sequence.hpp is not compatible with Visual C++ 4.2 or earlier
00097 #endif
00098
00099 #ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
00100 # include <winstl/filesystem/filesystem_traits.hpp>
00101 #endif
00102 #ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER
00103 # include <winstl/filesystem/file_path_buffer.hpp>
00104 #endif
00105 #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_VERSION
00106 # include <winstl/system/system_version.hpp>
00107 #endif
00108 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00109 # ifndef WINSTL_INCL_WINSTL_ERROR_HPP_WINDOWS_EXCEPTIONS
00110 # include <winstl/error/exceptions.hpp>
00111 # endif
00112 #endif
00113 #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
00114 # include <stlsoft/shims/access/string.hpp>
00115 #endif
00116 #ifndef STLSOFT_COMPILER_IS_WATCOM
00117 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00118 # include <stlsoft/util/std/iterator_helper.hpp>
00119 #endif
00120 #endif
00121 #ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SCOPED_HANDLE
00122 # include <stlsoft/smartptr/scoped_handle.hpp>
00123 #endif
00124 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_TOKENISER_FUNCTIONS
00125 # include <stlsoft/string/tokeniser_functions.hpp>
00126 #endif
00127 #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
00128 # include <winstl/memory/processheap_allocator.hpp>
00129 #endif
00130 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00131 # include <stlsoft/collections/util/collections.hpp>
00132 #endif
00133
00134 #ifdef STLSOFT_UNITTEST
00135 # include <winstl/filesystem/current_directory.hpp>
00136 #endif
00137
00138
00139
00140
00141
00142 #ifndef _WINSTL_NO_NAMESPACE
00143 # if defined(_STLSOFT_NO_NAMESPACE) || \
00144 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00145
00146 namespace winstl
00147 {
00148 # else
00149
00150
00151 namespace stlsoft
00152 {
00153
00154 namespace winstl_project
00155 {
00156
00157 # endif
00158 #endif
00159
00160
00161
00162
00163
00164 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00165
00166 template <ss_typename_param_k C, ss_typename_param_k T>
00167 class basic_findfile_sequence_value_type;
00168
00169 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00170 class basic_findfile_sequence_const_input_iterator;
00171
00172 #endif
00173
00174
00175
00176
00177
00178
00191 template< ss_typename_param_k C
00192 #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00193 , ss_typename_param_k T = filesystem_traits<C>
00194 #else
00195 , ss_typename_param_k T
00196 #endif
00197 >
00198 class basic_findfile_sequence
00199 : public stlsoft_ns_qual(stl_collection_tag)
00200 {
00203 public:
00205 typedef C char_type;
00207 typedef T traits_type;
00209 typedef basic_findfile_sequence<C, T> class_type;
00211 typedef basic_findfile_sequence_value_type<C, T> value_type;
00213 typedef basic_findfile_sequence_const_input_iterator<C, T, value_type> const_iterator;
00215 typedef value_type const reference;
00217 typedef value_type const const_reference;
00219 typedef ss_typename_type_k traits_type::find_data_type find_data_type;
00221 typedef ws_ptrdiff_t difference_type;
00223 typedef ws_size_t size_type;
00225 typedef ws_bool_t bool_type;
00227 typedef int flags_type;
00228 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00229
00230 typedef const_iterator const_input_iterator;
00231 #endif
00233
00236 public:
00237 enum search_flags
00238 {
00239 includeDots = 0x0008
00240 , directories = 0x0010
00241 , files = 0x0020
00242 , skipReparseDirs = 0x0100
00243 , skipHiddenFiles = 0x0200
00244 , skipHiddenDirs = 0x0400
00245 , relativePath = 0x0800
00246 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00247 , throwOnAccessFailure = 0x2000
00248 #endif
00249 };
00251
00254 public:
00256 ss_explicit_k basic_findfile_sequence( char_type const* pattern
00257 , flags_type flags = directories | files);
00259 basic_findfile_sequence(char_type const* patterns
00260 , char_type delim
00261 , flags_type flags = directories | files);
00263 basic_findfile_sequence(char_type const* directory
00264 , char_type const* pattern
00265 , flags_type flags = directories | files);
00267 basic_findfile_sequence(char_type const* directory
00268 , char_type const* patterns
00269 , char_type delim
00270 , flags_type flags = directories | files);
00272 ~basic_findfile_sequence() stlsoft_throw_0();
00274
00277 public:
00281 const_iterator begin() const;
00285 const_iterator end() const;
00287
00290 public:
00294 char_type const* get_directory(size_type* plen = NULL) const;
00296
00299 public:
00301 ws_bool_t empty() const;
00303 static size_type max_size();
00305
00308 private:
00309 typedef basic_file_path_buffer<char_type> file_path_buffer_type_;
00310 typedef stlsoft_ns_qual(auto_buffer_old)< char_type
00311 , processheap_allocator<char_type>
00312 , 64
00313 > patterns_buffer_type_;
00314
00315 const char_type m_delim;
00316 const flags_type m_flags;
00317 file_path_buffer_type_ m_directory;
00318 patterns_buffer_type_ m_patterns;
00319 const size_type m_directoryLen;
00321
00324 private:
00325 ws_bool_t is_valid() const;
00327
00330 private:
00331 static flags_type validate_flags_(flags_type flags);
00332 static size_type validate_directory_(char_type const* directory, file_path_buffer_type_& dir, flags_type flags);
00334
00337 private:
00338 basic_findfile_sequence(class_type const&);
00339 class_type& operator =(class_type const&);
00341 };
00342
00343
00344
00345
00346
00351 typedef basic_findfile_sequence<ws_char_a_t, filesystem_traits<ws_char_a_t> > findfile_sequence_a;
00356 typedef basic_findfile_sequence<ws_char_w_t, filesystem_traits<ws_char_w_t> > findfile_sequence_w;
00361 typedef basic_findfile_sequence<TCHAR, filesystem_traits<TCHAR> > findfile_sequence;
00362
00363
00364
00365
00370 template< ss_typename_param_k C
00371 , ss_typename_param_k T
00372 >
00373 class basic_findfile_sequence_value_type
00374 {
00377 private:
00378 typedef basic_findfile_sequence<C, T> sequence_type;
00379 public:
00381 typedef C char_type;
00383 typedef T traits_type;
00385 typedef basic_findfile_sequence_value_type<C, T> class_type;
00387 typedef ss_typename_type_k traits_type::find_data_type find_data_type;
00389 typedef ss_typename_type_k sequence_type::size_type size_type;
00390 private:
00391 typedef ss_typename_type_k sequence_type::bool_type bool_type;
00392 typedef ss_typename_type_k sequence_type::flags_type flags_type;
00394
00397 public:
00399 basic_findfile_sequence_value_type();
00400 private:
00401 basic_findfile_sequence_value_type(find_data_type const& data, char_type const* directory, size_type cchDirectory)
00402 : m_data(data)
00403 {
00404 WINSTL_ASSERT(NULL != directory);
00405 WINSTL_ASSERT(0 != cchDirectory);
00406
00407 const size_type cchFilename = traits_type::str_len(data.cFileName);
00408
00409 traits_type::char_copy(&m_path[0], directory, cchDirectory);
00410 m_path[cchDirectory] = '\0';
00411 if(!traits_type::has_dir_end(&m_path[0]))
00412 {
00413 traits_type::ensure_dir_end(&m_path[0] + (cchDirectory - 1));
00414 ++cchDirectory;
00415 }
00416 traits_type::char_copy(&m_path[0] + cchDirectory, data.cFileName, cchFilename);
00417 m_path[cchDirectory + cchFilename] = '\0';
00418 m_pathLen = cchDirectory + cchFilename;
00419
00420 WINSTL_ASSERT(traits_type::str_len(m_path.c_str()) == m_pathLen);
00421 }
00422 public:
00424 class_type& operator =(class_type const& rhs);
00426
00429 public:
00431 find_data_type const& get_find_data() const;
00432 #ifdef STLSOFT_OBSOLETE
00436 find_data_type const& GetFindData() const; // Deprecated
00437 #endif
00438
00440 char_type const* get_filename() const;
00442 char_type const* get_short_filename() const;
00447 char_type const* get_path() const;
00452 char_type const* c_str() const;
00454 ws_size_t length() const;
00455
00463 operator char_type const* () const;
00464
00466 ws_bool_t is_directory() const;
00468 ws_bool_t is_file() const;
00470 ws_bool_t is_compressed() const;
00471 #ifdef FILE_ATTRIBUTE_REPARSE_POINT
00473 ws_bool_t is_reparse_point() const;
00474 #endif
00476 ws_bool_t is_read_only() const;
00478 ws_bool_t is_system() const;
00480 ws_bool_t is_hidden() const;
00482
00485 public:
00487 ws_bool_t equal(char_type const* rhs) const;
00489 ws_bool_t equal(class_type const& rhs) const;
00491
00494 private:
00495 friend class basic_findfile_sequence_const_input_iterator<C, T, class_type>;
00496
00497 typedef basic_file_path_buffer<char_type> file_path_buffer_type_;
00498
00499 find_data_type m_data;
00500 file_path_buffer_type_ m_path;
00501 size_type m_pathLen;
00503 };
00504
00505
00510 template< ss_typename_param_k C
00511 , ss_typename_param_k T
00512 , ss_typename_param_k V
00513 >
00514 class basic_findfile_sequence_const_input_iterator
00515 #ifndef STLSOFT_COMPILER_IS_WATCOM
00516 : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(input_iterator_tag)
00517 , V
00518 , ws_ptrdiff_t
00519 , void
00520 , V
00521 >
00522 #endif
00523 {
00526 private:
00527 typedef basic_findfile_sequence<C, T> sequence_type;
00528 public:
00530 typedef C char_type;
00532 typedef T traits_type;
00534 typedef V value_type;
00536 typedef basic_findfile_sequence_const_input_iterator<C, T, V> class_type;
00538 typedef ss_typename_type_k traits_type::find_data_type find_data_type;
00540 typedef ss_typename_type_k sequence_type::size_type size_type;
00541 private:
00542 typedef ss_typename_type_k sequence_type::bool_type bool_type;
00543 typedef ss_typename_type_k sequence_type::flags_type flags_type;
00545
00548 private:
00549 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00550 struct shared_handle
00551 {
00554 public:
00555 typedef shared_handle class_type;
00556 typedef HANDLE handle_type;
00558
00561 public:
00562 handle_type hSrch;
00563 private:
00564 ss_sint32_t m_refCount;
00566
00569 public:
00570 ss_explicit_k shared_handle(handle_type h)
00571 : hSrch(h)
00572 , m_refCount(1)
00573 {}
00574 # if defined(STLSOFT_CF_COMPILER_WARNS_NO_PUBLIC_DTOR)
00575 protected:
00576 # else
00577 private:
00578 # endif
00579 ~shared_handle() stlsoft_throw_0()
00580 {
00581 WINSTL_MESSAGE_ASSERT("Shared search handle being destroyed with outstanding references!", 0 == m_refCount);
00582
00583 if(INVALID_HANDLE_VALUE != hSrch)
00584 {
00585 traits_type::find_file_close(hSrch);
00586 }
00587 }
00589
00592 public:
00593 ss_sint32_t AddRef()
00594 {
00595 return ++m_refCount;
00596 }
00597 ss_sint32_t Release()
00598 {
00599 ss_sint32_t rc = --m_refCount;
00600
00601 if(0 == rc)
00602 {
00603 delete this;
00604 }
00605
00606 return rc;
00607 }
00609
00612 private:
00613 shared_handle(class_type const&);
00614 class_type& operator =(class_type const&);
00616 };
00617 #endif
00619
00622 private:
00623 basic_findfile_sequence_const_input_iterator( sequence_type const& l
00624 , char_type const* patterns
00625 , char_type delim
00626 , flags_type flags);
00627 basic_findfile_sequence_const_input_iterator(sequence_type const& l);
00628 public:
00630 basic_findfile_sequence_const_input_iterator();
00632 basic_findfile_sequence_const_input_iterator(class_type const& rhs);
00634 ~basic_findfile_sequence_const_input_iterator() stlsoft_throw_0();
00635
00636
00637 basic_findfile_sequence_const_input_iterator& operator =(class_type const& rhs);
00639
00642 public:
00644 class_type& operator ++();
00646 class_type operator ++(int);
00648 const value_type operator *() const;
00650 ws_bool_t equal(class_type const& rhs) const;
00652
00655 private:
00656 static HANDLE find_first_file_(char_type const* spec, flags_type flags, find_data_type *findData);
00658
00661 private:
00662 friend class basic_findfile_sequence<C, T>;
00663
00664 typedef basic_file_path_buffer<char_type> file_path_buffer_type_;
00665
00666 sequence_type const* const m_list;
00667 shared_handle* m_handle;
00668 ss_typename_type_k traits_type::find_data_type m_data;
00669 file_path_buffer_type_ m_subpath;
00670 size_type m_subPathLen;
00671 char_type const* m_pattern0;
00672 char_type const* m_pattern1;
00673 char_type m_delim;
00674 flags_type m_flags;
00676 };
00677
00679
00680
00681
00682
00683 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00684 inline ws_bool_t operator ==( basic_findfile_sequence_const_input_iterator<C, T, V> const& lhs
00685 , basic_findfile_sequence_const_input_iterator<C, T, V> const& rhs)
00686 {
00687 return lhs.equal(rhs);
00688 }
00689
00690 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00691 inline ws_bool_t operator !=( basic_findfile_sequence_const_input_iterator<C, T, V> const& lhs
00692 , basic_findfile_sequence_const_input_iterator<C, T, V> const& rhs)
00693 {
00694 return !lhs.equal(rhs);
00695 }
00696
00697
00698
00699 template <ss_typename_param_k C, ss_typename_param_k T>
00700 inline ws_bool_t operator == ( basic_findfile_sequence_value_type<C, T> const& lhs
00701 , basic_findfile_sequence_value_type<C, T> const& rhs)
00702 {
00703 return lhs.equal(rhs);
00704 }
00705
00706 template <ss_typename_param_k C, ss_typename_param_k T>
00707 inline ws_bool_t operator == ( basic_findfile_sequence_value_type<C, T> const& lhs
00708 , C const* rhs)
00709 {
00710 return lhs.equal(rhs);
00711 }
00712
00713 template <ss_typename_param_k C, ss_typename_param_k T>
00714 inline ws_bool_t operator == (C const* lhs, basic_findfile_sequence_value_type<C, T> const& rhs)
00715 {
00716 return rhs.equal(lhs);
00717 }
00718
00719 template <ss_typename_param_k C, ss_typename_param_k T>
00720 inline ws_bool_t operator != ( basic_findfile_sequence_value_type<C, T> const& lhs
00721 , basic_findfile_sequence_value_type<C, T> const& rhs)
00722 {
00723 return !lhs.equal(rhs);
00724 }
00725
00726 template <ss_typename_param_k C, ss_typename_param_k T>
00727 inline ws_bool_t operator != ( basic_findfile_sequence_value_type<C, T> const& lhs
00728 , C const* rhs)
00729 {
00730 return !lhs.equal(rhs);
00731 }
00732
00733 template <ss_typename_param_k C, ss_typename_param_k T>
00734 inline ws_bool_t operator != (C const* lhs, basic_findfile_sequence_value_type<C, T> const& rhs)
00735 {
00736 return !rhs.equal(lhs);
00737 }
00738
00739
00740
00741
00742
00743 template <ss_typename_param_k S, ss_typename_param_k C, ss_typename_param_k T>
00744 inline S& operator <<(S& s, basic_findfile_sequence_value_type<C, T> const& value)
00745 {
00746 s << value.get_path();
00747
00748 return s;
00749 }
00750
00752
00753
00754
00755
00756 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00757
00758 template <ss_typename_param_k T>
00759 inline ws_char_a_t const* c_str_data_a(winstl_ns_qual(basic_findfile_sequence_value_type)<ws_char_a_t, T> const& v)
00760 {
00761 return v.get_path();
00762 }
00763 template <ss_typename_param_k T>
00764 inline ws_char_w_t const* c_str_data_w(winstl_ns_qual(basic_findfile_sequence_value_type)<ws_char_w_t, T> const& v)
00765 {
00766 return v.get_path();
00767 }
00768
00769 #endif
00770
00775 template <ss_typename_param_k C, ss_typename_param_k T>
00776 inline C const* c_str_data(winstl_ns_qual(basic_findfile_sequence_value_type)<C, T> const& v)
00777 {
00778 return v.get_path();
00779 }
00780
00781
00782
00783 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00784
00785 template <ss_typename_param_k T>
00786 inline ws_size_t c_str_len_a(winstl_ns_qual(basic_findfile_sequence_value_type)<ws_char_a_t, T> const& v)
00787 {
00788 return v.length();
00789 }
00790 template <ss_typename_param_k T>
00791 inline ws_size_t c_str_len_w(winstl_ns_qual(basic_findfile_sequence_value_type)<ws_char_w_t, T> const& v)
00792 {
00793 return v.length();
00794 }
00795
00796 #endif
00797
00802 template <ss_typename_param_k C, ss_typename_param_k T>
00803 inline ws_size_t c_str_len(winstl_ns_qual(basic_findfile_sequence_value_type)<C, T> const& v)
00804 {
00805 return v.length();
00806 }
00807
00808
00809
00810 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00811
00812 template <ss_typename_param_k T>
00813 inline ws_char_a_t const* c_str_ptr_a(winstl_ns_qual(basic_findfile_sequence_value_type)<ws_char_a_t, T> const& v)
00814 {
00815 return v.get_path();
00816 }
00817 template <ss_typename_param_k T>
00818 inline ws_char_w_t const* c_str_ptr_w(winstl_ns_qual(basic_findfile_sequence_value_type)<ws_char_w_t, T> const& v)
00819 {
00820 return v.get_path();
00821 }
00822
00823 #endif
00824
00829 template <ss_typename_param_k C, ss_typename_param_k T>
00830 inline C const* c_str_ptr(winstl_ns_qual(basic_findfile_sequence_value_type)<C, T> const& v)
00831 {
00832 return v.get_path();
00833 }
00834
00835
00836
00837 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00838
00839 template <ss_typename_param_k T>
00840 inline ws_char_a_t const* c_str_ptr_null_a(winstl_ns_qual(basic_findfile_sequence_value_type)<ws_char_a_t, T> const& v)
00841 {
00842 return stlsoft_ns_qual(c_str_ptr_null_a(v.get_path()));
00843 }
00844 template <ss_typename_param_k T>
00845 inline ws_char_w_t const* c_str_ptr_null_w(winstl_ns_qual(basic_findfile_sequence_value_type)<ws_char_w_t, T> const& v)
00846 {
00847 return stlsoft_ns_qual(c_str_ptr_null_w(v.get_path()));
00848 }
00849
00850 #endif
00851
00856 template <ss_typename_param_k C, ss_typename_param_k T>
00857 inline C const* c_str_ptr_null(winstl_ns_qual(basic_findfile_sequence_value_type)<C, T> const& v)
00858 {
00859 return stlsoft_ns_qual(c_str_ptr_null(v.get_path()));
00860 }
00861
00862
00863
00864
00865
00866 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00867
00868 template <ss_typename_param_k C, ss_typename_param_k T>
00869 inline ws_bool_t is_empty(basic_findfile_sequence<C, T> const& s)
00870 {
00871 return s.empty();
00872 }
00873
00874 #endif
00875
00877
00878
00879 #ifdef STLSOFT_UNITTEST
00880 # include "./unittest/findfile_sequence_unittest_.h"
00881 #endif
00882
00884
00885
00886 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00887
00888
00889
00890 template <ss_typename_param_k C, ss_typename_param_k T>
00891 inline ss_typename_type_ret_k basic_findfile_sequence<C, T>::flags_type basic_findfile_sequence<C, T>::validate_flags_(ss_typename_type_k basic_findfile_sequence<C, T>::flags_type flags)
00892 {
00893 const flags_type validFlags = 0
00894 | includeDots
00895 | directories
00896 | files
00897 | skipReparseDirs
00898 | skipHiddenFiles
00899 | skipHiddenDirs
00900 | relativePath
00901 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00902 | throwOnAccessFailure
00903 #endif
00904 | 0;
00905
00906 WINSTL_MESSAGE_ASSERT("Specification of unrecognised/unsupported flags", flags == (flags & validFlags));
00907 STLSOFT_SUPPRESS_UNUSED(validFlags);
00908
00909 if(0 == (flags & (directories | files)))
00910 {
00911 flags |= (directories | files);
00912 }
00913
00914 return flags;
00915 }
00916
00917 template <ss_typename_param_k C, ss_typename_param_k T>
00918 inline ws_bool_t basic_findfile_sequence<C, T>::is_valid() const
00919 {
00920 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00921 if('\0' == m_directory[0])
00922 {
00923 # ifdef STLSOFT_UNITTEST
00924 fprintf(err, "m_directory is empty when exception handling is enabled\n");
00925 # endif
00926
00927 return false;
00928 }
00929 #endif
00930
00931
00932 if( '\0' != m_directory[0] &&
00933 !traits_type::has_dir_end(m_directory.c_str()))
00934 {
00935 #ifdef STLSOFT_UNITTEST
00936 fprintf(err, "m_directory is not empty and does not have a trailing path name separator; m_directory=%s\n", m_directory.c_str());
00937 #endif
00938
00939 return false;
00940 }
00941
00942 if(m_directoryLen != traits_type::str_len(m_directory.c_str()))
00943 {
00944 #ifdef STLSOFT_UNITTEST
00945 fprintf(err, "m_directory is not length indicated by m_directoryLen; m_directory=%s; m_directoryLen=%d\n", m_directory.c_str(), int(m_directoryLen));
00946 #endif
00947
00948 return false;
00949 }
00950
00951 return true;
00952 }
00953
00954 template <ss_typename_param_k C, ss_typename_param_k T>
00955 inline ss_typename_type_ret_k basic_findfile_sequence<C, T>::size_type
00956 basic_findfile_sequence<C, T>::validate_directory_(
00957 char_type const* directory
00958 , file_path_buffer_type_& dir
00959 , flags_type flags
00960 )
00961 {
00962 if( NULL == directory ||
00963 '\0' == *directory)
00964 {
00965 static const char_type s_cwd[] = { '.', '\0' };
00966
00967 directory = &s_cwd[0];
00968 }
00969
00970 size_type directoryLen = traits_type::str_len(directory);
00971
00972 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00973 if(directoryLen > dir.size())
00974 {
00975 # ifndef CO_E_PATHTOOLONG
00976 enum { CO_E_PATHTOOLONG = int(0x80040212L) };
00977 # endif
00978
00979 STLSOFT_THROW_X(windows_exception(static_cast<windows_exception::error_code_type>(CO_E_PATHTOOLONG)));
00980 }
00981 #endif
00982
00983 if(relativePath & flags)
00984 {
00985 WINSTL_ASSERT(directoryLen < dir.size());
00986
00987 traits_type::char_copy(&dir[0], directory, directoryLen + 1);
00988 }
00989 else if(0 == (directoryLen = traits_type::get_full_path_name(directory, dir.size(), &dir[0])))
00990 {
00991 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00992 STLSOFT_THROW_X(windows_exception(::GetLastError()));
00993 #else
00994 return validate_directory_(directory, dir, flags | relativePath);
00995 #endif
00996 }
00997
00998 WINSTL_ASSERT(directoryLen == traits_type::str_len(dir.c_str()));
00999
01000 if( 0u != directoryLen &&
01001 !traits_type::has_dir_end(&dir[directoryLen - 1]))
01002 {
01003 traits_type::ensure_dir_end(&dir[directoryLen - 1]);
01004 ++directoryLen;
01005 }
01006
01007 WINSTL_ASSERT(directoryLen == traits_type::str_len(dir.c_str()));
01008
01009 return directoryLen;
01010 }
01011
01012
01013 template <ss_typename_param_k C, ss_typename_param_k T>
01014 inline basic_findfile_sequence<C, T>::basic_findfile_sequence(char_type const* pattern, flags_type flags )
01015 : m_delim(0)
01016 , m_flags(validate_flags_(flags))
01017 , m_directory()
01018 , m_patterns(1 + traits_type::str_len(pattern))
01019 , m_directoryLen(validate_directory_(NULL, m_directory, m_flags))
01020 {
01021 traits_type::char_copy(&m_patterns[0], pattern, m_patterns.size());
01022
01023 WINSTL_ASSERT(is_valid());
01024 }
01025
01026 template <ss_typename_param_k C, ss_typename_param_k T>
01027 inline basic_findfile_sequence<C, T>::basic_findfile_sequence( char_type const* patterns
01028 , char_type delim
01029 , flags_type flags )
01030 : m_delim(delim)
01031 , m_flags(validate_flags_(flags))
01032 , m_directory()
01033 , m_patterns(1 + traits_type::str_len(patterns))
01034 , m_directoryLen(validate_directory_(NULL, m_directory, m_flags))
01035 {
01036 traits_type::char_copy(&m_patterns[0], patterns, m_patterns.size());
01037
01038 WINSTL_ASSERT(is_valid());
01039 }
01040
01041 template <ss_typename_param_k C, ss_typename_param_k T>
01042 inline basic_findfile_sequence<C, T>::basic_findfile_sequence( char_type const* directory
01043 , char_type const* pattern
01044 , flags_type flags )
01045 : m_delim(0)
01046 , m_flags(validate_flags_(flags))
01047 , m_directory()
01048 , m_patterns(1 + traits_type::str_len(pattern))
01049 , m_directoryLen(validate_directory_(directory, m_directory, m_flags))
01050 {
01051 traits_type::char_copy(&m_patterns[0], pattern, m_patterns.size());
01052
01053 WINSTL_ASSERT(is_valid());
01054 }
01055
01056 template <ss_typename_param_k C, ss_typename_param_k T>
01057 inline basic_findfile_sequence<C, T>::basic_findfile_sequence( char_type const* directory
01058 , char_type const* patterns
01059 , char_type delim
01060 , flags_type flags )
01061 : m_delim(delim)
01062 , m_flags(validate_flags_(flags))
01063 , m_directory()
01064 , m_patterns(1 + traits_type::str_len(patterns))
01065 , m_directoryLen(validate_directory_(directory, m_directory, m_flags))
01066 {
01067 traits_type::char_copy(&m_patterns[0], patterns, m_patterns.size());
01068
01069 WINSTL_ASSERT(is_valid());
01070 }
01071
01072 template <ss_typename_param_k C, ss_typename_param_k T>
01073 inline basic_findfile_sequence<C, T>::~basic_findfile_sequence() stlsoft_throw_0()
01074 {
01075 WINSTL_ASSERT(is_valid());
01076
01077 #ifdef _DEBUG
01078 m_directory[0] = '\0';
01079 m_patterns[0] = '\0';
01080 #endif
01081 }
01082
01083
01084 template <ss_typename_param_k C, ss_typename_param_k T>
01085 inline ss_typename_type_ret_k basic_findfile_sequence<C, T>::const_iterator basic_findfile_sequence<C, T>::begin() const
01086 {
01087 WINSTL_ASSERT(is_valid());
01088
01089 #ifndef STLSOFT_CF_EXCEPTION_SUPPORT
01090 if('\0' == m_directory[0])
01091 {
01092 ::SetLastError(ERROR_INVALID_NAME);
01093
01094 return const_iterator(*this);
01095 }
01096 #endif
01097
01098 return const_iterator(*this, m_patterns.data(), m_delim, m_flags);
01099 }
01100
01101 template <ss_typename_param_k C, ss_typename_param_k T>
01102 inline ss_typename_type_ret_k basic_findfile_sequence<C, T>::const_iterator basic_findfile_sequence<C, T>::end() const
01103 {
01104 WINSTL_ASSERT(is_valid());
01105
01106 return const_iterator(*this);
01107 }
01108
01109
01110 template <ss_typename_param_k C, ss_typename_param_k T>
01111 ss_typename_type_k basic_findfile_sequence<C, T>::char_type const* basic_findfile_sequence<C, T>::get_directory(size_type* plen ) const
01112 {
01113 WINSTL_ASSERT(is_valid());
01114
01115
01116 size_type len_;
01117
01118 if(NULL == plen)
01119 {
01120 plen = &len_;
01121 }
01122
01123 *plen = m_directoryLen;
01124
01125 return m_directory.c_str();
01126 }
01127
01128
01129
01130 template <ss_typename_param_k C, ss_typename_param_k T>
01131 inline ws_bool_t basic_findfile_sequence<C, T>::empty() const
01132 {
01133 WINSTL_ASSERT(is_valid());
01134
01135 return begin() == end();
01136 }
01137
01138 template <ss_typename_param_k C, ss_typename_param_k T>
01139 inline ss_typename_type_ret_k basic_findfile_sequence<C, T>::size_type
01140 basic_findfile_sequence<C, T>::max_size()
01141 {
01142 return static_cast<size_type>(-1);
01143 }
01144
01145
01146
01147 template <ss_typename_param_k C, ss_typename_param_k T>
01148 inline basic_findfile_sequence_value_type<C, T>::basic_findfile_sequence_value_type()
01149 {
01150 m_data.dwFileAttributes = 0xFFFFFFFF;
01151 m_data.cFileName[0] = '\0';
01152 m_data.cAlternateFileName[0] = '\0';
01153 m_path[0] = '\0';
01154 m_pathLen = 0;
01155 }
01156
01157 template <ss_typename_param_k C, ss_typename_param_k T>
01158 inline ss_typename_type_ret_k basic_findfile_sequence_value_type<C, T>::class_type& basic_findfile_sequence_value_type<C, T>::operator =(ss_typename_type_k basic_findfile_sequence_value_type<C, T>::class_type const& rhs)
01159 {
01160 m_data = rhs.m_data;
01161 m_path = rhs.m_path;
01162 m_pathLen = rhs.m_pathLen;
01163
01164 return *this;
01165 }
01166
01167 template <ss_typename_param_k C, ss_typename_param_k T>
01168 inline ss_typename_type_ret_k basic_findfile_sequence_value_type<C, T>::find_data_type const& basic_findfile_sequence_value_type<C, T>::get_find_data() const
01169 {
01170 return m_data;
01171 }
01172
01173 #ifdef STLSOFT_OBSOLETE
01174 template <ss_typename_param_k C, ss_typename_param_k T>
01175 inline ss_typename_type_ret_k basic_findfile_sequence_value_type<C, T>::find_data_type const& basic_findfile_sequence_value_type<C, T>::GetFindData() const
01176 {
01177 return get_find_data();
01178 }
01179 #endif
01180
01181 template <ss_typename_param_k C, ss_typename_param_k T>
01182 inline ss_typename_type_ret_k basic_findfile_sequence_value_type<C, T>::char_type const* basic_findfile_sequence_value_type<C, T>::get_filename() const
01183 {
01184 return m_data.cFileName;
01185 }
01186
01187 template <ss_typename_param_k C, ss_typename_param_k T>
01188 inline ss_typename_type_ret_k basic_findfile_sequence_value_type<C, T>::char_type const* basic_findfile_sequence_value_type<C, T>::get_short_filename() const
01189 {
01190 return m_data.cAlternateFileName[0] != '\0' ? m_data.cAlternateFileName : m_data.cFileName;
01191 }
01192
01193 template <ss_typename_param_k C, ss_typename_param_k T>
01194 inline ss_typename_type_ret_k basic_findfile_sequence_value_type<C, T>::char_type const* basic_findfile_sequence_value_type<C, T>::get_path() const
01195 {
01196 return m_path.c_str();
01197 }
01198
01199 template <ss_typename_param_k C, ss_typename_param_k T>
01200 inline ss_typename_type_ret_k basic_findfile_sequence_value_type<C, T>::char_type const* basic_findfile_sequence_value_type<C, T>::c_str() const
01201 {
01202 return get_path();
01203 }
01204
01205 template <ss_typename_param_k C, ss_typename_param_k T>
01206 inline ws_size_t
01207 basic_findfile_sequence_value_type<C, T>::length() const
01208 {
01209 WINSTL_ASSERT(traits_type::str_len(this->c_str()) == m_pathLen);
01210
01211 return m_pathLen;
01212 }
01213
01214 template <ss_typename_param_k C, ss_typename_param_k T>
01215 #if defined(STLSOFT_COMPILER_IS_GCC) || \
01216 ( defined(STLSOFT_COMPILER_IS_MSVC) && \
01217 _MSC_VER < 1100)
01218 inline basic_findfile_sequence_value_type<C, T>::operator C const* () const
01219 #else
01220 inline basic_findfile_sequence_value_type<C, T>::operator ss_typename_type_k basic_findfile_sequence_value_type<C, T>::char_type const* () const
01221 #endif
01222 {
01223 return get_path();
01224 }
01225
01226 template <ss_typename_param_k C, ss_typename_param_k T>
01227 inline ws_bool_t basic_findfile_sequence_value_type<C, T>::is_directory() const
01228 {
01229 return traits_type::is_directory(&m_data);
01230 }
01231 template <ss_typename_param_k C, ss_typename_param_k T>
01232 inline ws_bool_t basic_findfile_sequence_value_type<C, T>::is_file() const
01233 {
01234 return traits_type::is_file(&m_data);
01235 }
01236 template <ss_typename_param_k C, ss_typename_param_k T>
01237 inline ws_bool_t basic_findfile_sequence_value_type<C, T>::is_compressed() const
01238 {
01239 return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED);
01240 }
01241 #ifdef FILE_ATTRIBUTE_REPARSE_POINT
01242 template <ss_typename_param_k C, ss_typename_param_k T>
01243 inline ws_bool_t basic_findfile_sequence_value_type<C, T>::is_reparse_point() const
01244 {
01245 return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT);
01246 }
01247 #endif
01248 template <ss_typename_param_k C, ss_typename_param_k T>
01249 inline ws_bool_t basic_findfile_sequence_value_type<C, T>::is_read_only() const
01250 {
01251 return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_READONLY);
01252 }
01253 template <ss_typename_param_k C, ss_typename_param_k T>
01254 inline ws_bool_t basic_findfile_sequence_value_type<C, T>::is_system() const
01255 {
01256 return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM);
01257 }
01258 template <ss_typename_param_k C, ss_typename_param_k T>
01259 inline ws_bool_t basic_findfile_sequence_value_type<C, T>::is_hidden() const
01260 {
01261 return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN);
01262 }
01263
01264 template <ss_typename_param_k C, ss_typename_param_k T>
01265 inline ws_bool_t basic_findfile_sequence_value_type<C, T>::equal(char_type const* rhs) const
01266 {
01267 return 0 == traits_type::str_compare_no_case(this->get_path(), rhs);
01268 }
01269
01270 template <ss_typename_param_k C, ss_typename_param_k T>
01271 inline ws_bool_t basic_findfile_sequence_value_type<C, T>::equal(basic_findfile_sequence_value_type<C, T> const& rhs) const
01272 {
01273 return equal(rhs.get_path());
01274 }
01275
01276
01277
01278 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01279 inline HANDLE basic_findfile_sequence_const_input_iterator<C, T, V>::find_first_file_(
01280 ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::char_type const* searchSpec
01281 , flags_type flags
01282 , ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::find_data_type* findData
01283 )
01284 {
01285 HANDLE hSrch = INVALID_HANDLE_VALUE;
01286
01287
01288
01289
01290 enum
01291 {
01292 #ifdef FILE_ATTRIBUTE_REPARSE_POINT
01293 reparsePointConstant = FILE_ATTRIBUTE_REPARSE_POINT
01294 #else
01295 reparsePointConstant = 0x00000400
01296 #endif
01297 };
01298
01299 #if defined(_WIN32_WINNT) && \
01300 _WIN32_WINNT >= 0x0400
01301 if( (sequence_type::directories == (flags & (sequence_type::directories | sequence_type::files))) &&
01302 system_version::winnt() &&
01303 system_version::major() >= 4)
01304 {
01305 hSrch = traits_type::find_first_file_ex(searchSpec, FindExSearchLimitToDirectories, findData);
01306 }
01307 else
01308 #endif
01309
01310 if(INVALID_HANDLE_VALUE == hSrch)
01311 {
01312 hSrch = traits_type::find_first_file(searchSpec, findData);
01313 }
01314
01315 if(INVALID_HANDLE_VALUE == hSrch)
01316 {
01317 DWORD dw = ::GetLastError();
01318
01319 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01320 if(ERROR_ACCESS_DENIED == dw)
01321 {
01322 if(flags & sequence_type::throwOnAccessFailure)
01323 {
01324 STLSOFT_THROW_X(access_exception(dw));
01325 }
01326 }
01327 #endif
01328 }
01329
01330
01331 for(; INVALID_HANDLE_VALUE != hSrch; )
01332 {
01333 if( traits_type::is_file(findData) &&
01334 ( 0 == (flags & sequence_type::skipHiddenFiles) ||
01335 0 == (findData->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)))
01336 {
01337
01338 if(flags & sequence_type::files)
01339 {
01340 break;
01341 }
01342 }
01343 else
01344 {
01345 if( 0 == (flags & sequence_type::skipHiddenDirs) ||
01346 0 == (findData->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
01347 {
01348 if(traits_type::is_dots(findData->cFileName))
01349 {
01350 if(flags & sequence_type::includeDots)
01351 {
01352
01353 break;
01354 }
01355 }
01356 else if(flags & sequence_type::directories)
01357 {
01358
01359 if( 0 == (flags & sequence_type::skipReparseDirs) ||
01360 0 == (findData->dwFileAttributes & reparsePointConstant))
01361 {
01362
01363 break;
01364 }
01365 }
01366 }
01367 }
01368
01369 if(!traits_type::find_next_file(hSrch, findData))
01370 {
01371 ::FindClose(hSrch);
01372
01373 hSrch = INVALID_HANDLE_VALUE;
01374
01375 break;
01376 }
01377 }
01378
01379 return hSrch;
01380 }
01381
01382 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01383 inline basic_findfile_sequence_const_input_iterator<C, T, V>::basic_findfile_sequence_const_input_iterator()
01384 : m_list(NULL)
01385 , m_handle(NULL)
01386 , m_subpath()
01387 , m_subPathLen(0)
01388 , m_pattern0(NULL)
01389 , m_pattern1(NULL)
01390 , m_delim('\0')
01391 , m_flags(0)
01392 {
01393 m_subpath[0] = '\0';
01394 }
01395
01396 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01397 inline basic_findfile_sequence_const_input_iterator<C, T, V>::basic_findfile_sequence_const_input_iterator(
01398 sequence_type const& l
01399 #if 0
01400 , ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::char_type const* rootDir
01401 #endif
01402 , ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::char_type const* patterns
01403 , ss_typename_type_k basic_findfile_sequence_const_input_iterator<C, T, V>::char_type delim
01404 , flags_type flags
01405 )
01406 : m_list(&l)
01407 , m_handle(NULL)
01408 , m_subpath()
01409 , m_subPathLen(0)
01410 , m_pattern0(patterns)
01411 , m_pattern1(patterns)
01412 , m_delim(delim)
01413 , m_flags(flags)
01414 {
01415 m_subpath[0] = '\0';
01416
01417 operator ++();
01418 }
01419
01420 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01421 inline basic_findfile_sequence_const_input_iterator<C, T, V>::basic_findfile_sequence_const_input_iterator(sequence_type const& l)
01422 : m_list(&l)
01423 , m_handle(NULL)
01424 , m_subpath()
01425 , m_subPathLen(0)
01426 , m_pattern0(NULL)
01427 , m_pattern1(NULL)
01428 , m_delim('\0')
01429 , m_flags(0)
01430 {
01431 m_subpath[0] = '\0';
01432 }
01433
01434
01435 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01436 inline basic_findfile_sequence_const_input_iterator<C, T, V>::basic_findfile_sequence_const_input_iterator(class_type const& rhs)
01437 : m_list(rhs.m_list)
01438 , m_handle(rhs.m_handle)
01439 , m_data(rhs.m_data)
01440 , m_subpath(rhs.m_subpath)
01441 , m_subPathLen(rhs.m_subPathLen)
01442 , m_pattern0(rhs.m_pattern0)
01443 , m_pattern1(rhs.m_pattern1)
01444 , m_delim(rhs.m_delim)
01445 , m_flags(rhs.m_flags)
01446 {
01447 if(NULL != m_handle)
01448 {
01449 m_handle->AddRef();
01450 }
01451 }
01452
01453 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01454 #ifndef STLSOFT_COMPILER_IS_WATCOM
01455 inline ss_typename_type_ret_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)
01456 #else
01457 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)
01458 #endif
01459 {
01460 WINSTL_MESSAGE_ASSERT("Assigning iterators from separate sequences", (m_list == NULL || rhs.m_list == NULL || rhs.m_list));
01461
01462 shared_handle* this_handle = m_handle;
01463
01464 m_handle = rhs.m_handle;
01465 m_data = rhs.m_data;
01466 m_subpath = rhs.m_subpath;
01467 m_subPathLen = rhs.m_subPathLen;
01468 m_pattern0 = rhs.m_pattern0;
01469 m_pattern1 = rhs.m_pattern1;
01470 m_delim = rhs.m_delim;
01471 m_flags = rhs.m_flags;
01472
01473 if(NULL != m_handle)
01474 {
01475 m_handle->AddRef();
01476 }
01477
01478 if(NULL != this_handle)
01479 {
01480 this_handle->Release();
01481 }
01482
01483 return *this;
01484 }
01485
01486 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01487 inline basic_findfile_sequence_const_input_iterator<C, T, V>::~basic_findfile_sequence_const_input_iterator() stlsoft_throw_0()
01488 {
01489 if(NULL != m_handle)
01490 {
01491 m_handle->Release();
01492 }
01493 }
01494
01495 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01496 inline ss_typename_type_ret_k basic_findfile_sequence_const_input_iterator<C, T, V>::class_type& basic_findfile_sequence_const_input_iterator<C, T, V>::operator ++()
01497 {
01498
01499 WINSTL_MESSAGE_ASSERT("Attempting to increment an invalid iterator!", '\0' != *m_pattern0);
01500 WINSTL_ASSERT(NULL != m_pattern0);
01501 WINSTL_ASSERT(NULL != m_pattern1);
01502
01503 enum
01504 {
01505 #ifdef FILE_ATTRIBUTE_REPARSE_POINT
01506 reparsePointConstant = FILE_ATTRIBUTE_REPARSE_POINT
01507 #else
01508 reparsePointConstant = 0x00000400
01509 #endif
01510 };
01511
01512 STLSOFT_STATIC_ASSERT(reparsePointConstant);
01513
01514 for(; '\0' != *m_pattern0 || '\0' != *m_pattern1;)
01515 {
01516 if(NULL == m_handle)
01517 {
01518
01519
01520 while(stlsoft_ns_qual(find_next_token)(m_pattern0, m_pattern1, m_delim))
01521 {
01522 WINSTL_ASSERT(m_pattern0 <= m_pattern1);
01523
01524 if(m_pattern1 != m_pattern0)
01525 {
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535 file_path_buffer_type_ search;
01536 size_type cch;
01537
01538 if(traits_type::is_path_rooted(m_pattern0))
01539 {
01540 search[0] = '\0';
01541 cch = 0;
01542 }
01543 else
01544 {
01545 char_type const* directory = m_list->get_directory(&cch);
01546
01547 WINSTL_ASSERT(NULL != directory);
01548 WINSTL_ASSERT(0 != cch);
01549 WINSTL_ASSERT(cch <= search.size());
01550 WINSTL_ASSERT(traits_type::has_dir_end(directory));
01551
01552 traits_type::char_copy(&search[0], directory, cch + 1);
01553 }
01554 size_type n2 = static_cast<size_type>(m_pattern1 - m_pattern0);
01555
01556 traits_type::char_copy(&search[0] + cch, m_pattern0, n2);
01557 search[cch + n2] = '\0';
01558
01559
01560
01561
01562
01563 char_type const* slash = traits_type::str_rchr(&search[0] + cch, '/');
01564 char_type const* bslash = traits_type::str_rchr(&search[0] + cch, '\\');
01565
01566 WINSTL_ASSERT(!traits_type::is_path_rooted(m_pattern0) || ((NULL != slash) || (NULL != bslash)));
01567
01568 if( NULL != slash &&
01569 slash >= m_pattern1)
01570 {
01571 slash = NULL;
01572 }
01573 if( NULL != bslash &&
01574 bslash >= m_pattern1)
01575 {
01576 bslash = NULL;
01577 }
01578
01579 if( NULL != slash ||
01580 NULL != bslash)
01581 {
01582 if(NULL == slash)
01583 {
01584 slash = bslash;
01585 }
01586 else if(NULL != bslash &&
01587 slash < bslash)
01588 {
01589 slash = bslash;
01590 }
01591
01592 const size_type n = static_cast<size_type>(slash - &search[0]);
01593
01594 traits_type::char_copy(&m_subpath[0], &search[0], n);
01595 m_subPathLen = n;
01596 m_subpath[n] = '\0';
01597 }
01598
01599 HANDLE hSrch = find_first_file_(search.c_str(), m_flags, &m_data);
01600
01601 if(INVALID_HANDLE_VALUE != hSrch)
01602 {
01603 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
01604 _MSC_VER < 1200
01605 stlsoft_ns_qual(scoped_handle)<HANDLE> cleanup(hSrch, (void (STLSOFT_STDCALL *)(HANDLE))&::FindClose, INVALID_HANDLE_VALUE);
01606
01607 #else
01608 stlsoft_ns_qual(scoped_handle)<HANDLE> cleanup(hSrch, ::FindClose, INVALID_HANDLE_VALUE);
01609 #endif
01610
01611
01612
01613
01614 if( '.' == m_pattern0[0] &&
01615 ( m_pattern1 == m_pattern0 + 1 ||
01616 ( '.' == m_pattern0[1] &&
01617 m_pattern1 == m_pattern0 + 2)))
01618 {
01619 const size_type n = static_cast<size_type>(m_pattern1 - m_pattern0);
01620
01621 traits_type::char_copy(&m_data.cFileName[0], m_pattern0, n);
01622 m_data.cFileName[n] = '\0';
01623 }
01624
01625 m_handle = new shared_handle(hSrch);
01626
01627 if(NULL != m_handle)
01628 {
01629 cleanup.detach();
01630 }
01631
01632 return *this;
01633 }
01634 else
01635 {
01636 #ifdef _DEBUG
01637 DWORD dwErr = ::GetLastError();
01638
01639 STLSOFT_SUPPRESS_UNUSED(dwErr);
01640 #endif
01641 }
01642 }
01643 }
01644 }
01645
01646 if(NULL != m_handle)
01647 {
01648 for(; INVALID_HANDLE_VALUE != m_handle->hSrch; )
01649 {
01650 if(!traits_type::find_next_file(m_handle->hSrch, &m_data))
01651 {
01652 m_handle->Release();
01653
01654 m_handle = NULL;
01655
01656 break;
01657 }
01658 else
01659 {
01660 if( traits_type::is_file(&m_data) &&
01661 ( 0 == (m_flags & sequence_type::skipHiddenFiles) ||
01662 0 == (m_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)))
01663 {
01664
01665 if(m_flags & sequence_type::files)
01666 {
01667 return *this;
01668 }
01669 }
01670 else
01671 {
01672 if( 0 == (m_flags & sequence_type::skipHiddenDirs) ||
01673 0 == (m_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
01674 {
01675 if(traits_type::is_dots(m_data.cFileName))
01676 {
01677 if(m_flags & sequence_type::includeDots)
01678 {
01679
01680 return *this;
01681 }
01682 }
01683 else if(m_flags & sequence_type::directories)
01684 {
01685
01686 if( 0 == (m_flags & sequence_type::skipReparseDirs) ||
01687 0 == (m_data.dwFileAttributes & reparsePointConstant))
01688 {
01689
01690 return *this;
01691 }
01692 }
01693 }
01694 }
01695 }
01696 }
01697 }
01698 }
01699
01700 return *this;
01701 }
01702
01703 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01704 inline ss_typename_type_ret_k basic_findfile_sequence_const_input_iterator<C, T, V>::class_type basic_findfile_sequence_const_input_iterator<C, T, V>::operator ++(int)
01705 {
01706 class_type ret(*this);
01707
01708 operator ++();
01709
01710 return ret;
01711 }
01712
01713 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01714 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
01715 {
01716 WINSTL_MESSAGE_ASSERT("Dereferencing end()-valued iterator", NULL != m_handle);
01717
01718 WINSTL_ASSERT(m_subPathLen == traits_type::str_len(m_subpath.c_str()));
01719
01720 if(0 == m_subPathLen)
01721 {
01722 return value_type(m_data, m_list->get_directory(), traits_type::str_len(m_list->get_directory()));
01723 }
01724 else
01725 {
01726 return value_type(m_data, m_subpath.c_str(), m_subPathLen);
01727 }
01728 }
01729
01730 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01731 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
01732 {
01733
01734 WINSTL_MESSAGE_ASSERT("Comparing iterators from separate sequences", (m_list == rhs.m_list || NULL == m_list || NULL == rhs.m_list));
01735
01736 return m_handle == rhs.m_handle;
01737 }
01738
01739 #endif
01740
01741
01742
01743 #ifndef _WINSTL_NO_NAMESPACE
01744 # if defined(_STLSOFT_NO_NAMESPACE) || \
01745 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01746 }
01747 # else
01748 }
01749 }
01750 # endif
01751 #endif
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761 #ifndef _WINSTL_NO_NAMESPACE
01762 # if !defined(_STLSOFT_NO_NAMESPACE) && \
01763 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01764 namespace stlsoft
01765 {
01766 # else
01767
01768 # endif
01769
01770 using ::winstl::c_str_len;
01771 using ::winstl::c_str_len_a;
01772 using ::winstl::c_str_len_w;
01773
01774 using ::winstl::c_str_data;
01775 using ::winstl::c_str_data_a;
01776 using ::winstl::c_str_data_w;
01777
01778 using ::winstl::c_str_ptr;
01779 using ::winstl::c_str_ptr_a;
01780 using ::winstl::c_str_ptr_w;
01781
01782 using ::winstl::c_str_ptr_null;
01783 using ::winstl::c_str_ptr_null_a;
01784 using ::winstl::c_str_ptr_null_w;
01785
01786 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
01787
01788 using ::winstl::is_empty;
01789
01790 #endif
01791
01792 # if !defined(_STLSOFT_NO_NAMESPACE) && \
01793 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01794 }
01795 # else
01796
01797 # endif
01798 #endif
01799
01800
01801
01802 #endif
01803
01804