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
00052 #ifndef STLSOFT_INCL_STLSOFT_FILESYSTEM_HPP_SEARCHSPEC_SEQUENCE
00053 #define STLSOFT_INCL_STLSOFT_FILESYSTEM_HPP_SEARCHSPEC_SEQUENCE
00054
00055 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00056 # define STLSOFT_VER_STLSOFT_FILESYSTEM_HPP_SEARCHSPEC_SEQUENCE_MAJOR 4
00057 # define STLSOFT_VER_STLSOFT_FILESYSTEM_HPP_SEARCHSPEC_SEQUENCE_MINOR 1
00058 # define STLSOFT_VER_STLSOFT_FILESYSTEM_HPP_SEARCHSPEC_SEQUENCE_REVISION 6
00059 # define STLSOFT_VER_STLSOFT_FILESYSTEM_HPP_SEARCHSPEC_SEQUENCE_EDIT 59
00060 #endif
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00078 # include <stlsoft/stlsoft.h>
00079 #endif
00080
00081 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00082 _MSC_VER < 1200
00083 # error stlsoft/filesystem/searchspec_sequence.hpp is not compatible with Visual C++ 5.0 or earlier
00084 #endif
00085
00086 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_SIMPLE_STRING
00087 # include <stlsoft/string/simple_string.hpp>
00088 #endif
00089 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_TOKENISER
00090 # include <stlsoft/string/string_tokeniser.hpp>
00091 #endif
00092
00093 #ifndef STLSOFT_COMPILER_IS_WATCOM
00094 # ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00095 # include <stlsoft/util/std/iterator_helper.hpp>
00096 # endif
00097 #endif
00098 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00099 # include <stlsoft/collections/util/collections.hpp>
00100 #endif
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 #ifndef _STLSOFT_NO_NAMESPACE
00113 namespace stlsoft
00114 {
00115 #endif
00116
00117
00118
00119
00120
00121 template <ss_typename_param_k T>
00122 inline void call_set_null(T *&pt, void (T::*F)())
00123 {
00124 STLSOFT_ASSERT(NULL != pt);
00125
00126 (pt->*F)();
00127
00128 pt = NULL;
00129 }
00130
00131
00132
00133
00134
00139 template <ss_typename_param_k S>
00140 class searchspec_sequence
00141 : public stl_collection_tag
00142 {
00145 public:
00147 typedef S find_sequence_type;
00149 typedef searchspec_sequence<S> class_type;
00150 private:
00151 typedef searchspec_sequence<S> outer_class_type;
00152 typedef ss_typename_type_k find_sequence_type::traits_type traits_type;
00153 public:
00155 typedef ss_typename_type_k find_sequence_type::char_type char_type;
00157 typedef ss_typename_type_k find_sequence_type::value_type value_type;
00159 typedef ss_typename_type_k find_sequence_type::size_type size_type;
00161 typedef ss_typename_type_k find_sequence_type::const_reference const_reference;
00163 class const_iterator;
00164 private:
00165 typedef basic_simple_string<char_type> string_type;
00166
00167
00168
00169 typedef string_tokeniser<string_type, char_type> tokeniser_type;
00171
00174 public:
00181 searchspec_sequence(char_type const* searchSpec, char_type delimiter)
00182 : m_rootDir(get_root_dir())
00183 , m_searchSpec(searchSpec)
00184 , m_delimiter(delimiter)
00185 , m_flags(0)
00186 {}
00194 searchspec_sequence(char_type const* searchSpec, char_type delimiter, ss_int_t flags)
00195 : m_rootDir(get_root_dir())
00196 , m_searchSpec(searchSpec)
00197 , m_delimiter(delimiter)
00198 , m_flags(flags)
00199 {}
00205 searchspec_sequence(char_type const* rootDir, char_type const* searchSpec, char_type delimiter)
00206 : m_rootDir(rootDir)
00207 , m_searchSpec(searchSpec)
00208 , m_delimiter(delimiter)
00209 , m_flags(0)
00210 {}
00217 searchspec_sequence(char_type const* rootDir, char_type const* searchSpec, char_type delimiter, ss_int_t flags)
00218 : m_rootDir(rootDir)
00219 , m_searchSpec(searchSpec)
00220 , m_delimiter(delimiter)
00221 , m_flags(flags)
00222 {}
00224
00227 private:
00228 struct search_state
00229 {
00230 string_type m_rootDir;
00231 ss_int_t m_flags;
00232 tokeniser_type m_tokens;
00233 ss_typename_type_k tokeniser_type::const_iterator m_tokensNext;
00234 ss_typename_type_k tokeniser_type::const_iterator m_tokensEnd;
00235 find_sequence_type *m_entries;
00236 ss_typename_type_k find_sequence_type::const_iterator m_entriesNext;
00237 ss_typename_type_k find_sequence_type::const_iterator m_entriesEnd;
00238 ss_sint32_t m_cRefs;
00239
00240 private:
00241 search_state(char_type const* rootDir, char_type const* searchSpec, char_type delimiter, ss_int_t flags)
00242 : m_rootDir(rootDir)
00243 , m_flags(flags)
00244 , m_tokens(searchSpec, delimiter)
00245 , m_tokensNext(m_tokens.begin())
00246 , m_tokensEnd(m_tokens.end())
00247 #if defined(STLSOFT_COMPILER_IS_VECTORC)
00248 , m_entries(new find_sequence_type(m_rootDir.c_str(), (*m_tokensNext).c_str(), m_flags))
00249 #else
00250 , m_entries(new find_sequence_type(c_str_ptr(m_rootDir), c_str_ptr(*m_tokensNext), m_flags))
00251 #endif
00252 , m_entriesNext(m_entries->begin())
00253 , m_entriesEnd(m_entries->end())
00254 , m_cRefs(1)
00255 {
00256 while(m_entriesNext == m_entriesEnd)
00257 {
00258 ++m_tokensNext;
00259
00260 if(m_tokensNext == m_tokensEnd)
00261 {
00262 break;
00263 }
00264 else
00265 {
00266 STLSOFT_ASSERT(NULL != m_entries);
00267
00268 stlsoft_destroy_instance_fn(m_entries);
00269 #if defined(STLSOFT_COMPILER_IS_VECTORC)
00270 m_entries = new(m_entries) find_sequence_type(m_rootDir.c_str(), (*m_tokensNext).c_str(), m_flags);
00271 #else
00272 m_entries = new(m_entries) find_sequence_type(c_str_ptr(m_rootDir), c_str_ptr(*m_tokensNext), m_flags);
00273 #endif
00274
00275 m_entriesEnd = m_entries->end();
00276 m_entriesNext = m_entries->begin();
00277 }
00278 }
00279 }
00280
00281 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00282 _MSC_VER < 1300
00283 friend class const_iterator;
00284 #endif
00285
00286 public:
00287 static search_state *create(char_type const* rootDir, char_type const* searchSpec, char_type delimiter, ss_int_t flags)
00288 {
00289 search_state *ss = new search_state(rootDir, searchSpec, delimiter, flags);
00290
00291 if(ss->m_tokensNext == ss->m_tokensEnd)
00292 {
00293 delete ss;
00294
00295 ss = NULL;
00296 }
00297
00298 return ss;
00299 }
00300
00301 public:
00302 bool next()
00303 {
00304 if(m_tokensNext == m_tokensEnd)
00305 {
00306 return false;
00307 }
00308
00309 STLSOFT_ASSERT(m_tokensNext != m_tokensEnd);
00310 STLSOFT_ASSERT(NULL != m_entries || m_tokensNext == m_tokensEnd);
00311
00312
00313
00314
00315
00316
00317 ++m_entriesNext;
00318
00319 while(m_entriesNext == m_entriesEnd)
00320 {
00321 ++m_tokensNext;
00322
00323 if(m_tokensNext == m_tokensEnd)
00324 {
00325 return false;
00326 }
00327 else
00328 {
00329 STLSOFT_ASSERT(NULL != m_entries);
00330
00331 stlsoft_destroy_instance_fn(m_entries);
00332 #if defined(STLSOFT_COMPILER_IS_VECTORC)
00333 m_entries = new(m_entries) find_sequence_type(m_rootDir.c_str(), (*m_tokensNext).c_str(), m_flags);
00334 #else
00335 m_entries = new(m_entries) find_sequence_type(c_str_ptr(m_rootDir), c_str_ptr(*m_tokensNext), m_flags);
00336 #endif
00337
00338 m_entriesEnd = m_entries->end();
00339 m_entriesNext = m_entries->begin();
00340 }
00341 }
00342
00343 return true;
00344 }
00345
00346 void Release()
00347 {
00348 if(0 == --m_cRefs)
00349 {
00350 delete this;
00351 }
00352 }
00353 #if defined(STLSOFT_CF_COMPILER_WARNS_NO_PUBLIC_DTOR)
00354 protected:
00355 #else
00356 private:
00357 #endif
00358 ~search_state() stlsoft_throw_0()
00359 {
00360 delete m_entries;
00361 }
00362 };
00364
00367 public:
00369 class const_iterator
00370 {
00371 private:
00372 typedef const_iterator class_type;
00373
00374 private:
00375 friend class searchspec_sequence<S>;
00376
00377 const_iterator(char_type const* rootDir, char_type const* searchSpec, char_type delimiter, ss_int_t flags)
00378 : m_searchState(search_state::create(rootDir, searchSpec, delimiter, flags))
00379 {}
00380
00381 public:
00383 const_iterator()
00384 : m_searchState(NULL)
00385 {}
00387 ~const_iterator() stlsoft_throw_0()
00388 {
00389 if(NULL != m_searchState)
00390 {
00391 m_searchState->Release();
00392 }
00393 }
00394
00396 const_iterator(class_type const& rhs)
00397 : m_searchState(rhs.m_searchState)
00398 {
00399 if(NULL != m_searchState)
00400 {
00401 ++m_searchState->m_cRefs;
00402 }
00403 }
00404
00405 class_type& operator =(class_type const& rhs)
00406 {
00407 if(NULL != m_searchState)
00408 {
00409 m_searchState->Release();
00410 }
00411
00412 m_searchState = rhs.m_searchState;
00413
00414 if(NULL != m_searchState)
00415 {
00416 ++m_searchState->m_cRefs;
00417 }
00418
00419 return *this;
00420 }
00421
00422 public:
00423 class_type& operator ++()
00424 {
00425 STLSOFT_ASSERT(NULL != m_searchState);
00426
00427 if(!m_searchState->next())
00428 {
00429 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00430 _MSC_VER < 1300
00431 m_searchState->Release();
00432
00433 m_searchState = NULL;
00434 #else
00435 call_set_null(m_searchState, &search_state::Release);
00436 #endif
00437 }
00438
00439 return *this;
00440 }
00441
00442 class_type operator ++(int)
00443 {
00444 class_type ret(*this);
00445
00446 operator ++();
00447
00448 return ret;
00449 }
00450
00452 const value_type operator *() const
00453 {
00454 STLSOFT_ASSERT(NULL != m_searchState);
00455
00456 return *m_searchState->m_entriesNext;
00457 }
00458
00459 ss_bool_t operator ==(class_type const& rhs) const
00460 {
00461
00462 return (NULL == m_searchState) && (NULL == rhs.m_searchState);
00463 }
00464 ss_bool_t operator !=(class_type const& rhs) const
00465 {
00466 return !operator ==(rhs);
00467 }
00468
00469 private:
00470 search_state *m_searchState;
00471 };
00473
00476 public:
00480 const_iterator begin() const
00481 {
00482 #if defined(STLSOFT_COMPILER_IS_VECTORC)
00483 return const_iterator(m_rootDir.c_str(), (m_searchSpec).c_str(), m_delimiter, m_flags);
00484 #else
00485 return const_iterator(c_str_ptr(m_rootDir), c_str_ptr(m_searchSpec), m_delimiter, m_flags);
00486 #endif
00487 }
00491 const_iterator end() const
00492 {
00493 return const_iterator();
00494 }
00496
00499 public:
00501 ss_bool_t empty() const
00502 {
00503 return begin() == end();
00504 }
00506
00509 private:
00510 static char_type const* get_root_dir()
00511 {
00512 static char_type s_rootDir[2] = { '.', '\0' };
00513
00514 return s_rootDir;
00515 }
00517
00520 private:
00521 string_type m_rootDir;
00522 string_type m_searchSpec;
00523 char_type m_delimiter;
00524 ss_int_t m_flags;
00526 };
00527
00529
00530
00531 #ifdef STLSOFT_UNITTEST
00532 # include "./unittest/searchspec_sequence_unittest_.h"
00533 #endif
00534
00536
00537
00538 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00539
00540
00541 #endif
00542
00543
00544
00545 #ifndef _STLSOFT_NO_NAMESPACE
00546 }
00547 #endif
00548
00549
00550
00551 #endif
00552
00553