summaryrefslogtreecommitdiff
path: root/indra/llcommon/llfile.h
diff options
context:
space:
mode:
authorDave Houlton <euclid@lindenlab.com>2020-07-23 19:21:30 +0000
committerDave Houlton <euclid@lindenlab.com>2020-07-23 19:21:30 +0000
commit6fbf39f9b319106e39f80b8641acaba122d02e0a (patch)
treee47af1ff1bd1db52fd93c11d857b11387bacf01a /indra/llcommon/llfile.h
parent05200cf827d9a6263adc4905bf41a4905bce2659 (diff)
parent64a9ad0f5f52dac633a76e39335a7def2573b82e (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.h63
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.