diff options
author | Dave Houlton <euclid@lindenlab.com> | 2020-07-23 19:21:30 +0000 |
---|---|---|
committer | Dave Houlton <euclid@lindenlab.com> | 2020-07-23 19:21:30 +0000 |
commit | 6fbf39f9b319106e39f80b8641acaba122d02e0a (patch) | |
tree | e47af1ff1bd1db52fd93c11d857b11387bacf01a /indra/llcommon/llfile.h | |
parent | 05200cf827d9a6263adc4905bf41a4905bce2659 (diff) | |
parent | 64a9ad0f5f52dac633a76e39335a7def2573b82e (diff) |
Merged in lmr4-merge-6.4.6 (pull request #213)
Merge master v6.4.6 into DRTVWR-497 (VS2017)
Diffstat (limited to 'indra/llcommon/llfile.h')
-rw-r--r-- | indra/llcommon/llfile.h | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 398938b729..9de095b45d 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -86,6 +86,69 @@ public: static const char * tmpdir(); }; +/// RAII class +class LLUniqueFile +{ +public: + // empty + LLUniqueFile(): mFileHandle(nullptr) {} + // wrap (e.g.) result of LLFile::fopen() + LLUniqueFile(LLFILE* f): mFileHandle(f) {} + // no copy + LLUniqueFile(const LLUniqueFile&) = delete; + // move construction + LLUniqueFile(LLUniqueFile&& other) + { + mFileHandle = other.mFileHandle; + other.mFileHandle = nullptr; + } + // The point of LLUniqueFile is to close on destruction. + ~LLUniqueFile() + { + close(); + } + + // simple assignment + LLUniqueFile& operator=(LLFILE* f) + { + close(); + mFileHandle = f; + return *this; + } + // copy assignment deleted + LLUniqueFile& operator=(const LLUniqueFile&) = delete; + // move assignment + LLUniqueFile& operator=(LLUniqueFile&& other) + { + close(); + std::swap(mFileHandle, other.mFileHandle); + return *this; + } + + // explicit close operation + void close() + { + if (mFileHandle) + { + // in case close() throws, set mFileHandle null FIRST + LLFILE* h{nullptr}; + std::swap(h, mFileHandle); + LLFile::close(h); + } + } + + // detect whether the wrapped LLFILE is open or not + explicit operator bool() const { return bool(mFileHandle); } + bool operator!() { return ! mFileHandle; } + + // LLUniqueFile should be usable for any operation that accepts LLFILE* + // (or FILE* for that matter) + operator LLFILE*() const { return mFileHandle; } + +private: + LLFILE* mFileHandle; +}; + #if LL_WINDOWS /** * @brief Controlling input for files. |