From b9d7ec228b03e2978b0e1d9f21dadd56b2f405e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Mon, 29 Aug 2022 23:33:48 +0200 Subject: Small improvments. --- c/CMakeLists.txt | 3 ++- c/data.cpp | 16 +++++++-------- c/data.h | 8 ++++---- c/ext.cpp | 2 +- c/util.h | 60 +++++++++++++++++++++++++++++++++----------------------- 5 files changed, 50 insertions(+), 39 deletions(-) diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt index b3a1671..da411b2 100644 --- a/c/CMakeLists.txt +++ b/c/CMakeLists.txt @@ -35,7 +35,8 @@ target_sources(EpisodeBrowser PRIVATE test.h util.h win.cpp - win.h) + win.h +) if (CMAKE_GENERATOR MATCHES "Visual Studio") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") diff --git a/c/data.cpp b/c/data.cpp index 4db294c..8c26138 100644 --- a/c/data.cpp +++ b/c/data.cpp @@ -24,15 +24,15 @@ struct ParsedDoc ParsedDoc(const wchar_t* wszUrl, const char* szUrl) { - if (!s_hi.Not(0)) + if (!s_hi.Bad(0)) throw Win32Error(); hiUrl = InternetOpenUrlW(s_hi.v, wszUrl, nullptr, 0, INTERNET_FLAG_NO_UI, 0); - if (!hiUrl.Not(0)) + if (!hiUrl.Bad(0)) throw InternetError(); ctxt = htmlCreatePushParserCtxt(nullptr, nullptr, bufX, sizeof(bufX), szUrl, XML_CHAR_ENCODING_UTF8); - if (!ctxt.Not(0)) + if (!ctxt.Bad(0)) throw XmlError(); htmlCtxtUseOptions(ctxt.v, HTML_PARSE_RECOVER|HTML_PARSE_NOERROR|HTML_PARSE_NOWARNING); @@ -57,7 +57,7 @@ template bool WcharsFromXmlchars(wchar_t (&dst)[N], xmlChar* utf8_) { Unique utf8 = utf8_; - if (!utf8.Not(0)) + if (!utf8.Bad(0)) throw XmlError(); /* Truncate if source is larger than destination. */ @@ -171,13 +171,13 @@ void FetchData(unsigned char* sig) "https://www.detectiveconanworld.com/wiki/Anime"); Unique xpathCtx = xmlXPathNewContext(doc); - if (!xpathCtx.Not(0)) + if (!xpathCtx.Bad(0)) throw XmlError(); Unique xpathObj = xmlXPathEvalExpression( reinterpret_cast("//tr[./td[1] != '' and ./td[3][@style='background:#f2fde9;']]"), xpathCtx.v); - if (!xpathObj.Not(0)) + if (!xpathObj.Bad(0)) throw XmlError(); xmlNodeSetPtr nodes = xpathObj.v->nodesetval; @@ -271,14 +271,14 @@ void FetchScreenwriters(unsigned char* sig) /* Retrieve screenwriter from HTML. */ ParsedDoc doc(url, nullptr); Unique xpathCtx = xmlXPathNewContext(doc); - if (!xpathCtx.Not(0)) + if (!xpathCtx.Bad(0)) throw XmlError(); Unique xpathObj = xmlXPathEvalExpression(reinterpret_cast( "//th[contains(text(), 'Screenplay:')]/following-sibling::td"), xpathCtx.v); - if (!xpathObj.Not(0)) + if (!xpathObj.Bad(0)) throw XmlError(); xmlNodeSetPtr nodes = xpathObj.v->nodesetval; diff --git a/c/data.h b/c/data.h index 478182d..171edaa 100644 --- a/c/data.h +++ b/c/data.h @@ -120,11 +120,11 @@ struct FileView { hf = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); - if (!hf.Not(INVALID_HANDLE_VALUE)) { + if (!hf.Bad(INVALID_HANDLE_VALUE)) { if (GetLastError() == ERROR_FILE_NOT_FOUND) { hf = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); - if (!hf.Not(INVALID_HANDLE_VALUE)) + if (!hf.Bad(INVALID_HANDLE_VALUE)) throw Win32Error(); } else throw Win32Error(); @@ -134,11 +134,11 @@ struct FileView cbMap.QuadPart = c*sizeof(T); hm = CreateFileMapping(hf.v, nullptr, PAGE_READWRITE, cbMap.HighPart, cbMap.LowPart, nullptr); - if (!hm.Not(0)) + if (!hm.Bad(0)) throw Win32Error(); view = reinterpret_cast(MapViewOfFile(hm.v, FILE_MAP_ALL_ACCESS, 0, 0, 0)); - if (!view.Not(0)) + if (!view.Bad(0)) throw Win32Error(); } diff --git a/c/ext.cpp b/c/ext.cpp index 398804e..8e58ade 100644 --- a/c/ext.cpp +++ b/c/ext.cpp @@ -87,7 +87,7 @@ static bool FindMatchingFile(wchar_t (&file)[MAX_PATH], const wchar_t* const roo WIN32_FIND_DATA fdata; Unique h = FindFirstFileW(pat, &fdata); - if (!h.Not(INVALID_HANDLE_VALUE)) + if (!h.Bad(INVALID_HANDLE_VALUE)) throw Win32Error(); do diff --git a/c/util.h b/c/util.h index ffc6b57..f9e3057 100644 --- a/c/util.h +++ b/c/util.h @@ -19,42 +19,49 @@ _Exit(1); \ }) +/* Scope guard. */ template struct Finally { F f; - inline Finally(F f) : f(f) {} + inline Finally(F f) noexcept : f(f) {} inline ~Finally() { f(); } }; #define FINALLY Finally _ = [=]() template -inline void Delete(T v) +inline void Delete(T v) noexcept { delete v; } +/* Unique is similar to unique_ptr, but it is designed for pointers + * and handles of type T, where T is not an RAII class. Further, the + * managed object is assumed to be in an invalid state until checked + * with Good or Bad. Upon destruction, the object, if valid, is passed + * to a given destructor function F. */ template > struct Unique { - T v; - bool ok = true; - Unique() : ok(false) {} - Unique(T v) : v(v) {} - Unique& operator =(T v_) + union { T v; }; + bool ok = false; + Unique() noexcept {} + Unique(T v) noexcept : v(v) {} + Unique& operator =(T v_) noexcept { - if (ok) + if (ok) { F(v); + v.~T(); + } v = v_; - ok = true; + ok = false; return *this; } - Unique(Unique&& other) + Unique(Unique&& other) noexcept : v(std::move(other.v)), ok(other.ok) { - v = std::move(other.v); other.ok = false; } - Unique& operator =(Unique&& other) + Unique& operator =(Unique&& other) noexcept { if (ok) F(v); @@ -63,17 +70,20 @@ struct Unique other.ok = false; return *this; } - bool Not(T u) + bool Good(T u) noexcept { - if (v == u) - return ok = false; - else - return true; + return ok = v == u; + } + bool Bad(T u) noexcept + { + return ok = v != u; } ~Unique() { - if (ok) + if (ok) { F(v); + v.~T(); + } } }; @@ -83,13 +93,13 @@ struct Buf { T* data; size_t c; - Buf(T* data, size_t c) : data(data), c(c) {} - Buf(std::basic_string& s) : data(s.data()), c(s.capacity()) {} - template Buf(T (&data)[N]) : data(data), c(N) {} - operator T*() { return data; } - T& operator *() { return *data; } - T& operator [](size_t i) { return data[i]; } - Buf operator +(size_t i) { return {data+i, c-i}; } + Buf(T* data, size_t c) noexcept : data(data), c(c) {} + Buf(std::basic_string& s) noexcept : data(s.data()), c(s.capacity()) {} + template Buf(T (&data)[N]) noexcept : data(data), c(N) {} + operator T*() noexcept { return data; } + T& operator *() noexcept { return *data; } + T& operator [](size_t i) noexcept { return data[i]; } + Buf operator +(size_t i) noexcept { return {data+i, c-i}; } //T operator -(size_t i) { return {data-i, c+i}; } }; -- cgit v1.2.3