| /** | |
| * 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 <type_traits> | |
| #include <windows.h> | |
| #include <intsafe.h> | |
| #include <winstring.h> | |
| #include <roapi.h> | |
| /* #include <wrl/def.h> */ | |
| #include <wrl/internal.h> | |
| 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 <size_t s> | |
| HRESULT Set(const wchar_t (&str)[s]) throw() { | |
| static_assert(static_cast<size_t>(static_cast<UINT32>(s - 1)) == s - 1, "mismatch string length"); | |
| return Set(str, s - 1); | |
| } | |
| template <size_t s> | |
| HRESULT Set(wchar_t (&strRef)[s]) throw() { | |
| const wchar_t *str = static_cast<const wchar_t *>(strRef); | |
| unsigned int l; | |
| HRESULT hr = SizeTToUInt32(::wcslen(str), &l); | |
| if (SUCCEEDED(hr)) | |
| hr = Set(str, l); | |
| return hr; | |
| } | |
| template <typename T> | |
| HRESULT Set(const T& s, typename ::std::enable_if<::std::is_convertible<const T&, const wchar_t *>::value, ::Microsoft::WRL::Details::Dummy>::type = ::Microsoft::WRL::Details::Dummy()) throw() { | |
| HRESULT hr = S_OK; | |
| const wchar_t *str = static_cast<PCWSTR>(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<unsigned int s> | |
| static HStringReference MakeReference(wchar_t const (&str)[s]) throw(); | |
| template<unsigned int s> | |
| 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<unsigned int sizeDest> | |
| explicit HStringReference(wchar_t const (&str)[sizeDest]) throw() : hstr_(nullptr) { | |
| Init(str, sizeDest - 1); | |
| } | |
| template <size_t sizeDest> | |
| explicit HStringReference(wchar_t (&strRef)[sizeDest]) throw() { | |
| const wchar_t *str = static_cast<const wchar_t*>(strRef); | |
| Init(str, ::wcslen(str)); | |
| } | |
| template<typename T> | |
| explicit HStringReference(const T &strRef) throw() : hstr_(nullptr) { | |
| const wchar_t* str = static_cast<const wchar_t*>(strRef); | |
| size_t len = ::wcslen(str); | |
| if(static_cast<size_t>(static_cast<unsigned int>(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 |