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 + -
显示快捷键?