diff options
Diffstat (limited to 'c/data.h')
-rw-r--r-- | c/data.h | 89 |
1 files changed, 37 insertions, 52 deletions
@@ -3,10 +3,24 @@ #include <stdexcept> #include <windows.h> +#include <libxml/xmlerror.h> #include "util.h" #include "win.h" +struct XmlError : public std::exception +{ + const char* msg; + inline XmlError() + { + msg = xmlGetLastError()->message; + } + inline virtual const char* what() const noexcept + { + return msg; + } +}; + /* Fetch data from the web. */ void FetchData(unsigned char* sig); void FetchScreenwriters(unsigned char* sig); @@ -71,15 +85,21 @@ constexpr inline bool HasVersion = false; template <typename T> constexpr inline bool HasVersion<T, decltype((void) T::version, 0)> = true; +inline void FreeView(void* view) +{ + FlushViewOfFile(view, 0); + UnmapViewOfFile(view); +} + /* FileView objects manage a memory-mapped file. The view buffer may * be treated as an array of a given type T. Note that reading and * writing a view can throw structured exceptions. We ignore these. */ template <typename T> struct FileView { - HANDLE hf; - HANDLE hm; - T* view; + Unique<HANDLE, CloseHandle> hf; + Unique<HANDLE, CloseHandle> hm; + Unique<T*, FreeView> view; size_t c; static FileView Initialized(const wchar_t* filename, size_t c, size_t cInit = 0) @@ -91,41 +111,20 @@ struct FileView cInit = cInit? cInit: c; for (size_t i = 0; i < cInit; i++) memcpy(fv+i, &t, sizeof(T)); - } - - return {filename, c}; - } - - FileView(FileView<T>&) = delete; - FileView<T>& operator =(const FileView<unsigned char>&) = delete; - - FileView(FileView<T>&& other) - { - hf = other.hf; - hm = other.hf; - view = other.view; - c = other.c; - other.view = nullptr; - } - FileView<T>& operator =(FileView<unsigned char>&& other) - { - hf = other.hf; - hm = other.hf; - view = other.view; - c = other.c; - other.view = nullptr; - return *this; + return fv; + } else + return {filename, c}; } FileView(const wchar_t* filename, size_t c) : c(c) { hf = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); - if (hf == INVALID_HANDLE_VALUE) { + if (!hf.Not(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 == INVALID_HANDLE_VALUE) + if (!hf.Not(INVALID_HANDLE_VALUE)) throw Win32Error(); } else throw Win32Error(); @@ -133,28 +132,14 @@ struct FileView LARGE_INTEGER cbMap; cbMap.QuadPart = c*sizeof(T); - hm = CreateFileMapping(hf, nullptr, PAGE_READWRITE, + hm = CreateFileMapping(hf.v, nullptr, PAGE_READWRITE, cbMap.HighPart, cbMap.LowPart, nullptr); - if (!hm) { - CloseHandle(hf); + if (!hm.Not(0)) throw Win32Error(); - } - view = reinterpret_cast<T*>(MapViewOfFile(hm, FILE_MAP_ALL_ACCESS, 0, 0, 0)); - if (!view) { - CloseHandle(hm); + view = reinterpret_cast<T*>(MapViewOfFile(hm.v, FILE_MAP_ALL_ACCESS, 0, 0, 0)); + if (!view.Not(0)) throw Win32Error(); - } - } - - ~FileView() - { - if (view) { - FlushViewOfFile(view, 0); - UnmapViewOfFile(view); - CloseHandle(hm); - CloseHandle(hf); - } } /* Access element by index, performing bounds check and, if @@ -165,7 +150,7 @@ struct FileView if (i >= c) throw std::out_of_range("index larger than buffer"); - T& t = view[i]; + T& t = view.v[i]; if constexpr (HasVersion<T>) { if (t.version == 0) { @@ -181,17 +166,17 @@ struct FileView return t; } - T* begin() { return *view; } - T* end() { return view[c-1]; } + T* begin() noexcept { return *view; } + T* end() noexcept { return view[c-1]; } inline operator T*() noexcept { - return view; + return view.v; } inline T* operator ->() noexcept { - return view; + return view.v; } }; |