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
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #ifndef WINSTL_INCL_H_WINSTL
00066 # include "winstl.h"
00067 #endif
00068 #ifndef WINSTL_INCL_H_WINSTL_REG_DEFS
00069 # include "winstl_reg_defs.h"
00070 #endif
00071 #ifndef WINSTL_INCL_H_WINSTL_REG_TRAITS
00072 # include "winstl_reg_traits.h"
00073 #endif
00074 #ifndef WINSTL_INCL_H_WINSTL_REG_KEY
00075 # include "winstl_reg_key.h"
00076 #endif
00077 #ifndef STLSOFT_INCL_H_STLSOFT_AUTO_DESTRUCTOR
00078 # include "stlsoft_auto_buffer.h"
00079 #endif
00080 #ifndef WINSTL_INCL_H_WINSTL_AUTO_DESTRUCTOR
00081 # include "winstl_processheap_allocator.h"
00082 #endif
00083 #ifndef STLSOFT_INCL_H_STLSOFT_ITERATOR
00084 # include "stlsoft_iterator.h"
00085 #endif
00086
00087
00088
00089
00090
00091 #ifndef _WINSTL_NO_NAMESPACE
00092 # if defined(_STLSOFT_NO_NAMESPACE) || \
00093 defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00094
00095 namespace winstl
00096 {
00097 # else
00098
00099
00100 namespace stlsoft
00101 {
00102
00103 namespace winstl_project
00104 {
00105
00106 # endif
00107 #endif
00108
00109
00110
00113
00114
00115
00116
00117
00118 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00119
00120 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00121 class basic_reg_key_sequence_const_iterator;
00122
00123 #endif
00124
00125
00126
00127
00128
00129
00135
00136 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00137 , ss_typename_param_k T = reg_traits<C>
00138 , ss_typename_param_k A = processheap_allocator<C>
00139 #else
00140 , ss_typename_param_k T
00141 , ss_typename_param_k A
00142 #endif
00143 >
00144 class basic_reg_key_sequence
00145 {
00146 public:
00148 typedef C char_type;
00150 typedef T traits_type;
00152 typedef A allocator_type;
00154 typedef basic_reg_key_sequence<C, T, A> class_type;
00156 typedef basic_reg_key<C, T, A> key_type;
00158 typedef const key_type value_type;
00160 typedef ss_typename_type_k traits_type::size_type size_type;
00162 typedef basic_reg_key<C, T, A> reg_key_type;
00164 typedef basic_reg_key_sequence_const_iterator<C, T, value_type, A> const_iterator;
00166 typedef key_type &reference;
00168 typedef key_type const &const_reference;
00170 typedef ss_typename_type_k traits_type::hkey_type hkey_type;
00172 typedef ws_ptrdiff_t difference_type;
00174 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00175 typedef stlsoft_ns_qual(const_reverse_bidirectional_iterator_base)< const_iterator,
00176 value_type,
00177 value_type,
00178 void*,
00179 difference_type> const_reverse_iterator;
00180 #endif
00181
00182
00183 public:
00185 basic_reg_key_sequence(hkey_type hkey, char_type const *sub_key_name)
00186 : m_hkey(NULL)
00187 {
00188 if(0 != traits_type::reg_open_key(hkey, sub_key_name, &m_hkey))
00189 {
00190 m_hkey = NULL;
00191 }
00192 }
00193
00195 basic_reg_key_sequence(reg_key_type const &key);
00197 ~basic_reg_key_sequence() winstl_throw_0();
00198
00199
00200 public:
00204 const_iterator begin() const;
00208 const_iterator end() const;
00209
00210 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00214 const_reverse_iterator rbegin() const;
00218 const_reverse_iterator rend() const;
00219 #endif
00220
00221
00222 public:
00224 size_type size() const;
00226 ws_bool_t empty() const;
00228 static size_type max_size();
00229
00230
00231 private:
00232 ss_typename_type_k traits_type::hkey_type m_hkey;
00233
00234
00235 private:
00236 basic_reg_key_sequence(class_type const &);
00237 basic_reg_key_sequence const &operator =(class_type const &);
00238 };
00239
00240
00242 typedef basic_reg_key_sequence<ws_char_a_t, reg_traits<ws_char_a_t>, processheap_allocator<ws_char_a_t> > reg_key_sequence_a;
00244 typedef basic_reg_key_sequence<ws_char_w_t, reg_traits<ws_char_w_t>, processheap_allocator<ws_char_w_t> > reg_key_sequence_w;
00245
00246
00253
00254 , ss_typename_param_k T
00255 , ss_typename_param_k V
00256 , ss_typename_param_k A
00257 >
00258 class basic_reg_key_sequence_const_iterator
00259 : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(bidirectional_iterator_tag), V, ws_ptrdiff_t, void *, V>
00260 {
00261 public:
00263 typedef C char_type;
00265 typedef T traits_type;
00267 typedef V value_type;
00269 typedef A allocator_type;
00271 typedef basic_reg_key_sequence_const_iterator<C, T, V, A> class_type;
00273 typedef ss_typename_type_k traits_type::size_type size_type;
00275 typedef ss_typename_type_k traits_type::difference_type difference_type;
00277 typedef ss_typename_type_k traits_type::string_type string_type;
00279 typedef ws_sint32_t index_type;
00281 typedef ss_typename_type_k traits_type::hkey_type hkey_type;
00282
00283
00284 private:
00285 basic_reg_key_sequence_const_iterator(hkey_type hkey, index_type index, string_type const &sub_key_name, size_type maxKnown)
00286 : m_hkey(hkey)
00287 , m_index(index)
00288 , m_name(sub_key_name)
00289 , m_maxKnown(maxKnown)
00290 {}
00292 basic_reg_key_sequence_const_iterator(hkey_type hkey, index_type index, char_type const *sub_key_name, size_type maxKnown)
00293 : m_hkey(hkey)
00294 , m_index(index)
00295 , m_name(sub_key_name)
00296 , m_maxKnown(maxKnown)
00297 {}
00298 basic_reg_key_sequence_const_iterator(hkey_type hkey)
00299 : m_hkey(hkey)
00300 , m_index(sentinel_())
00301 , m_maxKnown(0)
00302 {}
00303 public:
00305 basic_reg_key_sequence_const_iterator();
00307 basic_reg_key_sequence_const_iterator(class_type const &rhs);
00309 ~basic_reg_key_sequence_const_iterator() winstl_throw_0();
00310
00312 basic_reg_key_sequence_const_iterator &operator =(class_type const &rhs);
00313
00314
00315 public:
00317 class_type &operator ++();
00319 class_type &operator --();
00321 const class_type operator ++(int);
00323 const class_type operator --(int);
00325 const value_type operator *() const;
00327 ws_bool_t operator ==(class_type const &rhs) const;
00329 ws_bool_t operator !=(class_type const &rhs) const;
00330
00331
00332 private:
00333 static index_type sentinel_();
00334
00335
00336 private:
00337 friend class basic_reg_key_sequence<C, T, A>;
00338
00339 hkey_type m_hkey;
00340 index_type m_index;
00341 string_type m_name;
00342 size_type m_maxKnown;
00343 };
00344
00346
00347
00348 #ifdef STLSOFT_UNITTEST
00349
00350 namespace unittest
00351 {
00352 ss_bool_t test_winstl_reg_key_sequence(unittest_reporter *r)
00353 {
00354 using stlsoft::unittest::unittest_initialiser;
00355
00356 ss_bool_t bSuccess = true;
00357
00358 unittest_initialiser init(r, "WinSTL", "reg_key_sequence", __FILE__);
00359
00360 #if 0
00361 if(<<TODO>>)
00362 {
00363 r->report("<<TODO>> failed ", __LINE__);
00364 bSuccess = false;
00365 }
00366 #endif
00367
00368 return bSuccess;
00369 }
00370
00371 unittest_registrar unittest_winstl_reg_key_sequence(test_winstl_reg_key_sequence);
00372
00373 }
00374
00375 #endif
00376
00378
00379
00380 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00381
00382
00383
00384 #if 0
00385 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00386 inline basic_reg_key_sequence<C, T, A>::basic_reg_key_sequence(basic_reg_key_sequence<C, T, A>::hkey_type hkey, basic_reg_key_sequence<C, T, A>::char_type const *sub_key_name)
00387 : m_hkey(NULL)
00388 {
00389 if(0 != traits_type::reg_open_key(hkey, sub_key_name, &m_hkey))
00390 {
00391 m_hkey = NULL;
00392 }
00393 }
00394 #endif
00395
00396 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00397 inline basic_reg_key_sequence<C, T, A>::basic_reg_key_sequence(ss_typename_type_k basic_reg_key_sequence<C, T, A>::reg_key_type const &key)
00398 : m_hkey(traits_type::key_dup(key.m_hkey))
00399 {}
00400
00401 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00402 inline basic_reg_key_sequence<C, T, A>::~basic_reg_key_sequence() winstl_throw_0()
00403 {
00404 if(m_hkey != NULL)
00405 {
00406 ::RegCloseKey(m_hkey);
00407 }
00408 }
00409
00410 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00411 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::const_iterator basic_reg_key_sequence<C, T, A>::begin() const
00412 {
00413 typedef stlsoft_ns_qual(auto_buffer)<char_type, allocator_type, CCH_REG_API_AUTO_BUFFER> buffer_t;
00414
00415
00416 size_type cch_key_name = 0;
00417 size_type c_sub_keys = 0;
00418 ws_long_t res = traits_type::reg_query_info(m_hkey, NULL, NULL, &c_sub_keys, &cch_key_name, NULL, NULL, NULL, NULL, NULL, NULL);
00419
00420 if( 0 == res &&
00421 0 < c_sub_keys)
00422 {
00423 size_type const maxKnown = ++cch_key_name;
00424 buffer_t buffer(maxKnown);
00425
00426 res = traits_type::reg_enum_key(m_hkey, 0, buffer, &cch_key_name, NULL, NULL, NULL);
00427
00428 if(res == 0)
00429 {
00430 buffer[cch_key_name] = 0;
00431
00432 return const_iterator(m_hkey, 0, buffer.data(), maxKnown);
00433 }
00434 }
00435
00436 return end();
00437 }
00438
00439 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00440 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::const_iterator basic_reg_key_sequence<C, T, A>::end() const
00441 {
00442 return const_iterator(m_hkey);
00443 }
00444
00445 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00446 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00447 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::const_reverse_iterator basic_reg_key_sequence<C, T, A>::rbegin() const
00448 {
00449 return const_reverse_iterator(end());
00450 }
00451
00452 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00453 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::const_reverse_iterator basic_reg_key_sequence<C, T, A>::rend() const
00454 {
00455 return const_reverse_iterator(begin());
00456 }
00457 #endif
00458
00459 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00460 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::size_type basic_reg_key_sequence<C, T, A>::size() const
00461 {
00462 ws_uint_t c_sub_keys;
00463 ws_long_t res = traits_type::reg_query_info(m_hkey, NULL, NULL, &c_sub_keys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
00464
00465 if(res != 0)
00466 {
00467 c_sub_keys = 0;
00468 }
00469
00470 return static_cast<size_type>(c_sub_keys);
00471 }
00472
00473 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00474 inline ws_bool_t basic_reg_key_sequence<C, T, A>::empty() const
00475 {
00476 return size() == 0;
00477 }
00478
00479 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00480 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::size_type basic_reg_key_sequence<C, T, A>::max_size()
00481 {
00482 return static_cast<size_type>(-1);
00483 }
00484
00485
00486
00487 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00488 inline ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::index_type basic_reg_key_sequence_const_iterator<C, T, V, A>::sentinel_()
00489 {
00490 return 0x7fffffff;
00491 }
00492
00493 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00494 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::basic_reg_key_sequence_const_iterator()
00495 : m_hkey(NULL)
00496 , m_index(sentinel_())
00497 , m_maxKnown(0)
00498 {}
00499
00500 #if 0
00501 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00502 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::basic_reg_key_sequence_const_iterator(ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::hkey_type hkey, ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::index_type basic_reg_key_sequence_const_iterator<C, T, V, A>::index, ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::string_type const &sub_key_name)
00503 : m_hkey(hkey)
00504 , m_index(index)
00505 , m_name(sub_key_name)
00506 , m_maxKnown(0)
00507 {}
00508 #endif
00509
00510 #if 0
00511 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00512 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::basic_reg_key_sequence_const_iterator(ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::hkey_type hkey)
00513 : m_hkey(hkey)
00514 , m_index(sentinel_())
00515 , m_maxKnown(0)
00516 {}
00517 #endif
00518
00519 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00520 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::basic_reg_key_sequence_const_iterator(class_type const &rhs)
00521 : m_hkey(rhs.m_hkey)
00522 , m_index(rhs.m_index)
00523 , m_name(rhs.m_name)
00524 , m_maxKnown(rhs.m_maxKnown)
00525 {}
00526
00527 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00528 inline ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type &basic_reg_key_sequence_const_iterator<C, T, V, A>::operator =(ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type const &rhs)
00529 {
00530
00531
00532
00533 m_hkey = rhs.m_hkey;
00534 m_index = rhs.m_index;
00535 m_name = rhs.m_name;
00536
00537 return *this;
00538 }
00539
00540 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00541 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::~basic_reg_key_sequence_const_iterator() winstl_throw_0()
00542 {}
00543
00544 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00545 inline ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type &basic_reg_key_sequence_const_iterator<C, T, V, A>::operator ++()
00546 {
00547 stlsoft_message_assert("Attempting to increment an invalid iterator!", sentinel_() != m_index);
00548
00549 typedef stlsoft_ns_qual(auto_buffer)<char_type, allocator_type, CCH_REG_API_AUTO_BUFFER> buffer_t;
00550
00551
00552 size_type cch_key_name = m_maxKnown;
00553 buffer_t buffer(cch_key_name);
00554 ws_long_t res = (0 == m_maxKnown) ? ERROR_MORE_DATA : traits_type::reg_enum_key(m_hkey, 1 + m_index, buffer, &cch_key_name, NULL, NULL, NULL);
00555
00556
00557
00558 if(ERROR_MORE_DATA == res)
00559 {
00560 if(0 != traits_type::reg_query_info(m_hkey, NULL, NULL, NULL, &cch_key_name, NULL, NULL, NULL, NULL, NULL, NULL))
00561 {
00562 m_index = sentinel_();
00563 }
00564 else
00565 {
00566 m_maxKnown = 1 + cch_key_name;
00567
00568 if(buffer.resize(cch_key_name))
00569 {
00570 res = traits_type::reg_enum_key(m_hkey, 1 + m_index, buffer, &cch_key_name, NULL, NULL, NULL);
00571 }
00572 }
00573 }
00574
00575 if(res == 0)
00576 {
00577 buffer[cch_key_name] = 0;
00578
00579 m_name = buffer.data();
00580
00581 ++m_index;
00582 }
00583 else
00584 {
00585 m_index = sentinel_();
00586 }
00587
00588 return *this;
00589 }
00590
00591 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00592 inline ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type &basic_reg_key_sequence_const_iterator<C, T, V, A>::operator --()
00593 {
00594 typedef stlsoft_ns_qual(auto_buffer)<char_type, allocator_type, CCH_REG_API_AUTO_BUFFER> buffer_t;
00595
00596
00597 size_type cch_key_name = 0;
00598 ws_uint_t c_sub_keys;
00599 ws_long_t res = traits_type::reg_query_info(m_hkey, NULL, NULL, &c_sub_keys, &cch_key_name, NULL, NULL, NULL, NULL, NULL, NULL);
00600
00601 if(res == 0)
00602 {
00603 buffer_t buffer(++cch_key_name);
00604
00605
00606 if(m_index == sentinel_())
00607 {
00608
00609 m_index = c_sub_keys;
00610 }
00611
00612
00613 res = traits_type::reg_enum_key(m_hkey, --m_index, buffer, &cch_key_name, NULL, NULL, NULL);
00614
00615 if(res == 0)
00616 {
00617 buffer[cch_key_name] = 0;
00618
00619 m_name = buffer.data();
00620 }
00621 else
00622 {
00623 m_index = sentinel_();
00624 }
00625 }
00626 else
00627 {
00628 m_index = sentinel_();
00629 }
00630
00631 return *this;
00632 }
00633
00634 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00635 inline const ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type basic_reg_key_sequence_const_iterator<C, T, V, A>::operator ++(int)
00636 {
00637 class_type ret(*this);
00638
00639 operator ++();
00640
00641 return ret;
00642 }
00643
00644 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00645 inline const ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type basic_reg_key_sequence_const_iterator<C, T, V, A>::operator --(int)
00646 {
00647 class_type ret(*this);
00648
00649 operator --();
00650
00651 return ret;
00652 }
00653
00654 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00655 inline const ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::value_type basic_reg_key_sequence_const_iterator<C, T, V, A>::operator *() const
00656 {
00657 return value_type(m_hkey, m_name);
00658 }
00659
00660 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00661 inline ws_bool_t basic_reg_key_sequence_const_iterator<C, T, V, A>::operator ==(class_type const &rhs) const
00662 {
00663 winstl_message_assert("Comparing reg_key_sequence iterators from different sequences!", m_hkey == rhs.m_hkey);
00664
00665 return m_index == rhs.m_index;
00666 }
00667
00668 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00669 inline ws_bool_t basic_reg_key_sequence_const_iterator<C, T, V, A>::operator !=(class_type const &rhs) const
00670 {
00671 return ! operator ==(rhs);
00672 }
00673
00674 #endif
00675
00676
00677
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 #endif
00691
00692
00693
00694
00695
00696