fs/io/FileOutputStream: add mode APPEND_OR_CREATE

This commit is contained in:
Max Kellermann 2016-09-04 13:00:51 +02:00
parent d775f13a03
commit f600e226da
2 changed files with 21 additions and 6 deletions

View File

@ -30,7 +30,11 @@ FileOutputStream::FileOutputStream(Path _path, Mode _mode)
break; break;
case Mode::APPEND_EXISTING: case Mode::APPEND_EXISTING:
OpenAppendExisting(); OpenAppend(false);
break;
case Mode::APPEND_OR_CREATE:
OpenAppend(true);
break; break;
} }
} }
@ -50,10 +54,10 @@ FileOutputStream::OpenCreate()
} }
inline void inline void
FileOutputStream::OpenAppendExisting() FileOutputStream::OpenAppend(bool create)
{ {
handle = CreateFile(path.c_str(), GENERIC_WRITE, 0, nullptr, handle = CreateFile(path.c_str(), GENERIC_WRITE, 0, nullptr,
OPEN_EXISTING, create ? OPEN_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
nullptr); nullptr);
if (!IsDefined()) if (!IsDefined())
@ -162,9 +166,13 @@ FileOutputStream::OpenCreate()
} }
inline void inline void
FileOutputStream::OpenAppendExisting() FileOutputStream::OpenAppend(bool create)
{ {
if (!fd.Open(path.c_str(), O_WRONLY|O_APPEND)) int flags = O_WRONLY|O_APPEND;
if (create)
flags |= O_CREAT;
if (!fd.Open(path.c_str(), flags))
throw FormatErrno("Failed to append to %s", throw FormatErrno("Failed to append to %s",
path.c_str()); path.c_str());
} }
@ -234,6 +242,7 @@ FileOutputStream::Cancel()
break; break;
case Mode::APPEND_EXISTING: case Mode::APPEND_EXISTING:
case Mode::APPEND_OR_CREATE:
/* can't roll this back */ /* can't roll this back */
break; break;
} }

View File

@ -69,6 +69,12 @@ public:
* not, an exception is thrown. * not, an exception is thrown.
*/ */
APPEND_EXISTING, APPEND_EXISTING,
/**
* Like #APPEND_EXISTING, but create the file if it
* does not exist.
*/
APPEND_OR_CREATE,
}; };
private: private:
@ -98,7 +104,7 @@ public:
private: private:
void OpenCreate(); void OpenCreate();
void OpenAppendExisting(); void OpenAppend(bool create);
bool Close() { bool Close() {
assert(IsDefined()); assert(IsDefined());