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
00048 #ifndef COMSTL_INCL_COMSTL_SHIMS_ACCESS_STRING_HPP_VARIANT
00049 #define COMSTL_INCL_COMSTL_SHIMS_ACCESS_STRING_HPP_VARIANT
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define COMSTL_VER_COMSTL_SHIMS_ACCESS_STRING_HPP_VARIANT_MAJOR 5
00053 # define COMSTL_VER_COMSTL_SHIMS_ACCESS_STRING_HPP_VARIANT_MINOR 0
00054 # define COMSTL_VER_COMSTL_SHIMS_ACCESS_STRING_HPP_VARIANT_REVISION 6
00055 # define COMSTL_VER_COMSTL_SHIMS_ACCESS_STRING_HPP_VARIANT_EDIT 115
00056 #endif
00057
00058
00059
00060
00061
00062 #ifndef COMSTL_INCL_COMSTL_H_COMSTL
00063 # include <comstl/comstl.h>
00064 #endif
00065 #ifndef COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS
00066 # include <comstl/string/BSTR_functions.h>
00067 #endif
00068 #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
00069 # include <stlsoft/shims/access/string.hpp>
00070 #endif
00071
00072 #ifndef STLSOFT_INCL_H_WCHAR
00073 # define STLSOFT_INCL_H_WCHAR
00074 # include <wchar.h>
00075 #endif
00076
00077
00078
00079
00080
00081 #ifndef _COMSTL_NO_NAMESPACE
00082 # if defined(_STLSOFT_NO_NAMESPACE) || \
00083 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00084
00085 namespace comstl
00086 {
00087 # else
00088
00089
00090 namespace stlsoft
00091 {
00092
00093 namespace comstl_project
00094 {
00095
00096 # endif
00097 #endif
00098
00099
00100
00101
00102
00110 class c_str_null_VARIANT_proxy
00111 {
00112 public:
00113 typedef c_str_null_VARIANT_proxy class_type;
00114
00115
00116 public:
00120 ss_explicit_k c_str_null_VARIANT_proxy(const BSTR s)
00121 : m_bstr(s)
00122 , m_own(false)
00123 {}
00124
00128 ss_explicit_k c_str_null_VARIANT_proxy(BSTR *ps)
00129 : m_bstr(*ps)
00130 , m_own(true)
00131 {
00132 if(m_own)
00133 {
00134 *ps = NULL;
00135 }
00136 }
00137
00139 c_str_null_VARIANT_proxy()
00140 : m_bstr(NULL)
00141 , m_own(false)
00142 {}
00143
00144 #ifdef STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00153 c_str_null_VARIANT_proxy(class_type& rhs)
00154 : m_bstr(rhs.m_bstr)
00155 , m_own(rhs.m_own)
00156 {
00157 move_lhs_from_rhs(rhs).m_bstr = NULL;
00158 move_lhs_from_rhs(rhs).m_own = false;
00159 }
00160 #else
00161
00162 c_str_null_VARIANT_proxy(class_type const& rhs)
00163 : m_bstr(bstr_dup(rhs.m_bstr))
00164 {}
00165 #endif
00166
00168 ~c_str_null_VARIANT_proxy() stlsoft_throw_0()
00169 {
00170 if(m_own)
00171 {
00172 ::SysFreeString(m_bstr);
00173 }
00174 }
00175
00176
00177 public:
00180 operator LPCOLESTR () const
00181 {
00182 return m_bstr;
00183 }
00184
00185
00186 private:
00187 BSTR m_bstr;
00188 cs_bool_t m_own;
00189
00190
00191 private:
00192 void operator =(class_type const& rhs);
00193 };
00194
00202 class c_str_VARIANT_proxy_w
00203 {
00204 public:
00205 typedef c_str_VARIANT_proxy_w class_type;
00206
00207
00208 public:
00212 ss_explicit_k c_str_VARIANT_proxy_w(BSTR &s)
00213 : m_bstr(s)
00214 {
00215 s = NULL;
00216 }
00217
00218 #ifdef STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00227 c_str_VARIANT_proxy_w(class_type& rhs)
00228 : m_bstr(rhs.m_bstr)
00229 {
00230 move_lhs_from_rhs(rhs).m_bstr = NULL;
00231 }
00232 #else
00233
00234 c_str_VARIANT_proxy_w(class_type const& rhs)
00235 : m_bstr(bstr_dup(rhs.m_bstr))
00236 {}
00237 #endif
00238
00240 ~c_str_VARIANT_proxy_w() stlsoft_throw_0()
00241 {
00242 ::SysFreeString(m_bstr);
00243 }
00244
00245
00246 public:
00248 operator LPCOLESTR () const
00249 {
00250 return (m_bstr == NULL) ? L"" : m_bstr;
00251 }
00252
00253
00254 private:
00255 BSTR m_bstr;
00256
00257
00258 private:
00259 void operator =(class_type const& rhs);
00260 };
00261
00269 class c_str_VARIANT_proxy_a
00270 {
00271 public:
00272 typedef c_str_VARIANT_proxy_a class_type;
00273 typedef c_str_VARIANT_proxy_w class_w_type;
00274
00275
00276 public:
00280 ss_explicit_k c_str_VARIANT_proxy_a(class_w_type rhs)
00281 : m_proxyw(rhs)
00282 , m_buffer(0)
00283 {}
00284
00285 #ifdef STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00294 c_str_VARIANT_proxy_a(class_type& rhs)
00295 : m_proxyw(rhs.m_proxyw)
00296 , m_buffer(rhs.m_buffer)
00297 {
00298 move_lhs_from_rhs(rhs).m_buffer = NULL;
00299 }
00300 #else
00301
00302 c_str_VARIANT_proxy_a(class_type const& rhs)
00303 : m_proxyw(rhs.m_proxyw)
00304 , m_buffer(NULL)
00305 {}
00306 #endif
00307
00309 ~c_str_VARIANT_proxy_a() stlsoft_throw_0()
00310 {
00311 if(m_buffer != empty_string_())
00312 {
00313 ::CoTaskMemFree(m_buffer);
00314 }
00315 }
00316
00317
00318 public:
00320 operator cs_char_a_t const* () const
00321 {
00322 if(NULL == m_buffer)
00323 {
00324 LPCOLESTR w_value = m_proxyw;
00325 cs_char_a_t *&buffer_ = const_cast<class_type*>(this)->m_buffer;
00326
00327 if( NULL == w_value ||
00328 L'\0' == *w_value)
00329 {
00330 buffer_ = empty_string_();
00331 }
00332 else
00333 {
00334 cs_size_t cch = ::SysStringLen((BSTR)w_value);
00335
00336 buffer_ = static_cast<cs_char_a_t *>(::CoTaskMemAlloc((1 + cch) * sizeof(cs_char_a_t)));
00337
00338 if(NULL == buffer_)
00339 {
00340 buffer_ = empty_string_();
00341 }
00342 else
00343 {
00344 int n = ::WideCharToMultiByte(0, 0, w_value, -1, buffer_, static_cast<int>(cch + 1), NULL, NULL);
00345
00346 #ifdef WIN32
00347 if(0 == n)
00348 #else
00349 # error Not currently implemented for operating systems other than Win32
00350 #endif
00351 {
00352
00353 }
00354 }
00355 }
00356 }
00357
00358 return m_buffer;
00359 }
00360
00361
00362 private:
00363 static cs_char_a_t *empty_string_()
00364 {
00365
00366
00367
00368 static cs_char_a_t s_empty[1];
00369
00370 COMSTL_ASSERT(s_empty[0] == '\0');
00371
00372 return s_empty;
00373 }
00374
00375
00376 private:
00377 c_str_VARIANT_proxy_w m_proxyw;
00378 cs_char_a_t *m_buffer;
00379
00380
00381 private:
00382 void operator =(class_type const& rhs);
00383 };
00384
00385
00386
00387
00388
00389
00390 inline cs_bool_t operator ==(LPCOLESTR lhs, c_str_null_VARIANT_proxy const& rhs)
00391 {
00392 return lhs == static_cast<LPCOLESTR>(rhs);
00393 }
00394
00395 inline cs_bool_t operator ==(c_str_null_VARIANT_proxy const& lhs, LPCOLESTR rhs)
00396 {
00397 return static_cast<LPCOLESTR>(lhs) == rhs;
00398 }
00399
00400 inline cs_bool_t operator !=(LPCOLESTR lhs, c_str_null_VARIANT_proxy const& rhs)
00401 {
00402 return lhs != static_cast<LPCOLESTR>(rhs);
00403 }
00404
00405 inline cs_bool_t operator !=(c_str_null_VARIANT_proxy const& lhs, LPCOLESTR rhs)
00406 {
00407 return static_cast<LPCOLESTR>(lhs) != rhs;
00408 }
00409
00410
00411 inline cs_bool_t operator ==(LPCSTR lhs, c_str_VARIANT_proxy_a const& rhs)
00412 {
00413 return lhs == static_cast<LPCSTR>(rhs);
00414 }
00415
00416 inline cs_bool_t operator ==(c_str_VARIANT_proxy_a const& lhs, LPCSTR rhs)
00417 {
00418 return static_cast<LPCSTR>(lhs) == rhs;
00419 }
00420
00421 inline cs_bool_t operator !=(LPCSTR lhs, c_str_VARIANT_proxy_a const& rhs)
00422 {
00423 return lhs != static_cast<LPCSTR>(rhs);
00424 }
00425
00426 inline cs_bool_t operator !=(c_str_VARIANT_proxy_a const& lhs, LPCSTR rhs)
00427 {
00428 return static_cast<LPCSTR>(lhs) != rhs;
00429 }
00430
00431
00432 inline cs_bool_t operator ==(LPCOLESTR lhs, c_str_VARIANT_proxy_w const& rhs)
00433 {
00434 return lhs == static_cast<LPCOLESTR>(rhs);
00435 }
00436
00437 inline cs_bool_t operator ==(c_str_VARIANT_proxy_w const& lhs, LPCOLESTR rhs)
00438 {
00439 return static_cast<LPCOLESTR>(lhs) == rhs;
00440 }
00441
00442 inline cs_bool_t operator !=(LPCOLESTR lhs, c_str_VARIANT_proxy_w const& rhs)
00443 {
00444 return lhs != static_cast<LPCOLESTR>(rhs);
00445 }
00446
00447 inline cs_bool_t operator !=(c_str_VARIANT_proxy_w const& lhs, LPCOLESTR rhs)
00448 {
00449 return static_cast<LPCOLESTR>(lhs) != rhs;
00450 }
00451
00452
00453
00454
00455
00456 template <ss_typename_param_k S>
00457 inline S& operator <<(S& s, c_str_null_VARIANT_proxy const& shim)
00458 {
00459 s << static_cast<LPCOLESTR>(shim);
00460
00461 return s;
00462 }
00463
00464 template <ss_typename_param_k S>
00465 inline S& operator <<(S& s, c_str_VARIANT_proxy_w const& shim)
00466 {
00467 s << static_cast<LPCOLESTR>(shim);
00468
00469 return s;
00470 }
00471
00472 template <ss_typename_param_k S>
00473 inline S& operator <<(S& s, c_str_VARIANT_proxy_a const& shim)
00474 {
00475 s << static_cast<cs_char_a_t const*>(shim);
00476
00477 return s;
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00488
00489 inline c_str_VARIANT_proxy_a c_str_data_a(VARIANT const& v)
00490 {
00491 VARIANT vs;
00492 HRESULT hr;
00493
00494 ::VariantInit(&vs);
00495
00496 hr = ::VariantChangeTypeEx(&vs, const_cast<VARIANT *>(&v), LOCALE_USER_DEFAULT, VARIANT_ALPHABOOL, VT_BSTR);
00497
00498 if(FAILED(hr))
00499 {
00500 vs.bstrVal = NULL;
00501 }
00502
00503 return c_str_VARIANT_proxy_a(c_str_VARIANT_proxy_w(vs.bstrVal));
00504 }
00505
00506 inline c_str_VARIANT_proxy_w c_str_data_w(VARIANT const& v)
00507 {
00508 VARIANT vs;
00509 HRESULT hr;
00510
00511 ::VariantInit(&vs);
00512
00513 hr = ::VariantChangeTypeEx(&vs, const_cast<VARIANT *>(&v), LOCALE_USER_DEFAULT, VARIANT_ALPHABOOL, VT_BSTR);
00514
00515 if(FAILED(hr))
00516 {
00517 vs.bstrVal = NULL;
00518 }
00519
00520 return c_str_VARIANT_proxy_w(vs.bstrVal);
00521 }
00522
00523 #endif
00524
00530 #ifdef UNICODE
00531 inline c_str_VARIANT_proxy_w c_str_data(VARIANT const& v)
00532 #else
00533 inline c_str_VARIANT_proxy_a c_str_data(VARIANT const& v)
00534 #endif
00535 {
00536 #ifdef UNICODE
00537 return c_str_data_w(v);
00538 #else
00539 return c_str_data_a(v);
00540 #endif
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00556 inline cs_size_t c_str_len_a(VARIANT const& v)
00557 {
00558 if( v.vt == VT_NULL ||
00559 v.vt == VT_EMPTY)
00560 {
00561 return 0;
00562 }
00563 else
00564 {
00565 return stlsoft_ns_qual(c_str_len_a)(c_str_data_a(v));
00566 }
00567 }
00568
00574 inline cs_size_t c_str_len_w(VARIANT const& v)
00575 {
00576 if(v.vt == VT_BSTR)
00577 {
00578 return v.bstrVal != NULL ? ::SysStringLen(v.bstrVal) : 0;
00579 }
00580 else if(v.vt == VT_NULL ||
00581 v.vt == VT_EMPTY)
00582 {
00583 return 0;
00584 }
00585 else
00586 {
00587 return stlsoft_ns_qual(c_str_len_w)(c_str_data_w(v));
00588 }
00589 }
00590
00596 inline cs_size_t c_str_len(VARIANT const& v)
00597 {
00598 #ifdef UNICODE
00599 return c_str_len_w(v);
00600 #else
00601 return c_str_len_a(v);
00602 #endif
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00613
00614 inline c_str_VARIANT_proxy_a c_str_ptr_a(VARIANT const& v)
00615 {
00616 return c_str_data_a(v);
00617 }
00618
00619 inline c_str_VARIANT_proxy_w c_str_ptr_w(VARIANT const& v)
00620 {
00621 return c_str_data_w(v);
00622 }
00623
00624 #endif
00625
00631 #ifdef UNICODE
00632 inline c_str_VARIANT_proxy_w c_str_ptr(VARIANT const& v)
00633 #else
00634 inline c_str_VARIANT_proxy_a c_str_ptr(VARIANT const& v)
00635 #endif
00636 {
00637 #ifdef UNICODE
00638 return c_str_ptr_w(v);
00639 #else
00640 return c_str_ptr_a(v);
00641 #endif
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00656
00657
00658
00659
00660 inline c_str_null_VARIANT_proxy c_str_ptr_null_w(VARIANT const& v)
00661 {
00662 if(v.vt == VT_BSTR)
00663 {
00664 return c_str_null_VARIANT_proxy(v.bstrVal);
00665 }
00666 else if(v.vt == VT_NULL ||
00667 v.vt == VT_EMPTY)
00668 {
00669 return c_str_null_VARIANT_proxy();
00670 }
00671 else
00672 {
00673 VARIANT vs;
00674 HRESULT hr;
00675
00676 ::VariantInit(&vs);
00677
00678 hr = ::VariantChangeTypeEx(&vs, const_cast<VARIANT *>(&v), LOCALE_USER_DEFAULT, VARIANT_ALPHABOOL, VT_BSTR);
00679
00680 if(FAILED(hr))
00681 {
00682 vs.bstrVal = NULL;
00683 }
00684
00685 return c_str_null_VARIANT_proxy(&vs.bstrVal);
00686 }
00687 }
00688
00690
00691
00692 #ifdef STLSOFT_UNITTEST
00693 # include "./unittest/variant_unittest_.h"
00694 #endif
00695
00696
00697
00698 #ifndef _COMSTL_NO_NAMESPACE
00699 # if defined(_STLSOFT_NO_NAMESPACE) || \
00700 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00701 }
00702 # else
00703 }
00704 }
00705 # endif
00706 #endif
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 #ifndef _COMSTL_NO_NAMESPACE
00717 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00718 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00719 namespace stlsoft
00720 {
00721 # else
00722
00723 # endif
00724
00725 using ::comstl::c_str_data_a;
00726 using ::comstl::c_str_data_w;
00727
00728 using ::comstl::c_str_data;
00729
00730 using ::comstl::c_str_len_a;
00731 using ::comstl::c_str_len_w;
00732
00733 using ::comstl::c_str_len;
00734
00735 using ::comstl::c_str_ptr_a;
00736 using ::comstl::c_str_ptr_w;
00737
00738 using ::comstl::c_str_ptr;
00739
00740
00741 using ::comstl::c_str_ptr_null_w;
00742
00743
00744
00745 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00746 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00747 }
00748 # else
00749
00750 # endif
00751 #endif
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 #if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00762 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00763
00764 # include <iosfwd>
00765
00766 inline comstl_ns_qual_std(basic_ostream)<char>& operator <<(comstl_ns_qual_std(basic_ostream)<char> &stm, comstl_ns_qual(c_str_VARIANT_proxy_a) const& v)
00767 {
00768 return stm << static_cast<char const*>(v);
00769 }
00770
00771 inline comstl_ns_qual_std(basic_ostream)<wchar_t>& operator <<(comstl_ns_qual_std(basic_ostream)<wchar_t> &stm, comstl_ns_qual(c_str_VARIANT_proxy_w) const& v)
00772 {
00773 return stm << static_cast<wchar_t const*>(v);
00774 }
00775
00776 #endif
00777
00778
00779
00780 #endif
00781
00782