📄 bstr.hpp
字号:
m_bstr = bstr_create(s, static_cast<cs_size_t>(len));
}
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
if( NULL == m_bstr &&
NULL != s &&
0 != len &&
'\0' != 0[s])
{
STLSOFT_THROW_X(com_exception("failed to allocate string", HRESULT_FROM_WIN32(::GetLastError())));
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
inline /* explicit */ bstr::bstr(cs_char_w_t const* s, int len /* = -1 */)
{
// Precondition tests
COMSTL_MESSAGE_ASSERT("Default length must be specified by -1. No other -ve value allowed", len >= 0 || len == -1);
COMSTL_MESSAGE_ASSERT("Cannot pass in NULL pointer and -1 (default) length", NULL != s || len >= 0);
// There's a potential problem here (which has actually occurred!):
//
// If s is non-NULL and len is non-negative, it's possible for
// the underlying SysAllocStringLen() to walk into invalid
// memory while searching s.
int actualLen = static_cast<int>(stlsoft_ns_qual(c_str_len)(s));
if( NULL != s &&
len > actualLen)
{
m_bstr = bstr_create(static_cast<cs_char_w_t const*>(NULL), static_cast<cs_size_t>(len));
if(NULL != m_bstr)
{
::wcscpy(m_bstr, s);
}
}
else
{
if(-1 == len)
{
len = actualLen;
}
m_bstr = bstr_create(s, static_cast<cs_size_t>(len));
}
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
if( NULL == m_bstr &&
NULL != s &&
0 != len &&
'\0' != 0[s])
{
STLSOFT_THROW_X(com_exception("failed to allocate string", HRESULT_FROM_WIN32(::GetLastError())));
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
inline bstr::bstr(bstr::size_type n, bstr::char_type ch)
: m_bstr(bstr_create_w(NULL, n))
{
if(NULL == m_bstr)
{
if(0 != n)
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
STLSOFT_THROW_X(com_exception("failed to allocate string", HRESULT_FROM_WIN32(::GetLastError())));
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
}
else
{
{ for(size_type i = 0; i < n; ++i)
{
m_bstr[i] = ch;
}}
}
}
inline bstr::bstr(bstr::class_type const& rhs)
: m_bstr(bstr_dup(rhs.m_bstr))
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
if( NULL == m_bstr &&
!rhs.empty())
{
STLSOFT_THROW_X(com_exception("failed to allocate string", HRESULT_FROM_WIN32(::GetLastError())));
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
inline bstr::bstr(bstr::class_type const& rhs, bstr::size_type pos, bstr::size_type len)
: m_bstr(NULL)
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
if(pos > rhs.size())
{
throw stlsoft_ns_qual_std(out_of_range)("Position out of range");
}
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
COMSTL_MESSAGE_ASSERT("Position out of range", pos <= rhs.size());
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
if(pos + len > rhs.size())
{
len = rhs.size() - pos;
}
m_bstr = bstr_create(rhs.data() + pos, len);
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
if( NULL == m_bstr &&
!rhs.empty())
{
STLSOFT_THROW_X(com_exception("failed to allocate string", HRESULT_FROM_WIN32(::GetLastError())));
}
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
inline bstr::~bstr() stlsoft_throw_0()
{
::SysFreeString(m_bstr);
}
inline bstr::class_type& bstr::operator =(bstr::class_type const& rhs)
{
class_type t(rhs);
t.swap(*this);
return *this;
}
inline bstr::class_type& bstr::assign(cs_char_a_t const* s, int len /* = -1 */)
{
class_type t(s, len);
t.swap(*this);
return *this;
}
inline bstr::class_type& bstr::assign(cs_char_w_t const* s, int len /* = -1 */)
{
class_type t(s, len);
t.swap(*this);
return *this;
}
inline bstr::class_type& bstr::assign(bstr::const_iterator from, bstr::const_iterator to)
{
return assign(from, to - from);
}
inline bstr::class_type& bstr::operator =(cs_char_a_t const* s)
{
return assign(s);
}
inline bstr::class_type& bstr::operator =(cs_char_w_t const* s)
{
return assign(s);
}
inline bstr::class_type& bstr::attach(BSTR bstr)
{
*DestructiveAddress() = bstr;
return *this;
}
inline BSTR bstr::detach()
{
BSTR str = m_bstr;
m_bstr = NULL;
return str;
}
inline void bstr::clear()
{
::SysFreeString(m_bstr);
m_bstr = NULL;
}
inline bstr::class_type& bstr::append(bstr::class_type const& s, int len /* = -1 */)
{
return append(s.data(), len);
}
inline bstr::class_type& bstr::append(cs_char_w_t const* s, int len /* = -1 */)
{
if(empty())
{
bstr rhs(s, len);
rhs.swap(*this);
}
else
{
if(len < 0)
{
len = (NULL == s) ? 0 : static_cast<int>(::wcslen(s));
}
if(0 != len)
{
size_type totalLen = size() + len;
bstr rhs(data(), static_cast<int>(totalLen));
::wcsncpy(&rhs[0] + size(), s, static_cast<cs_size_t>(len));
rhs.swap(*this);
}
}
return *this;
}
inline bstr::class_type& bstr::operator +=(bstr::class_type const& s)
{
return append(s);
}
inline bstr::class_type& bstr::operator +=(cs_char_w_t const* s)
{
return append(s);
}
// Operations
// Accessors
inline bstr::const_pointer bstr::data() const
{
return this->c_str();
}
inline bstr::const_pointer bstr::c_str() const
{
return (NULL == m_bstr) ? L"" : m_bstr;
}
inline bstr::size_type bstr::length() const
{
return static_cast<size_type>(::SysStringLen(m_bstr));
}
inline bstr::size_type bstr::size() const
{
return this->length();
}
inline bstr::bool_type bstr::empty() const
{
return 0 == this->size();
}
inline BSTR bstr::get() const
{
return m_bstr;
}
inline bstr::reference bstr::operator [](bstr::size_type index)
{
COMSTL_MESSAGE_ASSERT("invalid index", index < size());
return index[m_bstr];
}
inline bstr::const_reference bstr::operator [](bstr::size_type index) const
{
COMSTL_MESSAGE_ASSERT("invalid index", index <= size());
return index[data()];
}
inline bstr::const_pointer *bstr::NonDestructiveAddress() const
{
return const_cast<const_pointer*>(&m_bstr);
}
inline BSTR *bstr::NonDestructiveAddress()
{
return &m_bstr;
}
inline BSTR *bstr::DestructiveAddress()
{
clear();
return &m_bstr;
}
inline bstr::iterator bstr::begin()
{
return get();
}
inline bstr::iterator bstr::end()
{
return get() + size();
}
inline bstr::const_iterator bstr::begin() const
{
return get();
}
inline bstr::const_iterator bstr::end() const
{
return get() + size();
}
#if defined(STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
inline bstr::const_reverse_iterator bstr::rbegin() const
{
return const_reverse_iterator(end());
}
inline bstr::const_reverse_iterator bstr::rend() const
{
return const_reverse_iterator(begin());
}
inline bstr::reverse_iterator bstr::rbegin()
{
return reverse_iterator(end());
}
inline bstr::reverse_iterator bstr::rend()
{
return reverse_iterator(begin());
}
#endif /* STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
inline bstr::bool_type bstr::equal(bstr::class_type const& rhs) const
{
return 0 == bstr_compare(this->get(), rhs.get());
}
inline bstr::bool_type bstr::equal(BSTR const& rhs) const
{
return 0 == bstr_compare(this->get(), rhs);
}
// Operations
inline void bstr::swap(bstr::class_type& rhs) stlsoft_throw_0()
{
std_swap(m_bstr, rhs.m_bstr);
}
inline void bstr::swap(BSTR& rhs) stlsoft_throw_0()
{
std_swap(m_bstr, rhs);
}
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* ////////////////////////////////////////////////////////////////////// */
#ifndef _COMSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace comstl
# else
} // namespace stlsoft::comstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_COMSTL_NO_NAMESPACE */
/* /////////////////////////////////////////////////////////////////////////
* Namespace
*
* The string access shims exist either in the stlsoft namespace, or in the
* global namespace. This is required by the lookup rules.
*
*/
#ifndef _COMSTL_NO_NAMESPACE
# if !defined(_STLSOFT_NO_NAMESPACE) && \
!defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
namespace stlsoft
{
# else /* ? _STLSOFT_NO_NAMESPACE */
/* There is no stlsoft namespace, so must define in the global namespace */
# endif /* !_STLSOFT_NO_NAMESPACE */
using ::comstl::c_str_data;
using ::comstl::c_str_data_w;
using ::comstl::c_str_data_o;
using ::comstl::c_str_len;
using ::comstl::c_str_len_w;
using ::comstl::c_str_len_o;
using ::comstl::c_str_ptr;
using ::comstl::c_str_ptr_w;
using ::comstl::c_str_ptr_o;
using ::comstl::c_str_ptr_null;
using ::comstl::c_str_ptr_null_w;
using ::comstl::c_str_ptr_null_o;
/* /////////////////////////////////////////////////////////////////////////
* Traits
*/
STLSOFT_TEMPLATE_SPECIALISATION
struct string_traits< ::comstl::bstr>
{
typedef ::comstl::bstr value_type;
typedef ::comstl::bstr::value_type char_type; // NOTE: Can't use value_type::value_type here, because of BC++ 5.5.1
typedef value_type::size_type size_type;
typedef char_type const const_char_type;
typedef value_type string_type;
typedef string_type::pointer pointer;
typedef string_type::const_pointer const_pointer;
typedef string_type::iterator iterator;
typedef string_type::const_iterator const_iterator;
#if defined(STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
typedef string_type::reverse_iterator reverse_iterator;
typedef string_type::const_reverse_iterator const_reverse_iterator;
#endif /* STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
enum
{
is_pointer = false
, is_pointer_to_const = false
, char_type_size = sizeof(char_type)
};
static string_type empty_string()
{
return string_type();
}
static string_type construct(string_type const& src, size_type pos, size_type len)
{
return string_type(src, pos, len);
}
# ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
template <ss_typename_param_k I>
static string_type &assign_inplace(string_type &str, I first, I last)
# else /* ? STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
static string_type &assign_inplace(string_type &str, const_iterator first, const_iterator last)
# endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
{
// comstl::bstr cannot assign in-place
return (str = string_type(first, last - first), str);
}
};
# if !defined(_STLSOFT_NO_NAMESPACE) && \
!defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace stlsoft
# else /* ? _STLSOFT_NO_NAMESPACE */
/* There is no stlsoft namespace, so must define in the global namespace */
# endif /* !_STLSOFT_NO_NAMESPACE */
#endif /* !_COMSTL_NO_NAMESPACE */
/* ////////////////////////////////////////////////////////////////////// */
#endif /* !COMSTL_INCL_COMSTL_STRING_HPP_BSTR */
/* ////////////////////////////////////////////////////////////////////// */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -