/** * This file has no copyright assigned and is placed in the Public Domain. * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #ifndef _WRL_COREWRAPPERS_H_ #define _WRL_COREWRAPPERS_H_ #include #include #include #include #include /* #include */ #include namespace Microsoft { namespace WRL { namespace Details { struct Dummy {}; } namespace Wrappers { class HStringReference; class HString { public: HString() throw() : hstr_(nullptr) {} HString(HString&& o) throw() : hstr_(o.hstr_) { o.hstr_ = nullptr; } HString(const HString&) = delete; HString& operator=(const HString&) = delete; operator HSTRING() const throw() { return hstr_; } ~HString() throw() { Release(); } HString& operator=(HString&& o) throw() { Release(); hstr_ = o.hstr_; o.hstr_ = nullptr; return *this; } HRESULT Set(const wchar_t *s, unsigned int l) throw() { Release(); return ::WindowsCreateString(s, l, &hstr_); } template HRESULT Set(const wchar_t (&str)[s]) throw() { static_assert(static_cast(static_cast(s - 1)) == s - 1, "mismatch string length"); return Set(str, s - 1); } template HRESULT Set(wchar_t (&strRef)[s]) throw() { const wchar_t *str = static_cast(strRef); unsigned int l; HRESULT hr = SizeTToUInt32(::wcslen(str), &l); if (SUCCEEDED(hr)) hr = Set(str, l); return hr; } template HRESULT Set(const T& s, typename ::std::enable_if<::std::is_convertible::value, ::Microsoft::WRL::Details::Dummy>::type = ::Microsoft::WRL::Details::Dummy()) throw() { HRESULT hr = S_OK; const wchar_t *str = static_cast(s); if (str != nullptr) { unsigned int l; hr = SizeTToUInt32(::wcslen(str), &l); if (SUCCEEDED(hr)) hr = Set(str, l); } else hr = Set(L"", 0); return hr; } HRESULT Set(const HSTRING& s) throw() { HRESULT hr = S_OK; if (s == nullptr || s != hstr_) { Release(); hr = ::WindowsDuplicateString(s, &hstr_); } return hr; } void Attach(HSTRING h) throw() { ::WindowsDeleteString(hstr_); hstr_ = h; } HSTRING Detach() throw() { HSTRING t = hstr_; hstr_ = nullptr; return t; } HSTRING* GetAddressOf() throw() { Release(); return &hstr_; } HSTRING* ReleaseAndGetAddressOf() throw() { Release(); return &hstr_; } HSTRING Get() const throw() { return hstr_; } void Release() throw() { ::WindowsDeleteString(hstr_); hstr_ = nullptr; } bool IsValid() const throw() { return hstr_ != nullptr; } UINT32 Length() const throw() { return ::WindowsGetStringLen(hstr_); } const wchar_t* GetRawBuffer(unsigned int *l) const { return ::WindowsGetStringRawBuffer(hstr_, l); } HRESULT CopyTo(HSTRING *s) const throw() { return ::WindowsDuplicateString(hstr_, s); } HRESULT Duplicate(const HString& o) throw() { HSTRING l; HRESULT hr = ::WindowsDuplicateString(o, &l); return ReleaseAndAssignOnSuccess(hr, l, *this); } bool IsEmpty() const throw() { return hstr_ == nullptr; } HRESULT Concat(const HString& s, HString& n) const throw() { HSTRING l; HRESULT hr = ::WindowsConcatString(hstr_, s, &l); return ReleaseAndAssignOnSuccess(hr, l, n); } HRESULT TrimStart(const HString& t, HString& n) const throw() { HSTRING l; HRESULT hr = ::WindowsTrimStringStart(hstr_, t, &l); return ReleaseAndAssignOnSuccess(hr, l, n); } HRESULT TrimEnd(const HString& t, HString& n) const throw() { HSTRING l; HRESULT hr = ::WindowsTrimStringEnd(hstr_, t, &l); return ReleaseAndAssignOnSuccess(hr, l, n); } HRESULT Substring(UINT32 s, HString& n) const throw() { HSTRING l; HRESULT hr = ::WindowsSubstring(hstr_, s, &l); return ReleaseAndAssignOnSuccess(hr, l, n); } HRESULT Substring(UINT32 s, UINT32 len, HString& n) const throw() { HSTRING l; HRESULT hr = ::WindowsSubstringWithSpecifiedLength(hstr_, s, len, &l); return ReleaseAndAssignOnSuccess(hr, l, n); } HRESULT Replace(const HString& s1, const HString& s2, HString& n) const throw() { HSTRING l; HRESULT hr = ::WindowsReplaceString(hstr_, s1, s2, &l); return ReleaseAndAssignOnSuccess(hr, l, n); } template static HStringReference MakeReference(wchar_t const (&str)[s]) throw(); template static HStringReference MakeReference(wchar_t const (&str)[s], unsigned int l) throw(); private: static HRESULT ReleaseAndAssignOnSuccess(HRESULT hr, HSTRING n, HString& t) { if (SUCCEEDED(hr)) { *t.ReleaseAndGetAddressOf() = n; } return hr; } protected: HSTRING hstr_; }; class HStringReference { private: void Init(const wchar_t* str, unsigned int len) { HRESULT hres = ::WindowsCreateStringReference(str, len, &header_, &hstr_); if (FAILED(hres)) ::Microsoft::WRL::Details::RaiseException(hres); } HStringReference() : hstr_(nullptr) {} public: HStringReference(const wchar_t* str, unsigned int len) throw() : hstr_(nullptr) { Init(str, len); } template explicit HStringReference(wchar_t const (&str)[sizeDest]) throw() : hstr_(nullptr) { Init(str, sizeDest - 1); } template explicit HStringReference(wchar_t (&strRef)[sizeDest]) throw() { const wchar_t *str = static_cast(strRef); Init(str, ::wcslen(str)); } template explicit HStringReference(const T &strRef) throw() : hstr_(nullptr) { const wchar_t* str = static_cast(strRef); size_t len = ::wcslen(str); if(static_cast(static_cast(len)) != len) ::Microsoft::WRL::Details::RaiseException(INTSAFE_E_ARITHMETIC_OVERFLOW); Init(str, len); } HStringReference(const HStringReference &other) throw() : hstr_(nullptr) { unsigned int len = 0; const wchar_t* value = other.GetRawBuffer(&len); Init(value, len); } ~HStringReference() throw() { hstr_ = nullptr; } HStringReference& operator=(const HStringReference &other) throw() { unsigned int len = 0; const wchar_t* value = other.GetRawBuffer(&len); Init(value, len); return *this; } HSTRING Get() const throw() { return hstr_; } const wchar_t *GetRawBuffer(unsigned int *len) const { return ::WindowsGetStringRawBuffer(hstr_, len); } HRESULT CopyTo(HSTRING *str) const throw() { return ::WindowsDuplicateString(hstr_, str); } friend class HString; protected: HSTRING_HEADER header_; HSTRING hstr_; }; class RoInitializeWrapper { public: RoInitializeWrapper(RO_INIT_TYPE flags) { hres = ::Windows::Foundation::Initialize(flags); } ~RoInitializeWrapper() { if(SUCCEEDED(hres)) ::Windows::Foundation::Uninitialize(); } operator HRESULT() { return hres; } private: HRESULT hres; }; } } } #endif