diff options
author | John Ankarström <john@ankarstrom.se> | 2022-07-30 03:14:13 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2022-07-30 03:14:13 +0200 |
commit | ebabd34385feb629b759216c1f7d85edc20bf2fd (patch) | |
tree | 432e68a6a58bcaf4bc1dd3c5ae438157f09f4d4a /c/common.cpp | |
parent | d485eb2bf7e0a82702afec9387f21bf0f89c985f (diff) | |
download | EpisodeBrowser-ebabd34385feb629b759216c1f7d85edc20bf2fd.tar.gz |
Add wstring_owner, replacing std::wstring.
std::basic_string is nice, but it is not very ergonomic if everything
you really need is to automatically free C strings at end of scope.
I suppose I could have used std::unique_ptr for this, but I suspect
the ergonomics would be worse.
Diffstat (limited to 'c/common.cpp')
-rw-r--r-- | c/common.cpp | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/c/common.cpp b/c/common.cpp index bc2d4af..614bfeb 100644 --- a/c/common.cpp +++ b/c/common.cpp @@ -2,6 +2,59 @@ #include "common.h" +/* wstring_owner: Simple wrapper for wide C strings. */ + +wstring_owner::wstring_owner() {} + +wstring_owner::wstring_owner(wchar_t* const wsz) : p(wsz) {} + +wstring_owner& wstring_owner::operator=(wchar_t* const wsz) +{ + if (p != wsz) { + delete p; + p = wsz; + } + return *this; +} + +wstring_owner::wstring_owner(wstring_owner&& wso) noexcept : p(std::exchange(wso.p, nullptr)) {} + +wstring_owner& wstring_owner::operator=(wstring_owner&& wso) noexcept +{ + std::swap(p, wso.p); + return *this; +} + +/* Return pointer, releasing ownership. */ +wchar_t* wstring_owner::release() +{ + wchar_t* p2 = p; + p = nullptr; + return p2; +} + +wstring_owner::operator bool() const +{ + return p; +} + +wstring_owner::~wstring_owner() +{ + delete p; +} + +wstring_owner WsoFromSz(const char* const sz, const int iCp) +{ + int cbMultiByte = strlen(sz)+1; + int cchWideChar = MultiByteToWideChar(iCp, 0, sz, cbMultiByte, NULL, 0); + wchar_t* wsz = new wchar_t[cchWideChar]; + if (!MultiByteToWideChar(iCp, 0, sz, cbMultiByte, wsz, cchWideChar)) { + delete wsz; + throw Win32Error(GetLastError()); + } + return wsz; +} + /* Win32Error: Exception for Windows API errors. */ Win32Error::Win32Error() : dwErr(GetLastError()) {} @@ -55,17 +108,6 @@ Library::~Library() FreeLibrary(m_hModule); } -/* Convert narrow unmanaged string to wide managed string. */ -std::wstring WsFromSz(const char* sz, int iCp) -{ - int cbMultiByte = strlen(sz)+1; - int cchWideChar = MultiByteToWideChar(iCp, 0, sz, cbMultiByte, NULL, 0); - std::wstring ws(cchWideChar, 0); - if (!MultiByteToWideChar(iCp, 0, sz, cbMultiByte, ws.data(), cchWideChar)) - throw Win32Error(GetLastError()); - return ws; -} - /* Move message box to center of main window. */ static LRESULT CALLBACK CBTProc(const int nCode, const WPARAM wParam, const LPARAM lParam) noexcept { |