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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #ifndef WINSTL_INCL_H_WINSTL
00061 # include "winstl.h"
00062 #endif
00063 #ifndef WINSTL_INCL_H_WINSTL_FILESYSTEM_TRAITS
00064 # include "winstl_filesystem_traits.h"
00065 #endif
00066 #ifndef WINSTL_INCL_H_WINSTL_PROCESSHEAP_ALLOCATOR
00067 # include "winstl_processheap_allocator.h"
00068 #endif
00069 #ifndef WINSTL_INCL_H_WINSTL_SYSTEM_VERSION
00070 # include "winstl_system_version.h"
00071 #endif
00072 #ifndef STLSOFT_INCL_H_STLSOFT_AUTO_BUFFER
00073 # include "stlsoft_auto_buffer.h"
00074 #endif
00075 #ifndef STLSOFT_INCL_H_STLSOFT_ITERATOR
00076 # include "stlsoft_iterator.h"
00077 #endif
00078
00079
00080
00081
00082
00083 #ifndef _WINSTL_NO_NAMESPACE
00084 # if defined(_STLSOFT_NO_NAMESPACE) || \
00085 defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00086
00087 namespace winstl
00088 {
00089 # else
00090
00091
00092 namespace stlsoft
00093 {
00094
00095 namespace winstl_project
00096 {
00097
00098 # endif
00099 #endif
00100
00101
00102
00105
00109
00114
00115
00116
00117
00118
00119
00124
00125 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00126 , ss_typename_param_k T = filesystem_traits<C>
00127 #else
00128 , ss_typename_param_k T
00129 #endif
00130 >
00131 class basic_searchpath_sequence
00132 {
00133 public:
00135 typedef C char_type;
00137 typedef T traits_type;
00139 typedef basic_searchpath_sequence<C, T> class_type;
00141 typedef char_type const *value_type;
00143 typedef value_type *pointer;
00145 typedef const value_type *const_pointer;
00147 typedef value_type &reference;
00149 typedef const value_type &const_reference;
00151 typedef ws_size_t size_type;
00153 typedef ws_ptrdiff_t difference_type;
00155 #if defined(__STLSOFT_COMPILER_IS_BORLAND)
00156 typedef stlsoft_ns_qual(pointer_iterator)< value_type
00157 #else
00158 typedef ss_typename_type_k stlsoft_ns_qual(pointer_iterator)< value_type
00159 #endif
00160 , const_pointer
00161 , const_reference
00162 >::iterator_type const_iterator;
00163 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00164
00165 typedef stlsoft_ns_qual(const_reverse_iterator_base)< const_iterator
00166 , value_type
00167 , const_reference
00168 , const_pointer
00169 , difference_type
00170 > const_reverse_iterator;
00171 #endif
00172
00173
00174 public:
00178 basic_searchpath_sequence();
00184 basic_searchpath_sequence(ws_bool_t bIncludeApplicationDirectory, ws_bool_t bIncludeCurrentDirectory, ws_bool_t bApplicationDirectoryFirst = true);
00186 ~basic_searchpath_sequence() winstl_throw_0();
00187
00188
00189 public:
00193 const_iterator begin() const;
00197 const_iterator end() const;
00198
00199 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00203 const_reverse_iterator rbegin() const;
00207 const_reverse_iterator rend() const;
00208 #endif
00209
00210
00211 public:
00213 size_type size() const;
00215 ws_bool_t empty() const;
00217 static size_type max_size();
00218
00219
00220 public:
00222 value_type operator [](size_type index) const;
00223
00224
00225 private:
00226
00227
00228
00229
00230
00231
00232
00233 typedef processheap_allocator<char_type> main_allocator_type;
00234 typedef processheap_allocator<value_type> value_allocator_type;
00235 typedef stlsoft_ns_qual(auto_buffer)<char_type, main_allocator_type, 1024> main_buffer_type;
00236 typedef stlsoft_ns_qual(auto_buffer)<value_type, value_allocator_type, 24> value_buffer_type;
00237
00238 main_buffer_type m_buffer;
00239 value_buffer_type m_values;
00240 const_iterator m_end;
00241
00242
00243 private:
00244 void _construct(ws_bool_t bIncludeApplicationDirectory, ws_bool_t bIncludeCurrentDirectory, ws_bool_t bApplicationDirectoryFirst);
00245
00246
00247 #ifdef __STLSOFT_COMPILER_IS_BORLAND
00248 typedef ws_int_t init_type;
00249 #else
00250 typedef ws_bool_t init_type;
00251 #endif
00252
00253 static char_type const *get_application_directory()
00254 {
00255 static char_type s_application_directory[_MAX_PATH + 1];
00256 static init_type s_init = ws_false_v;
00257
00258 if(!s_init)
00259 {
00260 char_type dummy[_MAX_PATH + 1];
00261 char_type *file_part;
00262
00263 traits_type::get_module_filename(NULL, s_application_directory, winstl_num_elements(s_application_directory));
00264 traits_type::get_full_path_name(s_application_directory, winstl_num_elements(dummy), dummy, &file_part);
00265 s_application_directory[file_part - &dummy[0]] = '\0';
00266 }
00267
00268 return s_application_directory;
00269 }
00270
00271 static char_type const *get_system_directory()
00272 {
00273 static char_type s_system_directory[_MAX_PATH + 1];
00274 static init_type s_init = (traits_type::get_system_directory(s_system_directory, winstl_num_elements(s_system_directory)), ws_true_v);
00275
00276 return s_system_directory;
00277 }
00278
00279 static char_type const *get_windows_directory()
00280 {
00281 static char_type s_windows_directory[_MAX_PATH + 1];
00282 static init_type s_init = (traits_type::get_windows_directory(s_windows_directory, winstl_num_elements(s_windows_directory)), ws_true_v);
00283
00284 return s_windows_directory;
00285 }
00286
00287 static char_type const *get_system16_directory()
00288 {
00289 static char_type s_system16_directory[_MAX_PATH + 1];
00290 static init_type s_init = ws_false_v;
00291
00292 if(!s_init)
00293 {
00294 if(system_version::winnt())
00295 {
00296 char_type *file_part;
00297
00298 traits_type::get_full_path_name(get_system_directory(), winstl_num_elements(s_system16_directory), s_system16_directory, &file_part);
00299 traits_type::str_copy(file_part, _disgusting_hack("SYSTEM", L"SYSTEM"));
00300 }
00301 else
00302 {
00303 s_system16_directory[0] = '\0';
00304 }
00305
00306 s_init = ws_true_v;
00307 }
00308
00309 return s_system16_directory;
00310 }
00311
00312 static ws_size_t directories_total()
00313 {
00314 ws_size_t cch = 0;
00315
00316 cch += 1 + traits_type::str_len(get_application_directory());
00317 cch += 1 + traits_type::get_current_directory(0, NULL);
00318 cch += 1 + traits_type::str_len(get_system_directory());
00319 cch += 1 + traits_type::str_len(get_system16_directory());
00320 cch += 1 + traits_type::str_len(get_windows_directory());
00321 cch += 1 + traits_type::get_environment_variable(_disgusting_hack("PATH", L"PATH"), NULL, 0);
00322
00323 return cch;
00324 }
00325
00326 static ws_size_t num_paths()
00327 {
00328 ws_size_t cPaths = 0;
00329 ws_size_t cch = traits_type::get_environment_variable(_disgusting_hack("PATH", L"PATH"), NULL, 0);
00330 main_buffer_type buffer(1 + cch);
00331 char_type const *begin = buffer;
00332 char_type const *end = begin + cch;
00333 char_type const *last;
00334
00335 traits_type::get_environment_variable(_disgusting_hack("PATH", L"PATH"), buffer, buffer.size());
00336
00337 for(; begin != end; ++begin)
00338 {
00339 if(*begin != ';')
00340 {
00341 break;
00342 }
00343 }
00344
00345 for(last = begin; begin != end; ++begin)
00346 {
00347 if(*begin == ';')
00348 {
00349 if(1 < begin - last)
00350 {
00351 ++cPaths;
00352 }
00353
00354 last = begin + 1;
00355 }
00356 }
00357
00358 if(1 < begin - last)
00359 {
00360 ++cPaths;
00361 }
00362
00363 return cPaths;
00364 }
00365
00366
00367 static char_type const *_disgusting_hack(ws_char_a_t *literal_a, ws_char_w_t *literal_w)
00368 {
00369 return static_cast<char_type *>((sizeof(char_type) == sizeof(ws_char_w_t)) ? static_cast<void*>(literal_w) : static_cast<void*>(literal_a));
00370 }
00371
00372
00373 private:
00374 basic_searchpath_sequence(class_type const &);
00375 const basic_searchpath_sequence &operator =(class_type const &);
00376 };
00377
00378
00379
00380
00381
00383 typedef basic_searchpath_sequence<ws_char_a_t, filesystem_traits<ws_char_a_t> > searchpath_sequence_a;
00385 typedef basic_searchpath_sequence<ws_char_w_t, filesystem_traits<ws_char_w_t> > searchpath_sequence_w;
00387 typedef basic_searchpath_sequence<TCHAR, filesystem_traits<TCHAR> > searchpath_sequence;
00388
00390
00391
00392 #ifdef STLSOFT_UNITTEST
00393
00394 namespace unittest
00395 {
00396 ss_bool_t test_winstl_searchpath_sequence(unittest_reporter *r)
00397 {
00398 using stlsoft::unittest::unittest_initialiser;
00399
00400 ss_bool_t bSuccess = true;
00401
00402 unittest_initialiser init(r, "WinSTL", "searchpath_sequence", __FILE__);
00403
00404 #if 0
00405 if(<<TODO>>)
00406 {
00407 r->report("<<TODO>> failed ", __LINE__);
00408 bSuccess = false;
00409 }
00410 #endif
00411
00412 return bSuccess;
00413 }
00414
00415 unittest_registrar unittest_winstl_searchpath_sequence(test_winstl_searchpath_sequence);
00416
00417 }
00418
00419 #endif
00420
00422
00423
00424 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00425
00426
00427
00428 template< ss_typename_param_k C
00429 , ss_typename_param_k T
00430 >
00431 inline basic_searchpath_sequence<C, T>::basic_searchpath_sequence()
00432 : m_buffer(directories_total())
00433 , m_values(num_paths() + (system_version::winnt() ? 5 : 4))
00434 {
00435 _construct(true, false, true);
00436 }
00437
00438 template< ss_typename_param_k C
00439 , ss_typename_param_k T
00440 >
00441 inline basic_searchpath_sequence<C, T>::basic_searchpath_sequence(ws_bool_t bIncludeApplicationDirectory, ws_bool_t bIncludeCurrentDirectory, ws_bool_t bApplicationDirectoryFirst )
00442
00443 : m_buffer(directories_total())
00444 , m_values(num_paths() + (system_version::winnt() ? 5 : 4))
00445 {
00446 _construct(bIncludeApplicationDirectory, bIncludeCurrentDirectory, bApplicationDirectoryFirst);
00447 }
00448
00449 template< ss_typename_param_k C
00450 , ss_typename_param_k T
00451 >
00452 inline void basic_searchpath_sequence<C, T>::_construct(ws_bool_t bIncludeApplicationDirectory, ws_bool_t bIncludeCurrentDirectory, ws_bool_t bApplicationDirectoryFirst)
00453 {
00454
00455
00456 char_type *psz = m_buffer;
00457 char_type const **it = m_values.begin();
00458
00459 psz[0] = '\0';
00460
00461 { for(int i = 0; i < 2; ++i) {
00462
00463 if((i & 1) != static_cast<int>(bApplicationDirectoryFirst))
00464 {
00465 if(bIncludeApplicationDirectory)
00466 {
00467 *it++ = psz;
00468
00469
00470 traits_type::str_copy(psz, get_application_directory());
00471 psz += traits_type::str_len(psz);
00472 }
00473 }
00474 else
00475 {
00476 if(bIncludeCurrentDirectory)
00477 {
00478 *it++ = psz;
00479
00480
00481 psz += traits_type::get_current_directory(_MAX_PATH + 1, psz);
00482 }
00483 }
00484
00485 ++psz;
00486 }}
00487
00488
00489 *it++ = psz;
00490 traits_type::str_copy(psz, get_system_directory());
00491 psz += traits_type::str_len(psz);
00492 ++psz;
00493
00494
00495 if(system_version::winnt())
00496 {
00497 *it++ = psz;
00498 traits_type::str_copy(psz, get_system16_directory());
00499 psz += traits_type::str_len(psz);
00500 ++psz;
00501 }
00502
00503
00504 *it++ = psz;
00505 traits_type::str_copy(psz, get_windows_directory());
00506 psz += traits_type::str_len(psz);
00507 ++psz;
00508
00509
00510 char_type const *begin = psz;
00511 char_type const * const end = m_buffer.end();
00512 char_type const *last;
00513
00514 traits_type::get_environment_variable(_disgusting_hack("PATH", L"PATH"), psz, static_cast<DWORD>(end - psz));
00515
00516
00517 for(; begin != end; ++begin)
00518 {
00519 if(*begin != ';')
00520 {
00521 break;
00522 }
00523 }
00524
00525 for(last = begin; begin != end; ++begin)
00526 {
00527 if(*begin == ';')
00528 {
00529 if(1 < begin - last)
00530 {
00531 *it++ = last;
00532 }
00533
00534 *const_cast<char_type*>(begin) = '\0';
00535
00536 last = begin + 1;
00537 }
00538 }
00539
00540 if(1 < begin - last)
00541 {
00542 *it++ = last;
00543 }
00544
00545 m_end = it;
00546 }
00547
00548 template< ss_typename_param_k C
00549 , ss_typename_param_k T
00550 >
00551 inline basic_searchpath_sequence<C, T>::~basic_searchpath_sequence() winstl_throw_0()
00552 {}
00553
00554 template< ss_typename_param_k C
00555 , ss_typename_param_k T
00556 >
00557 inline ss_typename_type_k basic_searchpath_sequence<C, T>::const_iterator basic_searchpath_sequence<C, T>::begin() const
00558 {
00559 return m_values.begin();
00560 }
00561
00562 template< ss_typename_param_k C
00563 , ss_typename_param_k T
00564 >
00565 inline ss_typename_type_k basic_searchpath_sequence<C, T>::const_iterator basic_searchpath_sequence<C, T>::end() const
00566 {
00567 return m_end;
00568 }
00569
00570 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00571 template< ss_typename_param_k C
00572 , ss_typename_param_k T
00573 >
00574 inline ss_typename_type_k basic_searchpath_sequence<C, T>::const_reverse_iterator basic_searchpath_sequence<C, T>::rbegin() const
00575 {
00576 return const_reverse_iterator(end());
00577 }
00578
00579 template< ss_typename_param_k C
00580 , ss_typename_param_k T
00581 >
00582 inline ss_typename_type_k basic_searchpath_sequence<C, T>::const_reverse_iterator basic_searchpath_sequence<C, T>::rend() const
00583 {
00584 return const_reverse_iterator(begin());
00585 }
00586 #endif
00587
00588 template< ss_typename_param_k C
00589 , ss_typename_param_k T
00590 >
00591 inline ss_typename_type_k basic_searchpath_sequence<C, T>::size_type basic_searchpath_sequence<C, T>::size() const
00592 {
00593 return static_cast<size_type>(end() - begin());
00594 }
00595
00596 template< ss_typename_param_k C
00597 , ss_typename_param_k T
00598 >
00599 inline ws_bool_t basic_searchpath_sequence<C, T>::empty() const
00600 {
00601 return begin() == end();
00602 }
00603
00604 template< ss_typename_param_k C
00605 , ss_typename_param_k T
00606 >
00607 inline ss_typename_type_k basic_searchpath_sequence<C, T>::size_type basic_searchpath_sequence<C, T>::max_size()
00608 {
00609
00610 return static_cast<size_type>(-1) / _MAX_PATH;
00611 }
00612
00613 template< ss_typename_param_k C
00614 , ss_typename_param_k T
00615 >
00616 inline ss_typename_type_k basic_searchpath_sequence<C, T>::value_type basic_searchpath_sequence<C, T>::operator [](ss_typename_type_k basic_searchpath_sequence<C, T>::size_type index) const
00617 {
00618 winstl_message_assert("Invalid index in search path sequence", !(size() < index));
00619
00620 return begin()[index];
00621 }
00622
00623 #endif
00624
00625
00626
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 #endif
00640
00641
00642
00643
00644
00645