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
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00077
00078
00079
00080
00081 #ifndef RECLS_INCL_H_RECLSTL
00082 # include "reclstl.h"
00083 #endif
00084 #ifndef RECLS_INCL_H_RECLS_ASSERT
00085 # include <recls_assert.h>
00086 #endif
00087 #ifndef _STLSOFT_INCL_H_STLSOFT_ITERATOR
00088 # include <stlsoft_iterator.h>
00089 #endif
00090
00091 #ifndef _STLSOFT_INCL_H_STLSOFT_PROXY_SEQUENCE
00092 # include <stlsoft_proxy_sequence.h>
00093 #endif
00094
00095
00096
00097
00098
00099 #if !defined(RECLS_NO_NAMESPACE)
00100 namespace recls
00101 {
00102
00103 namespace stl
00104 {
00105 #endif
00106
00107
00108
00109
00110
00111 #ifndef RECLS_DOCUMENTATION_SKIP_SECTION
00112
00113 template< typename C
00114 , typename T
00115 >
00116 class basic_search_sequence_value_type;
00117
00118 template< typename C
00119 , typename T
00120 , typename V
00121 >
00122 class basic_search_sequence_const_iterator;
00123
00124 #endif
00125
00126
00127
00128
00129
00130 #ifndef RECLS_DOCUMENTATION_SKIP_SECTION
00131 struct rss_shared_handle
00132 {
00133 hrecls_t hSrch;
00134 recls_sint32_t cRefs;
00135
00136 public:
00137 explicit rss_shared_handle(hrecls_t h)
00138 : hSrch(h)
00139 , cRefs(1)
00140 {}
00141 void Release()
00142 {
00143 if(--cRefs == 0)
00144 {
00145 delete this;
00146 }
00147 }
00148 #if defined(__STLSOFT_COMPILER_IS_GCC)
00149 protected:
00150 #else
00151 private:
00152 #endif
00153 ~rss_shared_handle()
00154 {
00155 recls_message_assert("Shared search handle being destroyed with outstanding references!", 0 == cRefs);
00156
00157 if(NULL != hSrch)
00158 {
00159 Recls_SearchClose(hSrch);
00160 }
00161 }
00162 };
00163 #endif
00164
00165
00166
00167
00168
00172 template <typename C>
00173 struct reclstl_traits
00174 {
00175 public:
00180 typedef void char_type;
00185 typedef void *entry_type;
00186
00187 public:
00189 static hrecls_t Search(char_type const *searchRoot, char_type const *pattern, recls_uint32_t flags);
00190
00192 static recls_rc_t GetDetails(hrecls_t hSrch, entry_type *pinfo);
00194 static recls_rc_t GetNextDetails(hrecls_t hSrch, entry_type *pinfo);
00195
00197 static void CloseDetails(entry_type fileInfo);
00199 static entry_type CopyDetails(entry_type fileInfo);
00200
00202 static char_type *str_copy(char_type *, char_type const *);
00203 };
00204
00205 #ifndef RECLS_DOCUMENTATION_SKIP_SECTION
00206 template <>
00207 struct reclstl_traits<recls_char_a_t>
00208 {
00209 public:
00210 typedef reclstl_traits<recls_char_a_t> traits_type;
00211 typedef recls_char_a_t char_type;
00212 typedef recls_info_t entry_type;
00213 typedef recls_strptrs_t strptrs_type;
00214 typedef recls_strptrsptrs_t strptrsptrs_type;
00215
00217 typedef stlsoft::proxy_sequence< const strptrs_type
00218 , string_t
00219 , traits_type
00220 > directory_parts_type;
00221
00225 static string_t make_value(strptrs_type const &ptrs)
00226 {
00227 return string_t(ptrs.begin, ptrs.end);
00228 }
00229
00230 public:
00231 static hrecls_t Search(char_type const *searchRoot, char_type const *pattern, recls_uint32_t flags)
00232 {
00233 hrecls_t hSrch;
00234 recls_rc_t rc = Recls_Search(searchRoot, pattern, flags, &hSrch);
00235
00236 return RECLS_SUCCEEDED(rc) ? hSrch : static_cast<hrecls_t>(NULL);
00237 }
00238
00239 static recls_rc_t GetDetails(hrecls_t hSrch, entry_type *pinfo)
00240 {
00241 return Recls_GetDetails(hSrch, pinfo);
00242 }
00243
00244 static recls_rc_t GetNextDetails(hrecls_t hSrch, entry_type *pinfo)
00245 {
00246 return Recls_GetNextDetails(hSrch, pinfo);
00247 }
00248
00249 static void CloseDetails(entry_type fileInfo)
00250 {
00251 Recls_CloseDetails(fileInfo);
00252 }
00253 static entry_type CopyDetails(entry_type fileInfo)
00254 {
00255 entry_type infoCopy;
00256
00257 return RECLS_SUCCEEDED(Recls_CopyDetails(fileInfo, &infoCopy)) ? infoCopy : static_cast<entry_type>(NULL);
00258 }
00259
00260 static char_type *str_copy(char_type *dest, char_type const *src)
00261 {
00262 return strcpy(dest, src);
00263 }
00264 };
00265 #endif
00266
00267
00274
00275 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00276 , typename T = reclstl_traits<C>
00277 #else
00278 , typename T
00279 #endif
00280 >
00281 class basic_search_sequence
00282 {
00285 public:
00287 typedef C char_type;
00289 typedef T traits_type;
00291 typedef basic_search_sequence<C, T> class_type;
00293 typedef basic_search_sequence_value_type<C, T> value_type;
00295 typedef basic_search_sequence_const_iterator<C, T, value_type> const_iterator;
00297 typedef value_type &reference;
00299 typedef value_type const &const_reference;
00301 typedef ss_typename_type_k traits_type::entry_type entry_type;
00303 typedef size_t size_type;
00304
00306
00309 public:
00311 basic_search_sequence(char_type const *searchSpec, recls_uint32_t flags);
00313 basic_search_sequence(char_type const *directory, char_type const *searchSpec, recls_uint32_t flags);
00314
00316
00319 public:
00323 const_iterator begin() const;
00327 const_iterator end() const;
00328
00330
00333 public:
00335 size_type size() const;
00337 recls_bool_t empty() const;
00339 static size_type max_size();
00340
00342
00345 private:
00346 friend class basic_search_sequence_value_type<C, T>;
00347 friend class basic_search_sequence_const_iterator<C, T, value_type>;
00348
00349 char_type m_directory[RECLS_PATH_MAX + 1];
00350 char_type m_search[RECLS_PATH_MAX + 1];
00351 recls_uint32_t m_flags;
00352
00354
00355
00356 private:
00357 basic_search_sequence(class_type const &);
00358 basic_search_sequence const &operator =(class_type const &);
00359 };
00360
00361
00362
00363
00364
00366 typedef basic_search_sequence<recls_char_a_t, reclstl_traits<recls_char_a_t> > search_sequence_a;
00368 typedef basic_search_sequence<recls_char_w_t, reclstl_traits<recls_char_w_t> > search_sequence_w;
00369
00370
00371
00372
00376
00377
00378
00379
00380
00383
00385
00387
00389
00391
00393
00394
00396
00399
00401
00402
00403
00404
00405
00406
00407
00409
00410
00412
00413
00415
00418
00420
00421
00422
00423
00425 string_t get_directory() const;
00427 string_t get_directory_path() const;
00429 directory_parts_type get_directory_parts() const;
00431 string_t get_file() const;
00433 string_t get_short_file() const;
00435 string_t get_filename() const;
00437 string_t get_fileext() const;
00438
00439 recls_time_t get_creation_time() const;
00440 recls_time_t get_modification_time() const;
00441 recls_time_t get_last_access_time() const;
00442 recls_time_t get_last_status_change_time() const;
00443
00444 recls_filesize_t get_size() const;
00445
00446 recls_bool_t is_readonly() const;
00447 recls_bool_t is_directory() const;
00448 recls_bool_t is_link() const;
00449
00451 char_type const *c_str() const;
00452
00454 entry_type const &get_entry() const;
00455
00457
00458
00459 private:
00460 friend class basic_search_sequence_const_iterator<C, T, class_type>;
00461
00462 entry_type m_info;
00463 };
00464
00465
00469
00470 , typename T
00471 , typename V
00472 >
00473 class basic_search_sequence_const_iterator
00474 : public stlsoft_ns_qual(iterator_base)<stlsoft_ns_qual_std(input_iterator_tag), V, ptrdiff_t, void, V>
00475 {
00476 public:
00478 typedef C char_type;
00480 typedef T traits_type;
00482 typedef V value_type;
00484 typedef basic_search_sequence_const_iterator<C, T, V> class_type;
00486 typedef ss_typename_type_k traits_type::entry_type entry_type;
00487 private:
00488 typedef basic_search_sequence<C, T> sequence_type;
00489
00490 private:
00491 explicit basic_search_sequence_const_iterator(hrecls_t hSrch)
00492 : m_handle(new rss_shared_handle(hSrch))
00493 {}
00494 public:
00496 basic_search_sequence_const_iterator();
00498 basic_search_sequence_const_iterator(class_type const &rhs);
00500 ~basic_search_sequence_const_iterator();
00501
00502 public:
00504 class_type &operator ++();
00506 void operator ++(int);
00508 const value_type operator *() const;
00510 recls_bool_t operator ==(class_type const &rhs) const;
00512 recls_bool_t operator !=(class_type const &rhs) const;
00513
00514
00515 private:
00516 friend class basic_search_sequence<C, T>;
00517
00518 rss_shared_handle *m_handle;
00519
00520
00521 private:
00522 basic_search_sequence_const_iterator &operator =(class_type const &rhs);
00523 };
00524
00526
00527
00538 template <typename C, typename T>
00539 inline recls_bool_t is_empty(basic_search_sequence<C, T> const &s)
00540 {
00541 return s.empty();
00542 }
00543
00554 template <typename C, typename T>
00555 #ifndef RECLS_DOCUMENTATION_SKIP_SECTION
00556 inline ss_typename_type_k basic_search_sequence_value_type<C, T>::char_type const *c_str_ptr(basic_search_sequence_value_type<C, T> const &v)
00557 #else
00558 inline C const *c_str_ptr(basic_search_sequence_value_type<C, T> const &v)
00559 #endif
00560 {
00561 return v.c_str();
00562 }
00563
00565
00566
00567 #ifndef RECLS_DOCUMENTATION_SKIP_SECTION
00568
00569
00570
00571
00572 template <typename C, typename T>
00573 inline basic_search_sequence<C, T>::basic_search_sequence(char_type const *searchSpec, recls_uint32_t flags)
00574 : m_flags(flags)
00575 {
00576 m_directory[0] = '\0';
00577 traits_type::str_copy(m_search, searchSpec);
00578 }
00579
00580 template <typename C, typename T>
00581 inline basic_search_sequence<C, T>::basic_search_sequence(char_type const *directory, char_type const * searchSpec, recls_uint32_t flags)
00582 : m_flags(flags)
00583 {
00584 traits_type::str_copy(m_directory, directory);
00585 traits_type::str_copy(m_search, searchSpec);
00586 }
00587
00588
00589 template <typename C, typename T>
00590 inline ss_typename_type_k basic_search_sequence<C, T>::const_iterator basic_search_sequence<C, T>::begin() const
00591 {
00592 return const_iterator(traits_type::Search(m_directory, m_search, m_flags));
00593 }
00594
00595 template <typename C, typename T>
00596 inline ss_typename_type_k basic_search_sequence<C, T>::const_iterator basic_search_sequence<C, T>::end() const
00597 {
00598 return const_iterator();
00599 }
00600
00601
00602 template <typename C, typename T>
00603 inline ss_typename_type_k basic_search_sequence<C, T>::size_type basic_search_sequence<C, T>::size() const
00604 {
00605 const_iterator b = begin();
00606 const_iterator e = end();
00607 size_type c = 0;
00608
00609 for(; b != e; ++b)
00610 {
00611 ++c;
00612 }
00613
00614 return c;
00615 }
00616
00617 template <typename C, typename T>
00618 inline recls_bool_t basic_search_sequence<C, T>::empty() const
00619 {
00620 return begin() == end();
00621 }
00622
00623 template <typename C, typename T>
00624 inline ss_typename_type_k basic_search_sequence<C, T>::size_type basic_search_sequence<C, T>::max_size()
00625 {
00626 return static_cast<size_type>(-1);
00627 }
00628
00629
00630
00631 template <typename C, typename T>
00632 inline basic_search_sequence_value_type<C, T>::basic_search_sequence_value_type()
00633 : m_info(NULL)
00634 {}
00635
00636 template <typename C, typename T>
00637 inline basic_search_sequence_value_type<C, T>::basic_search_sequence_value_type(ss_typename_type_k basic_search_sequence_value_type<C, T>::class_type const &rhs)
00638 : m_info(traits_type::CopyDetails(rhs.m_info))
00639 {}
00640
00641 template <typename C, typename T>
00642 inline basic_search_sequence_value_type<C, T>::~basic_search_sequence_value_type()
00643 {
00644 if(NULL != m_info)
00645 {
00646 traits_type::CloseDetails(m_info);
00647 }
00648 }
00649
00650 template <typename C, typename T>
00651 inline ss_typename_type_k basic_search_sequence_value_type<C, T>::class_type &basic_search_sequence_value_type<C, T>::operator =(ss_typename_type_k basic_search_sequence_value_type<C, T>::class_type const &rhs)
00652 {
00653 if(NULL != m_info)
00654 {
00655 traits_type::CloseDetails(m_info);
00656 }
00657
00658 m_info = traits_type::CopyDetails(rhs.m_info);
00659
00660 return *this;
00661 }
00662
00663 template <typename C, typename T>
00664 inline string_t basic_search_sequence_value_type<C, T>::get_path() const
00665 {
00666 recls_assert(NULL != m_info);
00667
00668 return string_t(m_info->path.begin, m_info->path.end);
00669 }
00670
00671 #ifdef RECLS_PLATFORM_API_WIN32
00672 template <typename C, typename T>
00673 inline ss_typename_type_k basic_search_sequence_value_type<C, T>::char_type basic_search_sequence_value_type<C, T>::get_drive() const
00674 {
00675 char_type chDrive;
00676
00677 return (Recls_GetDriveProperty(m_info, &chDrive), chDrive);
00678 }
00679 #endif
00680
00681 template <typename C, typename T>
00682 inline string_t basic_search_sequence_value_type<C, T>::get_directory() const
00683 {
00684 recls_assert(NULL != m_info);
00685
00686 return string_t(m_info->directory.begin, m_info->directory.end);
00687 }
00688
00689 template <typename C, typename T>
00690 inline string_t basic_search_sequence_value_type<C, T>::get_directory_path() const
00691 {
00692 recls_assert(NULL != m_info);
00693
00694 return string_t(m_info->path.begin, m_info->directory.end);
00695 }
00696
00697 template <typename C, typename T>
00698 inline ss_typename_type_k basic_search_sequence_value_type<C, T>::directory_parts_type basic_search_sequence_value_type<C, T>::get_directory_parts() const
00699 {
00700 recls_assert(NULL != m_info);
00701
00702 return directory_parts_type(m_info->directoryParts.begin, m_info->directoryParts.end);
00703 }
00704
00705 template <typename C, typename T>
00706 inline string_t basic_search_sequence_value_type<C, T>::get_file() const
00707 {
00708 recls_assert(NULL != m_info);
00709
00710 return string_t(m_info->fileName.begin, m_info->fileExt.end);
00711 }
00712
00713 #if 0
00714 template <typename C, typename T>
00715 inline string_t basic_search_sequence_value_type<C, T>::get_short_file() const
00716 {
00717 return m_info.cAlternateFileName[0] != '\0' ? m_info.cAlternateFileName : m_info.cFileName;
00718 }
00719 #endif
00720
00721 template <typename C, typename T>
00722 inline string_t basic_search_sequence_value_type<C, T>::get_filename() const
00723 {
00724 recls_assert(NULL != m_info);
00725
00726 return string_t(m_info->fileName.begin, m_info->fileName.end);
00727 }
00728
00729 template <typename C, typename T>
00730 inline string_t basic_search_sequence_value_type<C, T>::get_fileext() const
00731 {
00732 recls_assert(NULL != m_info);
00733
00734 return string_t(m_info->fileExt.begin, m_info->fileExt.end);
00735 }
00736
00737 template <typename C, typename T>
00738 inline recls_time_t basic_search_sequence_value_type<C, T>::get_creation_time() const
00739 {
00740 recls_assert(NULL != m_info);
00741
00742 return Recls_GetCreationTime(m_info);
00743 }
00744
00745 template <typename C, typename T>
00746 inline recls_time_t basic_search_sequence_value_type<C, T>::get_modification_time() const
00747 {
00748 recls_assert(NULL != m_info);
00749
00750 return Recls_GetModificationTime(m_info);
00751 }
00752
00753 template <typename C, typename T>
00754 inline recls_time_t basic_search_sequence_value_type<C, T>::get_last_access_time() const
00755 {
00756 recls_assert(NULL != m_info);
00757
00758 return Recls_GetLastAccessTime(m_info);
00759 }
00760
00761 template <typename C, typename T>
00762 inline recls_time_t basic_search_sequence_value_type<C, T>::get_last_status_change_time() const
00763 {
00764 recls_assert(NULL != m_info);
00765
00766 return Recls_GetLastStatusChangeTime(m_info);
00767 }
00768
00769 template <typename C, typename T>
00770 inline recls_filesize_t basic_search_sequence_value_type<C, T>::get_size() const
00771 {
00772 recls_assert(NULL != m_info);
00773
00774 return m_info->size;
00775 }
00776
00777 template <typename C, typename T>
00778 inline recls_bool_t basic_search_sequence_value_type<C, T>::is_readonly() const
00779 {
00780 recls_assert(NULL != m_info);
00781
00782 return Recls_IsFileReadOnly(m_info);
00783 }
00784
00785 template <typename C, typename T>
00786 inline recls_bool_t basic_search_sequence_value_type<C, T>::is_directory() const
00787 {
00788 recls_assert(NULL != m_info);
00789
00790 return Recls_IsFileDirectory(m_info);
00791 }
00792
00793 template <typename C, typename T>
00794 inline recls_bool_t basic_search_sequence_value_type<C, T>::is_link() const
00795 {
00796 recls_assert(NULL != m_info);
00797
00798 return Recls_IsFileLink(m_info);
00799 }
00800
00801 template <typename C, typename T>
00802 inline ss_typename_type_k basic_search_sequence_value_type<C, T>::char_type const * basic_search_sequence_value_type<C, T>::c_str() const
00803 {
00804 recls_assert(NULL != m_info);
00805
00806 return m_info->path.begin;
00807 }
00808
00809 template <typename C, typename T>
00810 inline ss_typename_type_k basic_search_sequence_value_type<C, T>::entry_type const &basic_search_sequence_value_type<C, T>::get_entry() const
00811 {
00812 return m_info;
00813 }
00814
00815
00816
00817 template <typename C, typename T, typename V>
00818 inline basic_search_sequence_const_iterator<C, T, V>::basic_search_sequence_const_iterator()
00819 : m_handle(NULL)
00820 {}
00821
00822 template <typename C, typename T, typename V>
00823 inline basic_search_sequence_const_iterator<C, T, V>::basic_search_sequence_const_iterator(class_type const &rhs)
00824 : m_handle(rhs.m_handle)
00825 {
00826 if(NULL != m_handle)
00827 {
00828 ++m_handle->cRefs;
00829 }
00830 }
00831
00832 template <typename C, typename T, typename V>
00833 inline ss_typename_type_k basic_search_sequence_const_iterator<C, T, V>::class_type &basic_search_sequence_const_iterator<C, T, V>::operator =(typename basic_search_sequence_const_iterator<C, T, V>::class_type const &rhs)
00834 {
00835 if(NULL != m_handle)
00836 {
00837 m_handle->Release();
00838 }
00839
00840 m_handle = rhs.m_handle;
00841
00842 if(NULL != m_handle)
00843 {
00844 ++m_handle->cRefs;
00845 }
00846
00847 return *this;
00848 }
00849
00850 template <typename C, typename T, typename V>
00851 inline basic_search_sequence_const_iterator<C, T, V>::~basic_search_sequence_const_iterator()
00852 {
00853 if(NULL != m_handle)
00854 {
00855 m_handle->Release();
00856 }
00857 }
00858
00859 template <typename C, typename T, typename V>
00860 inline ss_typename_type_k basic_search_sequence_const_iterator<C, T, V>::class_type &basic_search_sequence_const_iterator<C, T, V>::operator ++()
00861 {
00862 recls_message_assert("Attempting to increment invalid iterator", NULL != m_handle);
00863
00864 if(RECLS_FAILED(Recls_GetNext(m_handle->hSrch)))
00865 {
00866 m_handle->Release();
00867
00868 m_handle = NULL;
00869 }
00870
00871 return *this;
00872 }
00873
00874 template <typename C, typename T, typename V>
00875 inline void basic_search_sequence_const_iterator<C, T, V>::operator ++(int)
00876 {
00877 operator ++();
00878 }
00879
00880 template <typename C, typename T, typename V>
00881 inline const ss_typename_type_k basic_search_sequence_const_iterator<C, T, V>::value_type basic_search_sequence_const_iterator<C, T, V>::operator *() const
00882 {
00883 entry_type info;
00884
00885 recls_message_assert("Attempting to dereference invalid iterator", NULL != m_handle);
00886
00887 if( m_handle->hSrch != NULL &&
00888 RECLS_SUCCEEDED(traits_type::GetDetails(m_handle->hSrch, &info)))
00889 {
00890 return value_type(info);
00891 }
00892 else
00893 {
00894 recls_message_assert("Dereferencing end()-valued iterator", 0);
00895
00896 return value_type();
00897 }
00898 }
00899
00900 template <typename C, typename T, typename V>
00901 inline recls_bool_t basic_search_sequence_const_iterator<C, T, V>::operator ==(class_type const &rhs) const
00902 {
00903 return (m_handle == NULL) && (rhs.m_handle == NULL);
00904 }
00905
00906 template <typename C, typename T, typename V>
00907 inline recls_bool_t basic_search_sequence_const_iterator<C, T, V>::operator !=(class_type const &rhs) const
00908 {
00909 return ! operator ==(rhs);
00910 }
00911
00912 #endif
00913
00914
00915
00916
00917
00918 }
00919 #endif
00920
00921
00922
00923
00924
00925