From 7f6e1fbc8d463308e374bb7d9b112cd9f452f76e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 23 Mar 2015 22:42:07 +0100 Subject: fs/io/FileOutputStream: add class AppendFileOutputStream --- src/fs/io/FileOutputStream.cxx | 55 ++++++++++++++++++++++++++++++++++++++++++ src/fs/io/FileOutputStream.hxx | 12 +++++++++ 2 files changed, 67 insertions(+) (limited to 'src') diff --git a/src/fs/io/FileOutputStream.cxx b/src/fs/io/FileOutputStream.cxx index f587874a3..82d9c3dc1 100644 --- a/src/fs/io/FileOutputStream.cxx +++ b/src/fs/io/FileOutputStream.cxx @@ -197,4 +197,59 @@ FileOutputStream::Cancel() RemoveFile(GetPath()); } +#ifdef WIN32 + +FileOutputStream::FileOutputStream(Path _path, Error &error) + :path(_path), + handle(CreateFile(path.c_str(), GENERIC_WRITE, 0, nullptr, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH, + nullptr)) +{ + if (handle == INVALID_HANDLE_VALUE) { + const auto path_utf8 = path.ToUTF8(); + error.FormatLastError("Failed to create %s", + path_utf8.c_str()); + } +} + +#else + +AppendFileOutputStream::AppendFileOutputStream(Path _path, Error &error) + :BaseFileOutputStream(_path) +{ +#ifdef WIN32 + SetHandle(CreateFile(path.c_str(), GENERIC_WRITE, 0, nullptr, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH, + nullptr)) + if (!IsDefined()) + error.FormatLastError("Failed to append to %s", + GetPath().ToUTF8().c_str()); +#else + if (!SetFD().Open(GetPath().c_str(), + O_WRONLY|O_APPEND)) + error.FormatErrno("Failed to append to %s", + GetPath().c_str()); +#endif +} + +#endif + +bool +AppendFileOutputStream::Commit(gcc_unused Error &error) +{ + assert(IsDefined()); + +#ifdef WIN32 + return Close(); +#else + bool success = Close(); + if (!success) + error.FormatErrno("Failed to commit %s", GetPath().c_str()); + + return success; +#endif +} + #endif diff --git a/src/fs/io/FileOutputStream.hxx b/src/fs/io/FileOutputStream.hxx index ce53427e2..9decb6f00 100644 --- a/src/fs/io/FileOutputStream.hxx +++ b/src/fs/io/FileOutputStream.hxx @@ -135,4 +135,16 @@ public: void Cancel(); }; +class AppendFileOutputStream final : public BaseFileOutputStream { +public: + AppendFileOutputStream(Path _path, Error &error); + + ~AppendFileOutputStream() { + if (IsDefined()) + Close(); + } + + bool Commit(Error &error); +}; + #endif -- cgit v1.2.3