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_findvolume_sequence.h

Go to the documentation of this file.
00001 /* 
00002  * File:        winstl_findvolume_sequence.h
00003  *
00004  * Purpose:     Contains the basic_findvolume_sequence template class, and ANSI
00005  *              and Unicode specialisations thereof.
00006  *
00007  * Notes:       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  * Created:     15th January 2002
00013  * Updated:     11th September 2004
00014  *
00015  * Home:        http://stlsoft.org/
00016  *
00017  * Copyright (c) 2002-2004, Matthew Wilson and Synesis Software
00018  * All rights reserved.
00019  *
00020  * Redistribution and use in source and binary forms, with or without
00021  * modification, are permitted provided that the following conditions are met:
00022  *
00023  * - Redistributions of source code must retain the above copyright notice, this
00024  *   list of conditions and the following disclaimer.
00025  * - Redistributions in binary form must reproduce the above copyright notice,
00026  *   this list of conditions and the following disclaimer in the documentation
00027  *   and/or other materials provided with the distribution.
00028  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00029  *   any contributors may be used to endorse or promote products derived from
00030  *   this software without specific prior written permission.
00031  *
00032  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00033  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00034  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00035  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00036  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00037  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00038  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00039  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00040  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00041  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00042  * POSSIBILITY OF SUCH DAMAGE.
00043  *
00044  * 
00045 
00046 
00050 
00051 #ifndef WINSTL_INCL_H_WINSTL_FINDVOLUME_SEQUENCE
00052 #define WINSTL_INCL_H_WINSTL_FINDVOLUME_SEQUENCE
00053 
00054 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00055 # define WINSTL_VER_H_WINSTL_FINDVOLUME_SEQUENCE_MAJOR        2
00056 # define WINSTL_VER_H_WINSTL_FINDVOLUME_SEQUENCE_MINOR        0
00057 # define WINSTL_VER_H_WINSTL_FINDVOLUME_SEQUENCE_REVISION     1
00058 # define WINSTL_VER_H_WINSTL_FINDVOLUME_SEQUENCE_EDIT         62
00059 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00060 
00061 /* 
00062  * Includes
00063  */
00064 
00065 #ifndef WINSTL_INCL_H_WINSTL
00066 # include "winstl.h"                    // Include the WinSTL root header
00067 #endif /* !WINSTL_INCL_H_WINSTL */
00068 #ifndef WINSTL_INCL_H_WINSTL_FILESYSTEM_TRAITS
00069 # include "winstl_filesystem_traits.h"  // filesystem_traits
00070 #endif /* !WINSTL_INCL_H_WINSTL_FILESYSTEM_TRAITS */
00071 #ifndef STLSOFT_INCL_H_STLSOFT_ITERATOR
00072 # include "stlsoft_iterator.h"
00073 #endif /* !STLSOFT_INCL_H_STLSOFT_ITERATOR */
00074 
00075 /* 
00076  * Namespace
00077  */
00078 
00079 #ifndef _WINSTL_NO_NAMESPACE
00080 # if defined(_STLSOFT_NO_NAMESPACE) || \
00081      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00082 /* There is no stlsoft namespace, so must define ::winstl */
00083 namespace winstl
00084 {
00085 # else
00086 /* Define stlsoft::winstl_project */
00087 
00088 namespace stlsoft
00089 {
00090 
00091 namespace winstl_project
00092 {
00093 
00094 # endif /* _STLSOFT_NO_NAMESPACE */
00095 #endif /* !_WINSTL_NO_NAMESPACE */
00096 
00097 /* 
00098 
00101 
00105 
00110 
00111 /* 
00112  * Enumerations
00113  */
00114 
00115 // The FindNextVolume API is not well documented so assume _MAX_PATH
00116 // is sufficient for volume names
00117 enum
00118 {
00119     MAX_VOL_NAME    =   _MAX_PATH   
00120 };
00121 
00122 /* 
00123  * Forward declarations
00124  */
00125 
00126 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00127 
00128 template <ss_typename_param_k C, ss_typename_param_k T>
00129 class basic_findvolume_sequence_value_type;
00130 
00131 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00132 class basic_findvolume_sequence_const_iterator;
00133 
00134 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00135 
00136 /* 
00137  * Classes
00138  */
00139 
00140 // class basic_findvolume_sequence
00147 template<   ss_typename_param_k C
00148 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00149         ,   ss_typename_param_k T = filesystem_traits<C>
00150 #else
00151         ,   ss_typename_param_k T /* = filesystem_traits<C> */
00152 #endif /* __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00153         >
00154 class basic_findvolume_sequence
00155 {
00156 public:
00158     typedef C                                                           char_type;
00160     typedef T                                                           traits_type;
00162     typedef basic_findvolume_sequence<C, T>                             class_type;
00164     typedef basic_findvolume_sequence_value_type<C, T>                  value_type;
00166     typedef basic_findvolume_sequence_const_iterator<C, T, value_type>  const_iterator;
00168     typedef value_type                                                  &reference;
00170     typedef const value_type                                            &const_reference;
00171 
00172 // Iteration
00173 public:
00177     const_iterator  begin() const;
00181     const_iterator  end() const;
00182 
00183 // State
00184 public:
00186     ws_bool_t       empty() const;
00187 };
00188 
00189 /* 
00190  * Typedefs for commonly encountered types
00191  */
00192 
00194 typedef basic_findvolume_sequence<ws_char_a_t, filesystem_traits<ws_char_a_t> >     findvolume_sequence_a;
00196 typedef basic_findvolume_sequence<ws_char_w_t, filesystem_traits<ws_char_w_t> >     findvolume_sequence_w;
00198 typedef basic_findvolume_sequence<TCHAR, filesystem_traits<TCHAR> >                 findvolume_sequence;
00199 
00200 /* 
00201 
00202 // class basic_findvolume_sequence_value_type
00204 template<   ss_typename_param_k C
00205         ,   ss_typename_param_k T
00206         >
00207 class basic_findvolume_sequence_value_type
00208 {
00209 public:
00211     typedef C                                           char_type;
00213     typedef T                                           traits_type;
00215     typedef basic_findvolume_sequence_value_type<C, T>  class_type;
00216 
00217 public:
00219     basic_findvolume_sequence_value_type();
00221     basic_findvolume_sequence_value_type(const class_type &rhs);
00222 private:
00223     basic_findvolume_sequence_value_type(char_type const *vol_name);
00224 public:
00225 
00227     basic_findvolume_sequence_value_type &operator =(const class_type &rhs);
00228 
00229 // Attributes
00230 public:
00232     operator char_type const * () const
00233     {
00234         return m_name;
00235     }
00236 
00237 private:
00238     friend class basic_findvolume_sequence_const_iterator<C, T, class_type>;
00239 
00240     char_type   m_name[MAX_VOL_NAME + 1];
00241 };
00242 
00243 // class basic_findvolume_sequence_const_iterator
00245 template<   ss_typename_param_k C
00246         ,   ss_typename_param_k T
00247         ,   ss_typename_param_k V
00248         >
00249 class basic_findvolume_sequence_const_iterator
00250     : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(input_iterator_tag), V, ws_ptrdiff_t, void, V>
00251 {
00252 public:
00254     typedef C                                                   char_type;
00256     typedef T                                                   traits_type;
00258     typedef V                                                   value_type;
00260     typedef basic_findvolume_sequence_const_iterator<C, T, V>   class_type;
00261 
00264 private:
00265 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00266     struct shared_handle
00267     {
00268     public:
00269         typedef shared_handle       class_type;
00270 
00271     // Members
00272     public:
00273         HANDLE      hSrch;
00274     private:
00275         ss_sint32_t cRefs;
00276 
00277     public:
00278         ss_explicit_k shared_handle(HANDLE h)
00279             : hSrch(h)
00280             , cRefs(1)
00281         {}
00282         void AddRef()
00283         {
00284             ++cRefs;
00285         }
00286         void Release()
00287         {
00288             if(0 == --cRefs)
00289             {
00290                 delete this;
00291             }
00292         }
00293     #if defined(__STLSOFT_COMPILER_IS_GCC)
00294     protected:
00295     #else /* ? __STLSOFT_COMPILER_IS_GCC */
00296     private:
00297     #endif /* __STLSOFT_COMPILER_IS_GCC */
00298         ~shared_handle()
00299         {
00300             winstl_message_assert("Shared search handle being destroyed with outstanding references!", 0 == cRefs);
00301 
00302             if(hSrch != INVALID_HANDLE_VALUE)
00303             {
00304                 traits_type::find_volume_close(hSrch);
00305             }
00306         }
00307 
00308     private:
00309         shared_handle(class_type const &);
00310         class_type &operator =(class_type const &);
00311     };
00312 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00313 
00314 
00317 private:
00318     basic_findvolume_sequence_const_iterator(basic_findvolume_sequence<C, T> const &l, HANDLE hSrch, char_type const *vol_name)
00319         : m_list(&l)
00320         , m_handle(new shared_handle(hSrch))
00321     {
00322         traits_type::str_copy(m_name, vol_name);
00323 
00324         winstl_assert(INVALID_HANDLE_VALUE != hSrch);
00325     }
00326     basic_findvolume_sequence_const_iterator(basic_findvolume_sequence<C, T> const &l);
00327 public:
00329     basic_findvolume_sequence_const_iterator();
00331     basic_findvolume_sequence_const_iterator(const class_type &rhs);
00333     ~basic_findvolume_sequence_const_iterator() winstl_throw_0();
00334 
00336     basic_findvolume_sequence_const_iterator &operator =(const class_type &rhs);
00337 
00338 public:
00340     class_type &operator ++();
00342     class_type operator ++(int);
00344     const value_type operator *() const;
00346     ws_bool_t operator ==(const class_type &rhs) const;
00348     ws_bool_t operator !=(const class_type &rhs) const;
00349 
00350 // Members
00351 private:
00352     friend class basic_findvolume_sequence<C, T>;
00353 
00354     typedef basic_findvolume_sequence<C, T>     list_type;
00355 
00356     list_type const *m_list;
00357     shared_handle   *m_handle;
00358     char_type       m_name[MAX_VOL_NAME + 1];
00359 };
00360 
00362 // Unit-testing
00363 
00364 #ifdef STLSOFT_UNITTEST
00365 
00366 namespace unittest
00367 {
00368     ss_bool_t test_winstl_findvolume_sequence(unittest_reporter *r)
00369     {
00370         using stlsoft::unittest::unittest_initialiser;
00371 
00372         ss_bool_t               bSuccess    =   true;
00373 
00374         unittest_initialiser    init(r, "WinSTL", "findvolume_sequence", __FILE__);
00375 
00376         findvolume_sequence_a   fvsa;
00377         findvolume_sequence_w   fvsw;
00378 
00379         if(fvsa.empty() != fvsw.empty())
00380         {
00381             r->report("findvolume_sequence(ANSI)::empty() != findvolume_sequence(Unicode)::empty()", __LINE__);
00382             bSuccess = false;
00383         }
00384 
00385         return bSuccess;
00386     }
00387 
00388     unittest_registrar    unittest_winstl_findvolume_sequence(test_winstl_findvolume_sequence);
00389 
00390 } // namespace unittest
00391 
00392 #endif /* STLSOFT_UNITTEST */
00393 
00395 // Implementation
00396 
00397 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00398 
00399 // basic_findvolume_sequence
00400 
00401 template <ss_typename_param_k C, ss_typename_param_k T>
00402 inline ss_typename_type_k basic_findvolume_sequence<C, T>::const_iterator basic_findvolume_sequence<C, T>::begin() const
00403 {
00404     char_type   vol_name[MAX_VOL_NAME + 1];
00405     HANDLE      hSrch   =   traits_type::find_first_volume(vol_name, winstl_num_elements(vol_name));
00406 
00407     if(hSrch == INVALID_HANDLE_VALUE)
00408     {
00409         return const_iterator(*this);
00410     }
00411     else
00412     {
00413         return const_iterator(*this, hSrch, vol_name);
00414     }
00415 }
00416 
00417 template <ss_typename_param_k C, ss_typename_param_k T>
00418 inline ss_typename_type_k basic_findvolume_sequence<C, T>::const_iterator basic_findvolume_sequence<C, T>::end() const
00419 {
00420     return const_iterator(*this);
00421 }
00422 
00423 template <ss_typename_param_k C, ss_typename_param_k T>
00424 inline ws_bool_t basic_findvolume_sequence<C, T>::empty() const
00425 {
00426     return begin() == end();
00427 }
00428 
00429 // basic_findvolume_sequence_value_type
00430 
00431 template <ss_typename_param_k C, ss_typename_param_k T>
00432 inline basic_findvolume_sequence_value_type<C, T>::basic_findvolume_sequence_value_type()
00433 {
00434     m_name[0] = '\0';
00435 }
00436 
00437 template <ss_typename_param_k C, ss_typename_param_k T>
00438 inline basic_findvolume_sequence_value_type<C, T>::basic_findvolume_sequence_value_type(const class_type &rhs)
00439 {
00440     traits_type::str_copy(m_name, rhs.m_name);
00441 }
00442 
00443 template <ss_typename_param_k C, ss_typename_param_k T>
00444 inline basic_findvolume_sequence_value_type<C, T>::basic_findvolume_sequence_value_type(char_type const *vol_name)
00445 {
00446     traits_type::str_copy(m_name, vol_name);
00447 }
00448 
00449 template <ss_typename_param_k C, ss_typename_param_k T>
00450 inline ss_typename_type_k basic_findvolume_sequence_value_type<C, T>::class_type &basic_findvolume_sequence_value_type<C, T>::operator =(const class_type &rhs)
00451 {
00452     traits_type::str_copy(m_name, rhs.m_name);
00453 
00454     return *this;
00455 }
00456 
00457 
00458 #if 0
00459 template <ss_typename_param_k C, ss_typename_param_k T>
00460 #ifdef __STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED
00461 inline basic_findvolume_sequence_value_type<C, T>::operator basic_findvolume_sequence<C, T>::char_type const *() const
00462 #else
00463 inline basic_findvolume_sequence_value_type<C, T>::operator char_type const *() const
00464 #endif /* __STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
00465 {
00466     return m_name;
00467 }
00468 #endif /* 0 */
00469 
00470 
00471 // basic_findvolume_sequence_const_iterator
00472 
00473 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00474 inline basic_findvolume_sequence_const_iterator<C, T, V>::basic_findvolume_sequence_const_iterator()
00475     : m_list(NULL)
00476     , m_handle(NULL)
00477 {
00478     m_name[0] = '\0';
00479 }
00480 
00481 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00482 inline basic_findvolume_sequence_const_iterator<C, T, V>::basic_findvolume_sequence_const_iterator(basic_findvolume_sequence<C, T> const &l)
00483     : m_list(&l)
00484     , m_handle(NULL)
00485 {
00486     m_name[0] = '\0';
00487 }
00488 
00489 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00490 inline basic_findvolume_sequence_const_iterator<C, T, V>::basic_findvolume_sequence_const_iterator(const class_type &rhs)
00491     : m_list(rhs.m_list)
00492     , m_handle(rhs.m_handle)
00493 {
00494     if(NULL != m_handle)
00495     {
00496         m_handle->AddRef();
00497     }
00498 }
00499 
00500 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00501 
00502 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00503 inline ss_typename_type_k basic_findvolume_sequence_const_iterator<C, T, V>::class_type &basic_findvolume_sequence_const_iterator<C, T, V>::operator =(ss_typename_type_k basic_findvolume_sequence_const_iterator<C, T, V>::class_type const &rhs)
00504 {
00505     if(NULL != m_handle)
00506     {
00507         m_handle->Release();
00508     }
00509 
00510     m_list      =   rhs.m_list;
00511     m_handle    =   rhs.m_handle;
00512 
00513     if(NULL != m_handle)
00514     {
00515         m_handle->AddRef();
00516     }
00517 
00518     return *this;
00519 }
00520 
00521 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00522 
00523 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00524 inline basic_findvolume_sequence_const_iterator<C, T, V>::~basic_findvolume_sequence_const_iterator() winstl_throw_0()
00525 {
00526     if(NULL != m_handle)
00527     {
00528         m_handle->Release();
00529     }
00530 }
00531 
00532 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00533 inline ss_typename_type_k basic_findvolume_sequence_const_iterator<C, T, V>::class_type &basic_findvolume_sequence_const_iterator<C, T, V>::operator ++()
00534 {
00535     winstl_message_assert("Attempting to increment an invalid iterator!", NULL != m_handle);
00536 
00537     if(!traits_type::find_next_volume(m_handle->hSrch, m_name, winstl_num_elements(m_name)))
00538     {
00539         m_handle->Release();
00540 
00541         m_handle = NULL;
00542     }
00543 
00544     return *this;
00545 }
00546 
00547 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00548 inline ss_typename_type_k basic_findvolume_sequence_const_iterator<C, T, V>::class_type basic_findvolume_sequence_const_iterator<C, T, V>::operator ++(int)
00549 {
00550     class_type  ret(*this);
00551 
00552     operator ++();
00553 
00554     return ret;
00555 }
00556 
00557 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00558 inline const ss_typename_type_k basic_findvolume_sequence_const_iterator<C, T, V>::value_type basic_findvolume_sequence_const_iterator<C, T, V>::operator *() const
00559 {
00560     if(NULL != m_handle)
00561     {
00562         return value_type(m_name);
00563     }
00564     else
00565     {
00566         return value_type();
00567     }
00568 }
00569 
00570 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00571 inline ws_bool_t basic_findvolume_sequence_const_iterator<C, T, V>::operator ==(class_type const &rhs) const
00572 {
00573     ws_bool_t    eq;
00574 
00575     winstl_assert(m_list == rhs.m_list);    // Should only be comparing iterators from same container
00576 
00577     // Not equal if different lists, or if one but not both handles is the INVALID_HANDLE_VALUE
00578     // or if the data is not equal.
00579     if( m_list != rhs.m_list ||
00580         (NULL == m_handle) != (NULL == m_handle) ||
00581         (   NULL != m_handle &&
00582             traits_type::str_compare(m_name, rhs.m_name) != 0))
00583     {
00584         eq = ws_false_v;
00585     }
00586     else
00587     {
00588         eq = ws_true_v;
00589     }
00590 
00591     return eq;
00592 }
00593 
00594 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V>
00595 inline ws_bool_t basic_findvolume_sequence_const_iterator<C, T, V>::operator !=(class_type const &rhs) const
00596 {
00597     return ! operator ==(rhs);
00598 }
00599 
00600 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00601 
00602 /* 
00603 
00605 
00606 /* 
00607 
00608 #ifndef _WINSTL_NO_NAMESPACE
00609 # if defined(_STLSOFT_NO_NAMESPACE) || \
00610      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00611 } // namespace winstl
00612 # else
00613 } // namespace winstl_project
00614 } // namespace stlsoft
00615 # endif /* _STLSOFT_NO_NAMESPACE */
00616 #endif /* !_WINSTL_NO_NAMESPACE */
00617 
00618 /* 
00619 
00620 #endif /* WINSTL_INCL_H_WINSTL_FINDVOLUME_SEQUENCE */
00621 
00622 /* 

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