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;
00305
00308 public:
00310 basic_search_sequence(char_type const *pattern, recls_uint32_t flags);
00312 basic_search_sequence(char_type const *directory, char_type const *pattern, recls_uint32_t flags);
00314
00317 public:
00321 const_iterator begin() const;
00325 const_iterator end() const;
00327
00330 public:
00332 size_type size() const;
00334 recls_bool_t empty() const;
00336 static size_type max_size();
00338
00341 private:
00343
00346 private:
00347 friend class basic_search_sequence_value_type<C, T>;
00348 friend class basic_search_sequence_const_iterator<C, T, value_type>;
00349
00350 static char_type const *copy_or_null_(char_type *dest, char_type const *src);
00351
00352 char_type const *const m_directory;
00353 char_type const *const m_pattern;
00354
00355 char_type m_directory_[RECLS_PATH_MAX + 1];
00356 char_type m_pattern_[RECLS_PATH_MAX + 1];
00357 recls_uint32_t m_flags;
00359
00360
00361 private:
00362 basic_search_sequence(class_type const &);
00363 basic_search_sequence const &operator =(class_type const &);
00364 };
00365
00366
00367
00368
00369
00371 typedef basic_search_sequence<recls_char_a_t, reclstl_traits<recls_char_a_t> > search_sequence_a;
00373 typedef basic_search_sequence<recls_char_w_t, reclstl_traits<recls_char_w_t> > search_sequence_w;
00374
00375
00376
00377
00381
00382
00383
00384
00385
00388
00390
00392
00394
00396
00398
00400
00403
00405
00406
00407
00408
00409
00410
00411
00413
00414
00416
00418
00421
00423
00424
00425
00426
00428 string_t get_directory() const;
00430 string_t get_directory_path() const;
00432 directory_parts_type get_directory_parts() const;
00434 string_t get_file() const;
00436 string_t get_short_file() const;
00438 string_t get_filename() const;
00440 string_t get_fileext() const;
00441
00442 recls_time_t get_creation_time() const;
00443 recls_time_t get_modification_time() const;
00444 recls_time_t get_last_access_time() const;
00445 recls_time_t get_last_status_change_time() const;
00446
00447 recls_filesize_t get_size() const;
00448
00449 recls_bool_t is_readonly() const;
00450 recls_bool_t is_directory() const;
00451 recls_bool_t is_link() const;
00452
00454 char_type const *c_str() const;
00455
00457 entry_type const &get_entry() const;
00459
00460
00461 private:
00462 friend class basic_search_sequence_const_iterator<C, T, class_type>;
00463
00464 entry_type m_info;
00465 };
00466
00467
00471
00472 , typename T
00473 , typename V
00474 >
00475 class basic_search_sequence_const_iterator
00476 : public stlsoft_ns_qual(iterator_base)<stlsoft_ns_qual_std(input_iterator_tag), V, ptrdiff_t, void, V>
00477 {
00478 public:
00480 typedef C char_type;
00482 typedef T traits_type;
00484 typedef V value_type;
00486 typedef basic_search_sequence_const_iterator<C, T, V> class_type;
00488 typedef ss_typename_type_k traits_type::entry_type entry_type;
00489 private:
00490 typedef basic_search_sequence<C, T> sequence_type;
00491
00492 private:
00493 explicit basic_search_sequence_const_iterator(hrecls_t hSrch)
00494 : m_handle(new rss_shared_handle(hSrch))
00495 {}
00496 public:
00498 basic_search_sequence_const_iterator();
00500 basic_search_sequence_const_iterator(class_type const &rhs);
00502 ~basic_search_sequence_const_iterator();
00503
00504 public:
00506 class_type &operator ++();
00508 void operator ++(int);
00510 const value_type operator *() const;
00512 recls_bool_t operator ==(class_type const &rhs) const;
00514 recls_bool_t operator !=(class_type const &rhs) const;
00515
00516
00517 private:
00518 friend class basic_search_sequence<C, T>;
00519
00520 rss_shared_handle *m_handle;
00521
00522
00523 private:
00524 basic_search_sequence_const_iterator &operator =(class_type const &rhs);
00525 };
00526
00528
00529
00540 template <typename C, typename T>
00541 inline recls_bool_t is_empty(basic_search_sequence<C, T> const &s)
00542 {
00543 return s.empty();
00544 }
00545
00556 template <typename C, typename T>
00557 #ifndef RECLS_DOCUMENTATION_SKIP_SECTION
00558 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)
00559 #else
00560 inline C const *c_str_ptr(basic_search_sequence_value_type<C, T> const &v)
00561 #endif
00562 {
00563 return v.c_str();
00564 }
00565
00567
00568
00569 #ifndef RECLS_DOCUMENTATION_SKIP_SECTION
00570
00571
00572
00573 template <typename C, typename T>
00574 inline typename basic_search_sequence<C, T>::char_type const *basic_search_sequence<C, T>::copy_or_null_(typename basic_search_sequence<C, T>::char_type *dest, typename basic_search_sequence<C, T>::char_type const *src)
00575 {
00576 return (NULL == src) ? NULL : traits_type::str_copy(dest, src);
00577 }
00578
00579
00580
00581 template <typename C, typename T>
00582 inline basic_search_sequence<C, T>::basic_search_sequence(char_type const *pattern, recls_uint32_t flags)
00583 : m_flags(flags)
00584 , m_directory(copy_or_null_(m_directory_, ""))
00585 , m_pattern(copy_or_null_(m_pattern_, pattern))
00586 {}
00587
00588 template <typename C, typename T>
00589 inline basic_search_sequence<C, T>::basic_search_sequence(char_type const *directory, char_type const *pattern, recls_uint32_t flags)
00590 : m_flags(flags)
00591 , m_directory(copy_or_null_(m_directory_, directory))
00592 , m_pattern(copy_or_null_(m_pattern_, pattern))
00593 {}
00594
00595
00596 template <typename C, typename T>
00597 inline ss_typename_type_k basic_search_sequence<C, T>::const_iterator basic_search_sequence<C, T>::begin() const
00598 {
00599 return const_iterator(traits_type::Search(m_directory, m_pattern, m_flags));
00600 }
00601
00602 template <typename C, typename T>
00603 inline ss_typename_type_k basic_search_sequence<C, T>::const_iterator basic_search_sequence<C, T>::end() const
00604 {
00605 return const_iterator();
00606 }
00607
00608
00609 template <typename C, typename T>
00610 inline ss_typename_type_k basic_search_sequence<C, T>::size_type basic_search_sequence<C, T>::size() const
00611 {
00612 const_iterator b = begin();
00613 const_iterator e = end();
00614 size_type c = 0;
00615
00616 for(; b != e; ++b)
00617 {
00618 ++c;
00619 }
00620
00621 return c;
00622 }
00623
00624 template <typename C, typename T>
00625 inline recls_bool_t basic_search_sequence<C, T>::empty() const
00626 {
00627 return begin() == end();
00628 }
00629
00630 template <typename C, typename T>
00631 inline ss_typename_type_k basic_search_sequence<C, T>::size_type basic_search_sequence<C, T>::max_size()
00632 {
00633 return static_cast<size_type>(-1);
00634 }
00635
00636
00637
00638 template <typename C, typename T>
00639 inline basic_search_sequence_value_type<C, T>::basic_search_sequence_value_type()
00640 : m_info(NULL)
00641 {}
00642
00643 template <typename C, typename T>
00644 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)
00645 : m_info(traits_type::CopyDetails(rhs.m_info))
00646 {}
00647
00648 template <typename C, typename T>
00649 inline basic_search_sequence_value_type<C, T>::~basic_search_sequence_value_type()
00650 {
00651 if(NULL != m_info)
00652 {
00653 traits_type::CloseDetails(m_info);
00654 }
00655 }
00656
00657 template <typename C, typename T>
00658 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)
00659 {
00660 if(NULL != m_info)
00661 {
00662 traits_type::CloseDetails(m_info);
00663 }
00664
00665 m_info = traits_type::CopyDetails(rhs.m_info);
00666
00667 return *this;
00668 }
00669
00670 template <typename C, typename T>
00671 inline string_t basic_search_sequence_value_type<C, T>::get_path() const
00672 {
00673 recls_assert(NULL != m_info);
00674
00675 return string_t(m_info->path.begin, m_info->path.end);
00676 }
00677
00678 #ifdef RECLS_PLATFORM_API_WIN32
00679 template <typename C, typename T>
00680 inline ss_typename_type_k basic_search_sequence_value_type<C, T>::char_type basic_search_sequence_value_type<C, T>::get_drive() const
00681 {
00682 char_type chDrive;
00683
00684 return (Recls_GetDriveProperty(m_info, &chDrive), chDrive);
00685 }
00686 #endif
00687
00688 template <typename C, typename T>
00689 inline string_t basic_search_sequence_value_type<C, T>::get_directory() const
00690 {
00691 recls_assert(NULL != m_info);
00692
00693 return string_t(m_info->directory.begin, m_info->directory.end);
00694 }
00695
00696 template <typename C, typename T>
00697 inline string_t basic_search_sequence_value_type<C, T>::get_directory_path() const
00698 {
00699 recls_assert(NULL != m_info);
00700
00701 return string_t(m_info->path.begin, m_info->directory.end);
00702 }
00703
00704 template <typename C, typename T>
00705 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
00706 {
00707 recls_assert(NULL != m_info);
00708
00709 return directory_parts_type(m_info->directoryParts.begin, m_info->directoryParts.end);
00710 }
00711
00712 template <typename C, typename T>
00713 inline string_t basic_search_sequence_value_type<C, T>::get_file() const
00714 {
00715 recls_assert(NULL != m_info);
00716
00717 return string_t(m_info->fileName.begin, m_info->fileExt.end);
00718 }
00719
00720 #if 0
00721 template <typename C, typename T>
00722 inline string_t basic_search_sequence_value_type<C, T>::get_short_file() const
00723 {
00724 return m_info.cAlternateFileName[0] != '\0' ? m_info.cAlternateFileName : m_info.cFileName;
00725 }
00726 #endif
00727
00728 template <typename C, typename T>
00729 inline string_t basic_search_sequence_value_type<C, T>::get_filename() const
00730 {
00731 recls_assert(NULL != m_info);
00732
00733 return string_t(m_info->fileName.begin, m_info->fileName.end);
00734 }
00735
00736 template <typename C, typename T>
00737 inline string_t basic_search_sequence_value_type<C, T>::get_fileext() const
00738 {
00739 recls_assert(NULL != m_info);
00740
00741 return string_t(m_info->fileExt.begin, m_info->fileExt.end);
00742 }
00743
00744 template <typename C, typename T>
00745 inline recls_time_t basic_search_sequence_value_type<C, T>::get_creation_time() const
00746 {
00747 recls_assert(NULL != m_info);
00748
00749 return Recls_GetCreationTime(m_info);
00750 }
00751
00752 template <typename C, typename T>
00753 inline recls_time_t basic_search_sequence_value_type<C, T>::get_modification_time() const
00754 {
00755 recls_assert(NULL != m_info);
00756
00757 return Recls_GetModificationTime(m_info);
00758 }
00759
00760 template <typename C, typename T>
00761 inline recls_time_t basic_search_sequence_value_type<C, T>::get_last_access_time() const
00762 {
00763 recls_assert(NULL != m_info);
00764
00765 return Recls_GetLastAccessTime(m_info);
00766 }
00767
00768 template <typename C, typename T>
00769 inline recls_time_t basic_search_sequence_value_type<C, T>::get_last_status_change_time() const
00770 {
00771 recls_assert(NULL != m_info);
00772
00773 return Recls_GetLastStatusChangeTime(m_info);
00774 }
00775
00776 template <typename C, typename T>
00777 inline recls_filesize_t basic_search_sequence_value_type<C, T>::get_size() const
00778 {
00779 recls_assert(NULL != m_info);
00780
00781 return m_info->size;
00782 }
00783
00784 template <typename C, typename T>
00785 inline recls_bool_t basic_search_sequence_value_type<C, T>::is_readonly() const
00786 {
00787 recls_assert(NULL != m_info);
00788
00789 return Recls_IsFileReadOnly(m_info);
00790 }
00791
00792 template <typename C, typename T>
00793 inline recls_bool_t basic_search_sequence_value_type<C, T>::is_directory() const
00794 {
00795 recls_assert(NULL != m_info);
00796
00797 return Recls_IsFileDirectory(m_info);
00798 }
00799
00800 template <typename C, typename T>
00801 inline recls_bool_t basic_search_sequence_value_type<C, T>::is_link() const
00802 {
00803 recls_assert(NULL != m_info);
00804
00805 return Recls_IsFileLink(m_info);
00806 }
00807
00808 template <typename C, typename T>
00809 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
00810 {
00811 recls_assert(NULL != m_info);
00812
00813 return m_info->path.begin;
00814 }
00815
00816 template <typename C, typename T>
00817 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
00818 {
00819 return m_info;
00820 }
00821
00822
00823
00824 template <typename C, typename T, typename V>
00825 inline basic_search_sequence_const_iterator<C, T, V>::basic_search_sequence_const_iterator()
00826 : m_handle(NULL)
00827 {}
00828
00829 template <typename C, typename T, typename V>
00830 inline basic_search_sequence_const_iterator<C, T, V>::basic_search_sequence_const_iterator(class_type const &rhs)
00831 : m_handle(rhs.m_handle)
00832 {
00833 if(NULL != m_handle)
00834 {
00835 ++m_handle->cRefs;
00836 }
00837 }
00838
00839 template <typename C, typename T, typename V>
00840 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)
00841 {
00842 if(NULL != m_handle)
00843 {
00844 m_handle->Release();
00845 }
00846
00847 m_handle = rhs.m_handle;
00848
00849 if(NULL != m_handle)
00850 {
00851 ++m_handle->cRefs;
00852 }
00853
00854 return *this;
00855 }
00856
00857 template <typename C, typename T, typename V>
00858 inline basic_search_sequence_const_iterator<C, T, V>::~basic_search_sequence_const_iterator()
00859 {
00860 if(NULL != m_handle)
00861 {
00862 m_handle->Release();
00863 }
00864 }
00865
00866 template <typename C, typename T, typename V>
00867 inline ss_typename_type_k basic_search_sequence_const_iterator<C, T, V>::class_type &basic_search_sequence_const_iterator<C, T, V>::operator ++()
00868 {
00869 recls_message_assert("Attempting to increment invalid iterator", NULL != m_handle);
00870
00871 if(RECLS_FAILED(Recls_GetNext(m_handle->hSrch)))
00872 {
00873 m_handle->Release();
00874
00875 m_handle = NULL;
00876 }
00877
00878 return *this;
00879 }
00880
00881 template <typename C, typename T, typename V>
00882 inline void basic_search_sequence_const_iterator<C, T, V>::operator ++(int)
00883 {
00884 operator ++();
00885 }
00886
00887 template <typename C, typename T, typename V>
00888 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
00889 {
00890 entry_type info;
00891
00892 recls_message_assert("Attempting to dereference invalid iterator", NULL != m_handle);
00893
00894 if( m_handle->hSrch != NULL &&
00895 RECLS_SUCCEEDED(traits_type::GetDetails(m_handle->hSrch, &info)))
00896 {
00897 return value_type(info);
00898 }
00899 else
00900 {
00901 recls_message_assert("Dereferencing end()-valued iterator", 0);
00902
00903 return value_type();
00904 }
00905 }
00906
00907 template <typename C, typename T, typename V>
00908 inline recls_bool_t basic_search_sequence_const_iterator<C, T, V>::operator ==(class_type const &rhs) const
00909 {
00910 return (m_handle == NULL) && (rhs.m_handle == NULL);
00911 }
00912
00913 template <typename C, typename T, typename V>
00914 inline recls_bool_t basic_search_sequence_const_iterator<C, T, V>::operator !=(class_type const &rhs) const
00915 {
00916 return ! operator ==(rhs);
00917 }
00918
00919 #endif
00920
00921
00922
00923
00924
00925 }
00926 #endif
00927
00928
00929
00930
00931
00932