From 23dc657f0af27bdac887f8d18208d544cc9f010e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Tue, 2 Aug 2022 23:50:58 +0200 Subject: Improve wstring_owner, rename to wchar_ptr. The user-defined conversion function makes the interface a lot simpler AND safer. --- c/common.cpp | 42 +++++++++++++++++++++--------------------- c/common.h | 27 ++++++++++++++------------- c/datalistview.cpp | 8 ++++---- c/episodelistview.cpp | 12 ++++++------ c/main.cpp | 14 +++++++------- c/pl.cpp | 4 ++-- c/pl.h | 8 ++++---- 7 files changed, 58 insertions(+), 57 deletions(-) diff --git a/c/common.cpp b/c/common.cpp index 5d786da..59f0fdc 100644 --- a/c/common.cpp +++ b/c/common.cpp @@ -3,48 +3,48 @@ #include "common.h" -/* wstring_owner: Simple wrapper for wide C strings. */ +/* wchar_ptr: Simple wrapper for wide C strings. */ -wstring_owner::wstring_owner() {} +wchar_ptr::wchar_ptr() {} -wstring_owner::wstring_owner(wchar_t* const s) : p(s) {} +wchar_ptr::wchar_ptr(wchar_t* const s) : m_p(s) {} -wstring_owner& wstring_owner::operator=(wchar_t* const s) +wchar_ptr& wchar_ptr::operator=(wchar_t* const s) { - if (p != s) { - delete p; - p = s; + if (m_p != s) { + delete m_p; + m_p = s; } return *this; } -wstring_owner::wstring_owner(wstring_owner&& other) noexcept : p(std::exchange(other.p, nullptr)) {} +wchar_ptr::wchar_ptr(wchar_ptr&& other) noexcept : m_p(std::exchange(other.m_p, nullptr)) {} -wstring_owner& wstring_owner::operator=(wstring_owner&& other) noexcept +wchar_ptr& wchar_ptr::operator=(wchar_ptr&& other) noexcept { - std::swap(p, other.p); + std::swap(m_p, other.m_p); return *this; } -/* Return pointer, releasing ownership. */ -wchar_t* wstring_owner::release() +wchar_ptr::operator wchar_t*() noexcept { - wchar_t* p2 = p; - p = nullptr; - return p2; + return m_p; } -wstring_owner::operator bool() const +/* Return pointer, releasing ownership. */ +wchar_t* wchar_ptr::release() { - return p; + wchar_t* p2 = m_p; + m_p = nullptr; + return p2; } -wstring_owner::~wstring_owner() +wchar_ptr::~wchar_ptr() { - delete p; + delete m_p; } -wstring_owner wstring_owner::from_narrow(const char* const src, const int cp) +wchar_ptr wchar_ptr::from_narrow(const char* const src, const int cp) { int cbMultiByte = strlen(src)+1; int cchWideChar = MultiByteToWideChar(cp, 0, src, cbMultiByte, NULL, 0); @@ -56,7 +56,7 @@ wstring_owner wstring_owner::from_narrow(const char* const src, const int cp) return dst; } -wstring_owner wstring_owner::copy(const wchar_t* const src) +wchar_ptr wchar_ptr::copy(const wchar_t* const src) { const int cb = wcslen(src)+1; wchar_t* dst = new wchar_t[cb]; diff --git a/c/common.h b/c/common.h index 0851bb6..f011565 100644 --- a/c/common.h +++ b/c/common.h @@ -8,21 +8,22 @@ int EBMessageBox(const wchar_t* wszText, const wchar_t* wszCaption, unsigned uType); int GetRelativeCursorPos(HWND hWnd, POINT* pt); -struct wstring_owner +struct wchar_ptr { - static wstring_owner from_narrow(const char* buf, int cp = CP_UTF8); - static wstring_owner copy(const wchar_t* s); - wstring_owner(); - wstring_owner(wchar_t* s); - wstring_owner& operator=(wchar_t* s); - wstring_owner(wstring_owner& other) = delete; - wstring_owner& operator=(wstring_owner& other) = delete; - wstring_owner(wstring_owner&& other) noexcept; - wstring_owner& operator=(wstring_owner&& other) noexcept; + static wchar_ptr from_narrow(const char* buf, int cp = CP_UTF8); + static wchar_ptr copy(const wchar_t* s); + wchar_ptr(); + wchar_ptr(wchar_t* s); + wchar_ptr& operator=(wchar_t* s); + wchar_ptr(wchar_ptr& other) = delete; + wchar_ptr& operator=(wchar_ptr& other) = delete; + wchar_ptr(wchar_ptr&& other) noexcept; + wchar_ptr& operator=(wchar_ptr&& other) noexcept; + operator wchar_t*() noexcept; wchar_t *release(); - operator bool() const; - ~wstring_owner(); - wchar_t* p = nullptr; + ~wchar_ptr(); +private: + wchar_t* m_p = nullptr; }; struct Win32Error : public std::exception diff --git a/c/datalistview.cpp b/c/datalistview.cpp index ecaa76f..cdc6dfb 100644 --- a/c/datalistview.cpp +++ b/c/datalistview.cpp @@ -64,20 +64,20 @@ void DataListView::ShowEpisode(const int iEpisode) LVITEM lviValue = {LVIF_TEXT}; for (int i = 0; q.NextSolution(std::nothrow); i++) { - wstring_owner key; - wstring_owner value; + wchar_ptr key; + wchar_ptr value; if (!(PlGet(t+1, &key) && PlGet(t+2, &value))) continue; lviKey.iItem = i; lviKey.iSubItem = 0; - lviKey.pszText = key.p; + lviKey.pszText = key; ListView_InsertItem(hWnd, &lviKey); lviValue.iItem = i; lviValue.iSubItem = 1; - lviValue.pszText = value.p; + lviValue.pszText = value; ListView_SetItem(hWnd, &lviValue); } diff --git a/c/episodelistview.cpp b/c/episodelistview.cpp index 1c5c9ae..313f82f 100644 --- a/c/episodelistview.cpp +++ b/c/episodelistview.cpp @@ -264,16 +264,16 @@ int CALLBACK EpisodeListView::SortProc(const LPARAM iItem1, const LPARAM iItem2, case ELVSITITLE: { Mark m; - wstring_owner s1, s2; + wchar_ptr s1, s2; int cch, cch1, cch2; if (!Pl("episode_data","episode_title",lvi1.lParam,&s1)) return 0; if (!Pl("episode_data","episode_title",lvi2.lParam,&s2)) return 0; - cch1 = wcslen(s1.p); - cch2 = wcslen(s2.p); + cch1 = wcslen(s1); + cch2 = wcslen(s2); cch = cch1 > cch2? cch2: cch1; - return order*_wcsnicmp(s1.p, s2.p, cch); + return order*_wcsnicmp(s1, s2, cch); } default: return 0; @@ -404,12 +404,12 @@ void EpisodeListView::Update() /* Update episode name and rating. */ void EpisodeListView::UpdateItem(const int iItem, const LPARAM lParam) { - wstring_owner name; + wchar_ptr name; if (!Pl("episode_data","episode_title",lParam,&name)) { if (!Pl("episode_data","update_episode_data")) goto r; if (!Pl("episode_data","episode_title",lParam,&name)) goto r; } - ListView_SetItemText(hWnd, iItem, ELVSITITLE, name.p); + ListView_SetItemText(hWnd, iItem, ELVSITITLE, name); r: int rating; if (!Pl("episode_data","episode_rating",lParam,&rating)) { diff --git a/c/main.cpp b/c/main.cpp index 32187c8..3ec6fee 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -56,7 +56,7 @@ static void UpdateTheme(); void OnTerminate() noexcept { const wchar_t* what = L"an exception"; - wstring_owner why; + wchar_ptr why; try { std::rethrow_exception(std::current_exception()); @@ -65,14 +65,14 @@ void OnTerminate() noexcept try { why = PlString(t); } catch (...) {} } catch (const Win32Error& e) { what = L"a Windows error"; - try { why = wstring_owner::copy(e.WhatW()); } catch (...) {} + try { why = wchar_ptr::copy(e.WhatW()); } catch (...) {} } catch (const std::exception& e) { - try { why = wstring_owner::from_narrow(e.what()); } catch (...) {} + try { why = wchar_ptr::from_narrow(e.what()); } catch (...) {} } catch (...) {} wchar_t msg[256] = {0}; if (why) - wszf(msg, L"Episode Browser was terminated due to %s: %s", what, why.p); + wszf(msg, L"Episode Browser was terminated due to %s: %s", what, static_cast(why)); else wszf(msg, L"Episode Browser was terminated due to %s.", what); @@ -493,13 +493,13 @@ void WaitFor(const char* mod, const char* pred) static atom_t aThread; static int bActive; static int iTimer; - static wstring_owner activePred; + static wchar_ptr activePred; if (bActive) { wchar_t msg[256] = {0}; wszf(msg, L"Another task (%s) is active. " L"Do you want to cancel the existing task and start a new one?", - activePred.p); + static_cast(activePred)); if (EBMessageBox(msg, L"Error", MB_YESNO|MB_ICONWARNING) != IDYES) return; KillTimer(NULL, iTimer); @@ -529,7 +529,7 @@ void WaitFor(const char* mod, const char* pred) Plx(mod,"thread_create",pred,&aThread); SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)L"."); if (prefer(iTimer = SetTimer(NULL, -1, 500, proc))) { - activePred = wstring_owner::from_narrow(pred); + activePred = wchar_ptr::from_narrow(pred); bActive = 1; } } diff --git a/c/pl.cpp b/c/pl.cpp index 1dc22fb..8b3fcbe 100644 --- a/c/pl.cpp +++ b/c/pl.cpp @@ -90,11 +90,11 @@ int Query::NextSolution() } /* Convert Prolog term to wide characters. */ -wstring_owner PlString(const term_t t, const int flags) +wchar_ptr PlString(const term_t t, const int flags) { char* s; if (PL_get_chars(t, &s, flags)) - return {wstring_owner::from_narrow(s)}; + return {wchar_ptr::from_narrow(s)}; else return {}; } diff --git a/c/pl.h b/c/pl.h index 1c526a0..28e13b0 100644 --- a/c/pl.h +++ b/c/pl.h @@ -7,7 +7,7 @@ #include "common.h" -wstring_owner PlString(const term_t t, const int flags = CVT_WRITE); +wchar_ptr PlString(const term_t t, const int flags = CVT_WRITE); struct Frame { @@ -54,7 +54,7 @@ inline int PlPut(term_t, long*) { return -1; } inline int PlPut(term_t, long long*) { return -1; } inline int PlPut(term_t, atom_t*) { return -1; } inline int PlPut(term_t, char**) { return -1; } -inline int PlPut(term_t, wstring_owner*) { return -1; } +inline int PlPut(term_t, wchar_ptr*) { return -1; } inline int PlGet(term_t, int) { return -1; } inline int PlGet(term_t, long) { return -1; } @@ -67,11 +67,11 @@ inline int PlGet(term_t t, long* x) { return PL_get_long(t, x); } inline int PlGet(term_t t, long long* x) { return PL_get_int64(t, x); } inline int PlGet(term_t t, atom_t* x) { return PL_get_atom(t, x); } inline int PlGet(term_t t, char** x) { return PL_get_atom_chars(t, x); } -inline int PlGet(term_t t, wstring_owner* x) { +inline int PlGet(term_t t, wchar_ptr* x) { Mark m; char* s; if (!PlGet(t, &s)) return 0; - *x = wstring_owner::from_narrow(s); + *x = wchar_ptr::from_narrow(s); return 1; /* or catch potential exception from BstrFromSz? */ } -- cgit v1.2.3