string_access.hpp
来自「用STL的方式封装了WindowsAPI、COM调用、ACE、ATL、MFC、W」· HPP 代码 · 共 1,042 行 · 第 1/3 页
HPP
1,042 行
void operator =(class_type const &rhs);
};
/// This class provides an intermediary object that may be returned by the
/// c_str_ptr_a() function, such that the text of a given variant
/// may be accessed as a null-terminated string.
class c_str_VARIANT_proxy_a
{
public:
typedef c_str_VARIANT_proxy_a class_type;
typedef c_str_VARIANT_proxy_w class_w_type;
// Construction
public:
/// Constructs an instance of the proxy from the given c_str_VARIANT_proxy_w
///
/// \param rhs The c_str_VARIANT_proxy_w from which the text will be retrieved
ss_explicit_k c_str_VARIANT_proxy_a(class_w_type rhs)
: m_proxyw(rhs)
, m_buffer(0)
{}
#ifdef STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
/// Move constructor
///
/// This <a href = "http://synesis.com.au/resources/articles/cpp/movectors.pdf">move constructor</a>
/// is for circumstances when the compiler does not, or cannot, apply the
/// return value optimisation. It causes the contents of \c rhs to be
/// transferred into the constructing instance. This is completely safe
/// because the \c rhs instance will never be accessed in its own right, so
/// does not need to maintain ownership of its contents.
c_str_VARIANT_proxy_a(class_type &rhs)
: m_proxyw(rhs.m_proxyw)
, m_buffer(rhs.m_buffer)
{
move_lhs_from_rhs(rhs).m_buffer = NULL;
}
#else /* ? STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
// Copy constructor
c_str_VARIANT_proxy_a(class_type const &rhs)
: m_proxyw(rhs.m_proxyw)
, m_buffer(NULL)
{}
#endif /* STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
/// Releases any storage aquired by the proxy
~c_str_VARIANT_proxy_a() stlsoft_throw_0()
{
if(m_buffer != empty_string_())
{
::CoTaskMemFree(m_buffer);
}
}
// Accessors
public:
/// Returns a null-terminated string representing the VARIANT contents.
operator cs_char_a_t const *() const
{
if(NULL == m_buffer)
{
LPCOLESTR w_value = m_proxyw;
cs_char_a_t *&buffer_ = const_cast<class_type*>(this)->m_buffer;
if( NULL == w_value ||
L'\0' == *w_value)
{
buffer_ = empty_string_();
}
else
{
cs_size_t cch = ::SysStringLen((BSTR)w_value);
buffer_ = static_cast<cs_char_a_t *>(::CoTaskMemAlloc((1 + cch) * sizeof(cs_char_a_t)));
if(NULL == buffer_)
{
buffer_ = empty_string_();
}
else
{
#ifdef WIN32
::WideCharToMultiByte(0, 0, w_value, -1, buffer_, static_cast<int>(cch + 1), NULL, NULL);
#else /* ? WIN32 */
# error Not currently implemented for operating systems other than Win32
#endif /* WIN32 */
}
}
}
return m_buffer;
}
// Implementation
private:
static cs_char_a_t *empty_string_()
{
// This character array is initialised to 0, which conveniently happens to
// be the empty string, by the module/application load, so it is
// guaranteed to be valid, and there are no threading/race conditions
static cs_char_a_t s_empty[1];
COMSTL_ASSERT(s_empty[0] == '\0'); // Paranoid check
return s_empty;
}
// Members
private:
c_str_VARIANT_proxy_w m_proxyw;
cs_char_a_t *m_buffer;
// Not to be implemented
private:
void operator =(class_type const &rhs);
};
/* /////////////////////////////////////////////////////////////////////////
* Equivalence testing
*/
// c_str_ptr_GUID_proxy
template <ss_typename_param_k C>
inline cs_bool_t operator ==(C const *lhs, c_str_ptr_GUID_proxy<C> const &rhs)
{
return lhs == static_cast<C const *>(rhs);
}
template <ss_typename_param_k C>
inline cs_bool_t operator ==(c_str_ptr_GUID_proxy<C> const &lhs, C const *rhs)
{
return static_cast<C const *>(lhs) == rhs;
}
template <ss_typename_param_k C>
inline cs_bool_t operator !=(C const *lhs, c_str_ptr_GUID_proxy<C> const &rhs)
{
return lhs != static_cast<C const*>(rhs);
}
template <ss_typename_param_k C>
inline cs_bool_t operator !=(c_str_ptr_GUID_proxy<C> const &lhs, C const *rhs)
{
return static_cast<C const*>(lhs) != rhs;
}
// c_str_null_VARIANT_proxy
inline cs_bool_t operator ==(LPCOLESTR lhs, c_str_null_VARIANT_proxy const &rhs)
{
return lhs == static_cast<LPCOLESTR>(rhs);
}
inline cs_bool_t operator ==(c_str_null_VARIANT_proxy const &lhs, LPCOLESTR rhs)
{
return static_cast<LPCOLESTR>(lhs) == rhs;
}
inline cs_bool_t operator !=(LPCOLESTR lhs, c_str_null_VARIANT_proxy const &rhs)
{
return lhs != static_cast<LPCOLESTR>(rhs);
}
inline cs_bool_t operator !=(c_str_null_VARIANT_proxy const &lhs, LPCOLESTR rhs)
{
return static_cast<LPCOLESTR>(lhs) != rhs;
}
// c_str_VARIANT_proxy_a
inline cs_bool_t operator ==(LPCSTR lhs, c_str_VARIANT_proxy_a const &rhs)
{
return lhs == static_cast<LPCSTR>(rhs);
}
inline cs_bool_t operator ==(c_str_VARIANT_proxy_a const &lhs, LPCSTR rhs)
{
return static_cast<LPCSTR>(lhs) == rhs;
}
inline cs_bool_t operator !=(LPCSTR lhs, c_str_VARIANT_proxy_a const &rhs)
{
return lhs != static_cast<LPCSTR>(rhs);
}
inline cs_bool_t operator !=(c_str_VARIANT_proxy_a const &lhs, LPCSTR rhs)
{
return static_cast<LPCSTR>(lhs) != rhs;
}
// c_str_VARIANT_proxy_w
inline cs_bool_t operator ==(LPCOLESTR lhs, c_str_VARIANT_proxy_w const &rhs)
{
return lhs == static_cast<LPCOLESTR>(rhs);
}
inline cs_bool_t operator ==(c_str_VARIANT_proxy_w const &lhs, LPCOLESTR rhs)
{
return static_cast<LPCOLESTR>(lhs) == rhs;
}
inline cs_bool_t operator !=(LPCOLESTR lhs, c_str_VARIANT_proxy_w const &rhs)
{
return lhs != static_cast<LPCOLESTR>(rhs);
}
inline cs_bool_t operator !=(c_str_VARIANT_proxy_w const &lhs, LPCOLESTR rhs)
{
return static_cast<LPCOLESTR>(lhs) != rhs;
}
/* /////////////////////////////////////////////////////////////////////////
* IOStream compatibility
*/
template< ss_typename_param_k C
, ss_typename_param_k S
>
inline S &operator <<(S & s, c_str_ptr_GUID_proxy<C> const &shim)
{
s << static_cast<C const*>(shim);
return s;
}
template <ss_typename_param_k S>
inline S &operator <<(S & s, c_str_null_VARIANT_proxy const &shim)
{
s << static_cast<LPCOLESTR>(shim);
return s;
}
template <ss_typename_param_k S>
inline S &operator <<(S & s, c_str_VARIANT_proxy_w const &shim)
{
s << static_cast<LPCOLESTR>(shim);
return s;
}
template <ss_typename_param_k S>
inline S &operator <<(S & s, c_str_VARIANT_proxy_a const &shim)
{
s << static_cast<cs_char_a_t const*>(shim);
return s;
}
/* /////////////////////////////////////////////////////////////////////////
* c_str_ptr_null
*
* This can be applied to an expression, and the return value is either a
* pointer to the character string or NULL.
*/
/* GUID */
/// \brief Returns the corresponding ANSI C-string pointer of the GUID \c guid
inline c_str_ptr_GUID_proxy<cs_char_a_t> c_str_ptr_null_a(GUID const &guid)
{
return c_str_ptr_GUID_proxy<cs_char_a_t>(guid);
}
/// \brief Returns the corresponding Unicode C-string pointer of the GUID \c guid
inline c_str_ptr_GUID_proxy<cs_char_w_t> c_str_ptr_null_w(GUID const &guid)
{
return c_str_ptr_GUID_proxy<cs_char_w_t>(guid);
}
/// \brief Returns the corresponding C-string pointer of the GUID \c guid
inline c_str_ptr_GUID_proxy<cs_char_o_t> c_str_ptr_null_o(GUID const &guid)
{
return c_str_ptr_GUID_proxy<cs_char_o_t>(guid);
}
/// \brief Returns the corresponding C-string pointer of the GUID \c guid
inline c_str_ptr_GUID_proxy<TCHAR> c_str_ptr_null(GUID const &guid)
{
#ifdef UNICODE
return c_str_ptr_null_w(guid);
#else /* ? UNICODE */
return c_str_ptr_null_a(guid);
#endif /* UNICODE */
}
/* VARIANT */
/// \brief Returns the corresponding ANSI C-string pointer of the VARIANT \c v, or a null pointer
//inline c_str_null_VARIANT_proxy<cs_char_a_t> c_str_ptr_null_a(VARIANT const &v);
//inline c_str_null_VARIANT_proxy<cs_char_w_t> c_str_ptr_null_w(VARIANT const &v);
//inline c_str_null_VARIANT_proxy<cs_char_o_t> c_str_ptr_null_o(VARIANT const &v);
inline c_str_null_VARIANT_proxy c_str_ptr_null_w(VARIANT const &v)
{
if(v.vt == VT_BSTR)
{
return c_str_null_VARIANT_proxy(v.bstrVal);
}
else if(v.vt == VT_NULL ||
v.vt == VT_EMPTY)
{
return c_str_null_VARIANT_proxy();
}
else
{
VARIANT vs;
HRESULT hr;
::VariantInit(&vs);
hr = ::VariantChangeTypeEx(&vs, const_cast<VARIANT *>(&v), LOCALE_USER_DEFAULT, 0, VT_BSTR);
if(FAILED(hr))
{
vs.bstrVal = NULL;
}
return c_str_null_VARIANT_proxy(&vs.bstrVal);
}
}
/* /////////////////////////////////////////////////////////////////////////
* c_str_ptr
*
* This can be applied to an expression, and the return value is either a
* pointer to the character string or to an empty string.
*/
/* GUID */
/// \brief Returns the corresponding ANSI C-string pointer of the GUID \c guid
inline c_str_ptr_GUID_proxy<cs_char_a_t> c_str_ptr_a(GUID const &guid)
{
return c_str_ptr_GUID_proxy<cs_char_a_t>(guid);
}
/// \brief Returns the corresponding Unicode C-string pointer of the GUID \c guid
inline c_str_ptr_GUID_proxy<cs_char_w_t> c_str_ptr_w(GUID const &guid)
{
return c_str_ptr_GUID_proxy<cs_char_w_t>(guid);
}
/// \brief Returns the corresponding C-string pointer of the GUID \c guid
inline c_str_ptr_GUID_proxy<cs_char_o_t> c_str_ptr_o(GUID const &guid)
{
return c_str_ptr_GUID_proxy<cs_char_o_t>(guid);
}
/// \brief Returns the corresponding C-string pointer of the GUID \c guid
inline c_str_ptr_GUID_proxy<TCHAR> c_str_ptr(GUID const &guid)
{
#ifdef UNICODE
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?