STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

winstl_findfile_sequence.h

Go to the documentation of this file.
00001 /* 
00002  * File:        winstl_findfile_sequence.h
00003  *
00004  * Purpose:     Contains the basic_findfile_sequence template class, and ANSI
00005  *              and Unicode specialisations thereof.
00006  *
00007  * Notes:       1. The original implementation of the class had the const_iterator
00008  *              and value_type as nested classes. Unfortunately, Visual C++ 5 &
00009  *              6 both had either compilation or linking problems so these are
00010  *              regretably now implemented as independent classes.
00011  *
00012  *              2. This class was described in detail in the article
00013  *              "Adapting Windows Enumeration Models to STL Iterator Concepts"
00014  *              (http://www.windevnet.com/documents/win0303a/), in the March
00015  *              2003 issue of Windows Developer Network (http://windevnet.com).
00016  *
00017  * Created:     15th January 2002
00018  * Updated:     11th September 2004
00019  *
00020  * Home:        http://stlsoft.org/
00021  *
00022  * Copyright (c) 2002-2004, Matthew Wilson and Synesis Software
00023  * All rights reserved.
00024  *
00025  * Redistribution and use in source and binary forms, with or without
00026  * modification, are permitted provided that the following conditions are met:
00027  *
00028  * - Redistributions of source code must retain the above copyright notice, this
00029  *   list of conditions and the following disclaimer.
00030  * - Redistributions in binary form must reproduce the above copyright notice,
00031  *   this list of conditions and the following disclaimer in the documentation
00032  *   and/or other materials provided with the distribution.
00033  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00034  *   any contributors may be used to endorse or promote products derived from
00035  *   this software without specific prior written permission.
00036  *
00037  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00038  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00039  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00040  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00041  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00042  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00043  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00044  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00045  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00046  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00047  * POSSIBILITY OF SUCH DAMAGE.
00048  *
00049  * 
00050 
00051 
00055 
00056 #ifndef WINSTL_INCL_H_WINSTL_FINDFILE_SEQUENCE
00057 #define WINSTL_INCL_H_WINSTL_FINDFILE_SEQUENCE
00058 
00059 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00060 # define WINSTL_VER_H_WINSTL_FINDFILE_SEQUENCE_MAJOR        2
00061 # define WINSTL_VER_H_WINSTL_FINDFILE_SEQUENCE_MINOR        0
00062 # define WINSTL_VER_H_WINSTL_FINDFILE_SEQUENCE_REVISION     1
00063 # define WINSTL_VER_H_WINSTL_FINDFILE_SEQUENCE_EDIT         110
00064 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00065 
00066 /* 
00067  * Compatibility
00068  */
00069 
00070 /*
00071 [Incompatibilies-start]
00072 __STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
00073 [Incompatibilies-end]
00074  */
00075 
00076 /* 
00077  * Includes
00078  */
00079 
00080 #ifndef WINSTL_INCL_H_WINSTL
00081 # include "winstl.h"                    // Include the WinSTL root header
00082 #endif /* !WINSTL_INCL_H_WINSTL */
00083 #ifndef WINSTL_INCL_H_WINSTL_FILESYSTEM_TRAITS
00084 
00085 #if defined(__STLSOFT_COMPILER_IS_MSVC) && \
00086     _MSC_VER < 1200
00087 # error winstl_file_path_buffer.h is not compatible with Visual C++ 5.0 or earlier
00088 #endif /* _MSC_VER < 1200 */
00089 
00090 # include "winstl_filesystem_traits.h"  // filesystem_traits
00091 #endif /* !WINSTL_INCL_H_WINSTL_FILESYSTEM_TRAITS */
00092 #ifndef WINSTL_INCL_H_WINSTL_FILE_PATH_BUFFER
00093 # include "winstl_file_path_buffer.h"   // basic_file_path_buffer
00094 #endif /* !WINSTL_INCL_H_WINSTL_FILE_PATH_BUFFER */
00095 #ifndef WINSTL_INCL_H_WINSTL_SYSTEM_VERSION
00096 # include "winstl_system_version.h"     // winnt(), major()
00097 #endif /* !WINSTL_INCL_H_WINSTL_SYSTEM_VERSION */
00098 #ifndef WINSTL_INCL_H_WINSTL_STRING_ACCESS
00099 # include "winstl_string_access.h"                  // winstl::string_access
00100 #endif /* WINSTL_INCL_H_WINSTL_STRING_ACCESS */
00101 #ifndef __STLSOFT_COMPILER_IS_WATCOM
00102 # ifndef STLSOFT_INCL_H_STLSOFT_ITERATOR
00103 #  include "stlsoft_iterator.h"          // iterator_base
00104 # endif /* !STLSOFT_INCL_H_STLSOFT_ITERATOR */
00105 #endif /* __STLSOFT_COMPILER_IS_WATCOM */
00106 
00107 /* 
00108  * Pre-processor
00109  *
00110  * Definition of the
00111  */
00112 
00113 /* 
00114  * Namespace
00115  */
00116 
00117 #ifndef _WINSTL_NO_NAMESPACE
00118 # if defined(_STLSOFT_NO_NAMESPACE) || \
00119      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00120 /* There is no stlsoft namespace, so must define ::winstl */
00121 namespace winstl
00122 {
00123 # else
00124 /* Define stlsoft::winstl_project */
00125 
00126 namespace stlsoft
00127 {
00128 
00129 namespace winstl_project
00130 {
00131 
00132 # endif /* _STLSOFT_NO_NAMESPACE */
00133 #endif /* !_WINSTL_NO_NAMESPACE */
00134 
00135 /* 
00136 
00139 
00143 
00148 
00149 /* 
00150  * Forward declarations
00151  */
00152 
00153 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00154 
00155 template <ss_typename_param_k C, ss_typename_param_k T>
00156 class basic_findfile_sequence_value_type;
00157 
00158 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00159 class basic_findfile_sequence_const_input_iterator;
00160 
00161 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00162 
00163 /* 
00164  * Classes
00165  */
00166 
00167 // class basic_findfile_sequence
00177 template<   ss_typename_param_k C
00178 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00179         ,   ss_typename_param_k T = filesystem_traits<C>
00180 #else
00181         ,   ss_typename_param_k T /* = filesystem_traits<C> */
00182 #endif /* __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00183         >
00184 class basic_findfile_sequence
00185 {
00186 public:
00188     typedef C                                                                   char_type;
00190     typedef T                                                                   traits_type;
00192     typedef basic_findfile_sequence<C, T>                                       class_type;
00194     typedef basic_findfile_sequence_value_type<C, T>                            value_type;
00196     typedef basic_findfile_sequence_const_input_iterator<C, T, value_type>      const_input_iterator;
00198     typedef const_input_iterator                                                const_iterator;
00200     typedef value_type const                                                    reference;
00202     typedef value_type const                                                    const_reference;
00204     typedef ss_typename_type_k traits_type::find_data_type                      find_data_type;
00206     typedef ws_ptrdiff_t                                                        difference_type;
00208     typedef ws_size_t                                                           size_type;
00209 
00210     enum
00211     {
00212             includeDots =   0x0008          
00213         ,   directories =   0x0010          
00214         ,   files       =   0x0020          
00215 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00216         ,   noSort      =   0 /* 0x0100 */  
00217 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00218         ,
00219     };
00220 
00221 // Construction
00222 public:
00224     ss_explicit_k basic_findfile_sequence(char_type const *searchSpec, ws_int_t flags = directories | files);
00226     basic_findfile_sequence(char_type const *directory, char_type const *searchSpec, ws_int_t flags = directories | files);
00228     ~basic_findfile_sequence() winstl_throw_0();
00229 
00230 // Iteration
00231 public:
00235     const_iterator      begin() const;
00239     const_iterator      end() const;
00240 
00241 // Attributes
00242 public:
00246     char_type const     *get_directory() const;
00247 
00248 // State
00249 public:
00250 #ifdef STLSOFT_OBSOLETE
00255     size_type           size() const;
00256 #endif /* STLSOFT_OBSOLETE */
00257 
00258     ws_bool_t           empty() const;
00260     static size_type    max_size();
00261 
00262 // Members
00263 private:
00264     friend class basic_findfile_sequence_value_type<C, T>;
00265     friend class basic_findfile_sequence_const_input_iterator<C, T, value_type>;
00266 
00267     typedef basic_file_path_buffer<char_type>   file_path_buffer_type;
00268 
00269     file_path_buffer_type   m_directory;
00270     file_path_buffer_type   m_subpath;
00271     file_path_buffer_type   m_search;
00272     ws_int_t const          m_flags;
00273 
00274 // Implementation
00275 private:
00276     static ws_int_t validate_flags_(ws_int_t flags);
00277     static void     extract_subpath_(file_path_buffer_type &dest, char_type const *searchSpec);
00278 
00279     static  HANDLE  find_first_file_(char_type const *spec, ws_int_t flags, find_data_type *findData);
00280     HANDLE          begin_(find_data_type &findData) const;
00281 
00282 // Not to be implemented
00283 private:
00284     class_type &operator =(class_type const&);
00285 };
00286 
00287 /* 
00288  * Typedefs for commonly encountered types
00289  */
00290 
00292 typedef basic_findfile_sequence<ws_char_a_t, filesystem_traits<ws_char_a_t> >     findfile_sequence_a;
00294 typedef basic_findfile_sequence<ws_char_w_t, filesystem_traits<ws_char_w_t> >     findfile_sequence_w;
00296 typedef basic_findfile_sequence<TCHAR, filesystem_traits<TCHAR> >                 findfile_sequence;
00297 
00298 /* 
00299 
00300 // class basic_findfile_sequence_value_type
00302 template<   ss_typename_param_k C
00303         ,   ss_typename_param_k T
00304         >
00305 class basic_findfile_sequence_value_type
00306 {
00307 public:
00309     typedef C                                               char_type;
00311     typedef T                                               traits_type;
00313     typedef basic_findfile_sequence_value_type<C, T>        class_type;
00315     typedef ss_typename_type_k traits_type::find_data_type  find_data_type;
00316 
00317 public:
00319     basic_findfile_sequence_value_type();
00320 private:
00321     basic_findfile_sequence_value_type(find_data_type const &data, char_type const *path)
00322         : m_data(data)
00323     {
00324         traits_type::str_copy(&m_path[0], path);
00325         traits_type::ensure_dir_end(&m_path[0]);
00326         traits_type::str_cat(&m_path[0], data.cFileName);
00327     }
00328 public:
00329 #if 0
00331     basic_findfile_sequence_value_type(class_type const &rhs);
00332 #endif /* 0 */
00333 
00335     ~basic_findfile_sequence_value_type() winstl_throw_0();
00336 
00338     class_type &operator =(class_type const &rhs);
00339 
00341     find_data_type const    &get_find_data() const;
00345     find_data_type const    &GetFindData() const;   // Deprecated
00346 
00348     char_type const         *get_filename() const;
00350     char_type const         *get_short_filename() const;
00352     char_type const         *get_path() const;
00353 
00355     operator char_type const * () const;
00356 
00357 // Members
00358 private:
00359     friend class basic_findfile_sequence_const_input_iterator<C, T, class_type>;
00360 
00361     typedef basic_file_path_buffer<char_type>   file_path_buffer_type;
00362 
00363     find_data_type          m_data;
00364     file_path_buffer_type   m_path;
00365 };
00366 
00367 // class basic_findfile_sequence_const_input_iterator
00369 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00370 class basic_findfile_sequence_const_input_iterator
00371 #ifndef __STLSOFT_COMPILER_IS_WATCOM
00372     : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(input_iterator_tag), V, ws_ptrdiff_t, void, V>
00373 #endif /* !__STLSOFT_COMPILER_IS_WATCOM */
00374 {
00375 public:
00377     typedef C                                                       char_type;
00379     typedef T                                                       traits_type;
00381     typedef V                                                       value_type;
00383     typedef basic_findfile_sequence_const_input_iterator<C, T, V>   class_type;
00385     typedef ss_typename_type_k traits_type::find_data_type          find_data_type;
00386 private:
00387     typedef basic_findfile_sequence<C, T>                           sequence_type;
00388 
00391 private:
00392 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00393     struct shared_handle
00394     {
00395     public:
00396         typedef shared_handle       class_type;
00397 
00398     // Members
00399     public:
00400         HANDLE      hSrch;
00401     private:
00402         ss_sint32_t cRefs;
00403 
00405     public:
00406         ss_explicit_k shared_handle(HANDLE h)
00407             : hSrch(h)
00408             , cRefs(1)
00409         {}
00410 # if defined(__STLSOFT_COMPILER_IS_GCC)
00411     protected:
00412 # else /* ? __STLSOFT_COMPILER_IS_GCC */
00413     private:
00414 # endif /* __STLSOFT_COMPILER_IS_GCC */
00415         ~shared_handle()
00416         {
00417             winstl_message_assert("Shared search handle being destroyed with outstanding references!", 0 == cRefs);
00418 
00419             if(hSrch != INVALID_HANDLE_VALUE)
00420             {
00421                 traits_type::find_file_close(hSrch);
00422             }
00423         }
00424 
00426     public:
00427         void AddRef()
00428         {
00429             ++cRefs;
00430         }
00431         void Release()
00432         {
00433             if(0 == --cRefs)
00434             {
00435                 delete this;
00436             }
00437         }
00438 
00439     // Not to be implemented
00440     private:
00441         shared_handle(class_type const &);
00442         class_type &operator =(class_type const &);
00443     };
00444     #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00445 
00446 
00449 private:
00450     basic_findfile_sequence_const_input_iterator(sequence_type const &l, HANDLE hSrch, find_data_type const &data)
00451         : m_list(&l)
00452         , m_handle(new shared_handle(hSrch))
00453         , m_data(data)
00454     {
00455         winstl_assert(INVALID_HANDLE_VALUE != hSrch);
00456     }
00457     basic_findfile_sequence_const_input_iterator(sequence_type const &l);
00458 public:
00460     basic_findfile_sequence_const_input_iterator();
00462     basic_findfile_sequence_const_input_iterator(class_type const &rhs);
00464     ~basic_findfile_sequence_const_input_iterator() winstl_throw_0();
00465 
00466     // Copy assignment operator
00467     basic_findfile_sequence_const_input_iterator &operator =(class_type const &rhs);
00469 
00470 public:
00472     class_type &operator ++();
00474     class_type operator ++(int);
00476     const value_type operator *() const;
00478     ws_bool_t operator ==(class_type const &rhs) const;
00480     ws_bool_t operator !=(class_type const &rhs) const;
00481 
00482 // Members
00483 private:
00484     friend class basic_findfile_sequence<C, T>;
00485 
00486     sequence_type const * const                     m_list;
00487     shared_handle                                   *m_handle;
00488     ss_typename_type_k traits_type::find_data_type  m_data;
00489 };
00490 
00492 // Shims
00493 
00494 template <ss_typename_param_k C, ss_typename_param_k T>
00495 inline C const *c_str_ptr_null(basic_findfile_sequence_value_type<C, T> const &v)
00496 {
00497     return stlsoft_ns_qual(c_str_ptr_null(v.get_path()));
00498 }
00499 
00500 template <ss_typename_param_k C, ss_typename_param_k T>
00501 inline C const *c_str_ptr(basic_findfile_sequence_value_type<C, T> const &v)
00502 {
00503     return stlsoft_ns_qual(c_str_ptr(v.get_path()));
00504 }
00505 
00506 template <ss_typename_param_k C, ss_typename_param_k T>
00507 inline ws_size_t c_str_len(basic_findfile_sequence_value_type<C, T> const &v)
00508 {
00509     return stlsoft_ns_qual(c_str_len(v.get_path()));
00510 }
00511 
00512 template <ss_typename_param_k C, ss_typename_param_k T>
00513 inline ws_size_t c_str_size(basic_findfile_sequence_value_type<C, T> const &v)
00514 {
00515     return stlsoft_ns_qual(c_str_size(v.get_path()));
00516 }
00517 
00518 template <ss_typename_param_k C, ss_typename_param_k T>
00519 inline ws_bool_t is_empty(basic_findfile_sequence<C, T> const &s)
00520 {
00521     return s.empty();
00522 }
00523 
00525 // Unit-testing
00526 
00527 #ifdef STLSOFT_UNITTEST
00528 
00529 namespace unittest
00530 {
00531     ss_bool_t test_winstl_findfile_sequence(unittest_reporter *r)
00532     {
00533         using stlsoft::unittest::unittest_initialiser;
00534 
00535         ss_bool_t               bSuccess    =   true;
00536 
00537         unittest_initialiser    init(r, "WinSTL", "findfile_sequence", __FILE__);
00538 
00539 #if 0
00540         if(<<TODO>>)
00541         {
00542             r->report("<<TODO>> failed ", __LINE__);
00543             bSuccess = false;
00544         }
00545 #endif /* 0 */
00546 
00547         return bSuccess;
00548     }
00549 
00550     unittest_registrar    unittest_winstl_findfile_sequence(test_winstl_findfile_sequence);
00551 
00552 } // namespace unittest
00553 
00554 #endif /* STLSOFT_UNITTEST */
00555 
00557 // Implementation
00558 
00559 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00560 
00561 // basic_findfile_sequence
00562 
00563 template <ss_typename_param_k C, ss_typename_param_k T>
00564 inline /* static */ HANDLE basic_findfile_sequence<C, T>::find_first_file_(ss_typename_type_k basic_findfile_sequence<C, T>::char_type const *spec, ws_int_t flags, ss_typename_type_k basic_findfile_sequence<C, T>::find_data_type *findData)
00565 {
00566     HANDLE  hSrch;
00567 
00568 #if _WIN32_WINNT >= 0x0400
00569     if( (directories == (flags & (directories | files))) &&
00570         system_version::winnt() &&
00571         system_version::major() >= 4)
00572     {
00573         hSrch = traits_type::find_first_file_ex(spec, FindExSearchLimitToDirectories , findData);
00574     }
00575     else
00576 #else
00577     STLSOFT_SUPPRESS_UNUSED(flags);
00578 #endif /* _WIN32_WINNT >= 0x0400 */
00579     {
00580         hSrch = traits_type::find_first_file(spec, findData);
00581     }
00582 
00583     return hSrch;
00584 }
00585 
00586 template <ss_typename_param_k C, ss_typename_param_k T>
00587 inline HANDLE basic_findfile_sequence<C, T>::begin_(ss_typename_type_k basic_findfile_sequence<C, T>::find_data_type &findData) const
00588 {
00589     HANDLE  hSrch   =   find_first_file_(stlsoft_ns_qual(c_str_ptr)(m_search), m_flags, &findData);
00590 
00591     if(hSrch != INVALID_HANDLE_VALUE)
00592     {
00593         // Now need to validate against the flags
00594 
00595         for(; hSrch != INVALID_HANDLE_VALUE; )
00596         {
00597             if((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
00598             {
00599                 // A file, and files requested, so break
00600                 if(m_flags & files)
00601                 {
00602                     break;
00603                 }
00604             }
00605             else
00606             {
00607                 if(traits_type::is_dots(findData.cFileName))
00608                 {
00609                     if(m_flags & includeDots)
00610                     {
00611                         // A dots file, and dots are requested
00612                         break;
00613                     }
00614                 }
00615                 else if(m_flags & directories)
00616                 {
00617                     // A directory, and directories requested
00618                     break;
00619                 }
00620             }
00621 
00622             if(!traits_type::find_next_file(hSrch, &findData))
00623             {
00624                 ::FindClose(hSrch);
00625 
00626                 hSrch = INVALID_HANDLE_VALUE;
00627 
00628                 break;
00629             }
00630         }
00631     }
00632 
00633     return hSrch;
00634 }
00635 
00636 template <ss_typename_param_k C, ss_typename_param_k T>
00637 inline /* static */ ws_int_t basic_findfile_sequence<C, T>::validate_flags_(ws_int_t flags)
00638 {
00639     return (flags & (directories | files)) == 0 ? (flags | (directories | files)) : flags;
00640 }
00641 
00642 template <ss_typename_param_k C, ss_typename_param_k T>
00643 inline /* static */ void basic_findfile_sequence<C, T>::extract_subpath_(ss_typename_param_k basic_findfile_sequence<C, T>::file_path_buffer_type &dest, ss_typename_param_k basic_findfile_sequence<C, T>::char_type const *searchSpec)
00644 {
00645     char_type   *pFile;
00646 
00647     traits_type::get_full_path_name(searchSpec, dest.size(), &dest[0], &pFile);
00648 
00649     if(pFile != 0)
00650     {
00651         *pFile = '\0';
00652     }
00653 }
00654 
00655 // Construction
00656 template <ss_typename_param_k C, ss_typename_param_k T>
00657 inline basic_findfile_sequence<C, T>::basic_findfile_sequence(char_type const *searchSpec, ws_int_t flags /* = directories | files */)
00658     : m_flags(validate_flags_(flags))
00659 {
00660     m_directory[0] = '\0';
00661 
00662     traits_type::str_copy(&m_search[0], searchSpec);
00663 
00664     extract_subpath_(m_subpath, searchSpec);
00665 }
00666 
00667 template <ss_typename_param_k C, ss_typename_param_k T>
00668 inline basic_findfile_sequence<C, T>::basic_findfile_sequence(char_type const *directory, char_type const *searchSpec, ws_int_t flags /* = directories | files */)
00669     : m_flags(validate_flags_(flags))
00670 {
00671     traits_type::str_copy(&m_directory[0], directory);
00672 
00673     traits_type::str_copy(&m_search[0], directory);
00674     if( searchSpec[0] == '.' &&
00675         searchSpec[1] == '\0')
00676     {
00677         // This is needed to prevent a searchSpec of "." from stipulating the name twice
00678         traits_type::remove_dir_end(&m_search[0]);
00679     }
00680     else
00681     {
00682         traits_type::ensure_dir_end(&m_search[0]);
00683         traits_type::str_cat(&m_search[0], searchSpec);
00684     }
00685 
00686     extract_subpath_(m_subpath, &m_search[0]);
00687 }
00688 
00689 template <ss_typename_param_k C, ss_typename_param_k T>
00690 inline basic_findfile_sequence<C, T>::~basic_findfile_sequence() winstl_throw_0()
00691 {
00692 #ifdef _DEBUG
00693     m_directory[0]  =   '\0';
00694     m_subpath[0]    =   '\0';
00695     m_search[0]     =   '\0';
00696 #endif /* _DEBUG */
00697 }
00698 
00699 // Iteration
00700 template <ss_typename_param_k C, ss_typename_param_k T>
00701 inline ss_typename_type_k basic_findfile_sequence<C, T>::const_iterator basic_findfile_sequence<C, T>::begin() const
00702 {
00703     ss_typename_type_k traits_type::find_data_type  findData;
00704     HANDLE                                          hSrch   =   begin_(findData);
00705 
00706     if(hSrch == INVALID_HANDLE_VALUE)
00707     {
00708         return const_input_iterator(*this);
00709     }
00710     else
00711     {
00712         return const_input_iterator(*this, hSrch, findData);
00713     }
00714 }
00715 
00716 template <ss_typename_param_k C, ss_typename_param_k T>
00717 inline ss_typename_type_k basic_findfile_sequence<C, T>::const_iterator basic_findfile_sequence<C, T>::end() const
00718 {
00719     return const_input_iterator(*this);
00720 }
00721 
00722 // Attributes
00723 template <ss_typename_param_k C, ss_typename_param_k T>
00724 ss_typename_type_k basic_findfile_sequence<C, T>::char_type const *basic_findfile_sequence<C, T>::get_directory() const
00725 {
00726     return stlsoft_ns_qual(c_str_ptr)(m_directory);
00727 }
00728 
00729 // State
00730 #ifdef STLSOFT_OBSOLETE
00731 template <ss_typename_param_k C, ss_typename_param_k T>
00732 inline ss_typename_type_k basic_findfile_sequence<C, T>::size_type basic_findfile_sequence<C, T>::size() const
00733 {
00734     return stlsoft_ns_qual_std(distance)(begin(), end());
00735 }
00736 #endif /* STLSOFT_OBSOLETE */
00737 
00738 template <ss_typename_param_k C, ss_typename_param_k T>
00739 inline ws_bool_t basic_findfile_sequence<C, T>::empty() const
00740 {
00741     return begin() == end();
00742 }
00743 
00744 template <ss_typename_param_k C, ss_typename_param_k T>
00745 inline /* static */ ss_typename_type_k basic_findfile_sequence<C, T>::size_type basic_findfile_sequence<C, T>::max_size()
00746 {
00747     return static_cast<size_type>(-1);
00748 }
00749 
00750 // basic_findfile_sequence_value_type
00751 
00752 template <ss_typename_param_k C, ss_typename_param_k T>
00753 inline basic_findfile_sequence_value_type<C, T>::basic_findfile_sequence_value_type()
00754 {
00755     m_data.dwFileAttributes         =   0xFFFFFFFF;
00756     m_data.cFileName[0]             =   '\0';
00757     m_data.cAlternateFileName[0]    =   '\0';
00758     m_path[0]                       =   '\0';
00759 }
00760 
00761 #if 0
00762 template <ss_typename_param_k C, ss_typename_param_k T>
00763 inline basic_findfile_sequence_value_type<C, T>::basic_findfile_sequence_value_type(ss_typename_type_k basic_findfile_sequence_value_type<C, T>::class_type const &rhs)
00764     : m_data(rhs.m_data)
00765     , m_path(rhs.m_path)
00766 {}
00767 #endif /* 0 */
00768 
00769 template <ss_typename_param_k C, ss_typename_param_k T>
00770 inline basic_findfile_sequence_value_type<C, T>::~basic_findfile_sequence_value_type() winstl_throw_0()
00771 {
00772 #ifdef _DEBUG
00773     m_data.cFileName[0] =   '\0';
00774     m_path[0]           =   '\0';
00775 #endif /* _DEBUG */
00776 }
00777 
00778 #if 0
00779 template <ss_typename_param_k C, ss_typename_param_k T>
00780 #ifdef __STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED
00781 inline basic_findfile_sequence_value_type<C, T>::operator basic_findfile_sequence_value_type<C, T>::char_type const *() const
00782 #else
00783 inline basic_findfile_sequence_value_type<C, T>::operator char_type const *() const
00784 #endif /* __STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
00785 {
00786     return m_data.cFileName;
00787 }
00788 #endif /* 0 */
00789 
00790 template <ss_typename_param_k C, ss_typename_param_k T>
00791 inline ss_typename_type_k basic_findfile_sequence_value_type<C, T>::find_data_type const &basic_findfile_sequence_value_type<C, T>::get_find_data() const
00792 {
00793     return m_data;
00794 }
00795 
00796 template <ss_typename_param_k C, ss_typename_param_k T>
00797 inline ss_typename_type_k basic_findfile_sequence_value_type<C, T>::find_data_type const &basic_findfile_sequence_value_type<C, T>::GetFindData() const
00798 {
00799     return get_find_data();
00800 }
00801 
00802 template <ss_typename_param_k C, ss_typename_param_k T>
00803 inline ss_typename_type_k basic_findfile_sequence_value_type<C, T>::char_type const *basic_findfile_sequence_value_type<C, T>::get_filename() const
00804 {
00805     return m_data.cFileName;
00806 }
00807 
00808 template <ss_typename_param_k C, ss_typename_param_k T>
00809 inline ss_typename_type_k basic_findfile_sequence_value_type<C, T>::char_type const *basic_findfile_sequence_value_type<C, T>::get_short_filename() const
00810 {
00811     return m_data.cAlternateFileName[0] != '\0' ? m_data.cAlternateFileName : m_data.cFileName;
00812 }
00813 
00814 template <ss_typename_param_k C, ss_typename_param_k T>
00815 inline ss_typename_type_k basic_findfile_sequence_value_type<C, T>::char_type const *basic_findfile_sequence_value_type<C, T>::get_path() const
00816 {
00817     return stlsoft_ns_qual(c_str_ptr)(m_path);
00818 }
00819 
00820 template <ss_typename_param_k C, ss_typename_param_k T>
00821 #if defined(__STLSOFT_COMPILER_IS_GCC) || \
00822     (   defined(__STLSOFT_COMPILER_IS_MSVC) && \
00823         _MSC_VER < 1100)
00824 inline basic_findfile_sequence_value_type<C, T>::operator C const * () const
00825 #else
00826 inline basic_findfile_sequence_value_type<C, T>::operator ss_typename_type_k basic_findfile_sequence_value_type<C, T>::char_type const * () const
00827 #endif /* !__GNUC__ */
00828 {
00829     return get_path();
00830 }
00831 
00832 // operator == ()
00833 template <ss_typename_param_k C, ss_typename_param_k T>
00834 inline ws_bool_t operator == (basic_findfile_sequence_value_type<C, T> const &lhs, basic_findfile_sequence_value_type<C, T> const &rhs)
00835 {
00836     return 0 == basic_findfile_sequence_value_type<C, T>::traits_type::str_compare(lhs.get_path(), rhs.get_path());
00837 }
00838 
00839 template <ss_typename_param_k C, ss_typename_param_k T>
00840 inline ws_bool_t operator == (basic_findfile_sequence_value_type<C, T> const &lhs, C const *rhs)
00841 {
00842     return 0 == basic_findfile_sequence_value_type<C, T>::traits_type::str_compare(lhs.get_path(), rhs);
00843 }
00844 
00845 template <ss_typename_param_k C, ss_typename_param_k T>
00846 inline ws_bool_t operator == (C const *lhs, basic_findfile_sequence_value_type<C, T> const &rhs)
00847 {
00848     return 0 == basic_findfile_sequence_value_type<C, T>::traits_type::str_compare(lhs, rhs.get_path());
00849 }
00850 
00851 // basic_findfile_sequence_const_input_iterator
00852 
00853 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00854 inline basic_findfile_sequence_const_input_iterator<C, T, V>::basic_findfile_sequence_const_input_iterator()
00855     : m_list(NULL)
00856     , m_handle(NULL)
00857 {}
00858 
00859 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00860 inline basic_findfile_sequence_const_input_iterator<C, T, V>::basic_findfile_sequence_const_input_iterator(sequence_type const &l)
00861     : m_list(&l)
00862     , m_handle(NULL)
00863 {}
00864 
00865 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00866 inline basic_findfile_sequence_const_input_iterator<C, T, V>::basic_findfile_sequence_const_input_iterator(class_type const &rhs)
00867     : m_list(rhs.m_list)
00868     , m_handle(rhs.m_handle)
00869     , m_data(rhs.m_data)
00870 {
00871     if(NULL != m_handle)
00872     {
00873         m_handle->AddRef();
00874     }
00875 }
00876 
00877 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00878 #ifndef __STLSOFT_COMPILER_IS_WATCOM
00879 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)
00880 #else /* ? __STLSOFT_COMPILER_IS_WATCOM */
00881 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)
00882 #endif /* __STLSOFT_COMPILER_IS_WATCOM */
00883 {
00884     winstl_message_assert("Assigning iterators from separate sequences", m_list == rhs.m_list);    // Should only be comparing iterators from same container
00885 
00886     m_handle    =   rhs.m_handle;
00887     m_data      =   rhs.m_data;
00888 
00889     if(NULL != m_handle)
00890     {
00891         m_handle->AddRef();
00892     }
00893 
00894     return *this;
00895 }
00896 
00897 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00898 inline basic_findfile_sequence_const_input_iterator<C, T, V>::~basic_findfile_sequence_const_input_iterator() winstl_throw_0()
00899 {
00900     if(NULL != m_handle)
00901     {
00902         m_handle->Release();
00903     }
00904 }
00905 
00906 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00907 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 ++()
00908 {
00909     ws_int_t    flags   =   m_list->m_flags;
00910 
00911     winstl_message_assert("Attempting to increment an invalid iterator!", NULL != m_handle);
00912 
00913     for(; m_handle->hSrch != INVALID_HANDLE_VALUE; )
00914     {
00915         if(!traits_type::find_next_file(m_handle->hSrch, &m_data))
00916         {
00917             m_handle->Release();
00918 
00919             m_handle = NULL;
00920 
00921             break;
00922         }
00923         else
00924         {
00925             if((m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
00926             {
00927                 // A file, and files requested, so break
00928                 if(flags & sequence_type::files)
00929                 {
00930                     break;
00931                 }
00932             }
00933             else
00934             {
00935                 if(traits_type::is_dots(m_data.cFileName))
00936                 {
00937                     if(flags & sequence_type::includeDots)
00938                     {
00939                         // A dots file, and dots are requested
00940                         break;
00941                     }
00942                 }
00943                 else if(flags & sequence_type::directories)
00944                 {
00945                     // A directory, and directories requested
00946                     break;
00947                 }
00948             }
00949         }
00950     }
00951 
00952     return *this;
00953 }
00954 
00955 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00956 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)
00957 {
00958     class_type  ret(*this);
00959 
00960     operator ++();
00961 
00962     return ret;
00963 }
00964 
00965 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00966 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
00967 {
00968     if(NULL != m_handle)
00969     {
00970         return value_type(m_data, stlsoft_ns_qual(c_str_ptr)(m_list->m_subpath));
00971     }
00972     else
00973     {
00974         winstl_message_assert("Dereferencing end()-valued iterator", 0);
00975 
00976         return value_type();
00977     }
00978 }
00979 
00980 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00981 inline ws_bool_t basic_findfile_sequence_const_input_iterator<C, T, V>::operator ==(class_type const &rhs) const
00982 {
00983     ws_bool_t    eq;
00984 
00985     // Should only be comparing iterators from same container
00986     winstl_message_assert("Comparing iterators from separate sequences", m_list == rhs.m_list);
00987 
00988     // Not equal if one but not both handles is the INVALID_HANDLE_VALUE
00989     // or if the data is not equal.
00990     if( (NULL == m_handle) != (NULL == rhs.m_handle) ||
00991         (   NULL != m_handle &&
00992             traits_type::str_compare(m_data.cFileName, rhs.m_data.cFileName) != 0))
00993     {
00994         eq = ws_false_v;
00995     }
00996     else
00997     {
00998         eq = ws_true_v;
00999     }
01000 
01001     return eq;
01002 }
01003 
01004 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
01005 inline ws_bool_t basic_findfile_sequence_const_input_iterator<C, T, V>::operator !=(class_type const &rhs) const
01006 {
01007     return ! operator ==(rhs);
01008 }
01009 
01010 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
01011 
01012 /* 
01013 
01015 
01016 /* 
01017 
01018 #ifndef _WINSTL_NO_NAMESPACE
01019 # if defined(_STLSOFT_NO_NAMESPACE) || \
01020      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
01021 } // namespace winstl
01022 # else
01023 } // namespace winstl_project
01024 } // namespace stlsoft
01025 # endif /* _STLSOFT_NO_NAMESPACE */
01026 #endif /* !_WINSTL_NO_NAMESPACE */
01027 
01028 /* 
01029  * Namespace
01030  *
01031  * The string access shims exist either in the stlsoft namespace, or in the
01032  * global namespace. This is required by the lookup rules.
01033  *
01034  */
01035 
01036 #ifndef _WINSTL_NO_NAMESPACE
01037 # if !defined(_STLSOFT_NO_NAMESPACE) && \
01038      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
01039 namespace stlsoft
01040 {
01041 # else /* ? _STLSOFT_NO_NAMESPACE */
01042 /* There is no stlsoft namespace, so must define in the global namespace */
01043 # endif /* !_STLSOFT_NO_NAMESPACE */
01044 
01045 //using ::winstl::c_str_ptr_null;
01046 
01047 using ::winstl::c_str_ptr;
01048 
01049 //using ::winstl::c_str_len;
01050 
01051 //using ::winstl::c_str_size;
01052 
01053 using ::winstl::is_empty;
01054 
01055 # if !defined(_STLSOFT_NO_NAMESPACE) && \
01056      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
01057 } // namespace stlsoft
01058 # else /* ? _STLSOFT_NO_NAMESPACE */
01059 /* There is no stlsoft namespace, so must define in the global namespace */
01060 # endif /* !_STLSOFT_NO_NAMESPACE */
01061 #endif /* !_WINSTL_NO_NAMESPACE */
01062 
01063 /* 
01064 
01065 #endif /* WINSTL_INCL_H_WINSTL_FINDFILE_SEQUENCE */
01066 
01067 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004