diff options
author | Daniel Wilhelm <shieldwed@outlook.com> | 2017-02-13 21:25:04 -0700 |
---|---|---|
committer | Daniel Wilhelm <shieldwed@outlook.com> | 2017-02-13 21:25:04 -0700 |
commit | 9d071d2a2cec9a7662a02669488569a017f0ea35 (patch) | |
tree | c83a623fbdff098339b66d21ea2e81f3f67344ae /zen/file_io.h | |
parent | 8.8 (diff) | |
download | FreeFileSync-9d071d2a2cec9a7662a02669488569a017f0ea35.tar.gz FreeFileSync-9d071d2a2cec9a7662a02669488569a017f0ea35.tar.bz2 FreeFileSync-9d071d2a2cec9a7662a02669488569a017f0ea35.zip |
8.9
Diffstat (limited to 'zen/file_io.h')
-rwxr-xr-x[-rw-r--r--] | zen/file_io.h | 240 |
1 files changed, 123 insertions, 117 deletions
diff --git a/zen/file_io.h b/zen/file_io.h index 4a135150..8a5e0f7f 100644..100755 --- a/zen/file_io.h +++ b/zen/file_io.h @@ -1,117 +1,123 @@ -// ***************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * -// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * -// ***************************************************************************** - -#ifndef FILE_IO_H_89578342758342572345 -#define FILE_IO_H_89578342758342572345 - -#include "file_error.h" -#include "serialize.h" - -#ifdef ZEN_WIN - #include "win.h" //includes "windows.h" -#endif - - -namespace zen -{ -#ifdef ZEN_WIN - const char LINE_BREAK[] = "\r\n"; -#elif defined ZEN_LINUX || defined ZEN_MAC - const char LINE_BREAK[] = "\n"; //since OS X apple uses newline, too -#endif - -//OS-buffered file IO optimized for sequential read/write accesses + better error reporting + long path support + following symlinks - -#ifdef ZEN_WIN - using FileHandle = HANDLE; -#elif defined ZEN_LINUX || defined ZEN_MAC - using FileHandle = int; -#endif - -class FileBase -{ -public: - const Zstring& getFilePath() const { return filename_; } - -protected: - FileBase(const Zstring& filename) : filename_(filename) {} - -private: - FileBase (const FileBase&) = delete; - FileBase& operator=(const FileBase&) = delete; - - const Zstring filename_; -}; - -//----------------------------------------------------------------------------------------------- - -class FileInput : public FileBase -{ -public: - FileInput(const Zstring& filePath); //throw FileError, ErrorFileLocked - FileInput(FileHandle handle, const Zstring& filePath); //takes ownership! - ~FileInput(); - - //Windows: better use 64kB ?? https://technet.microsoft.com/en-us/library/cc938632 - //Linux: use st_blksize? - size_t getBlockSize() const { return 128 * 1024; } - size_t tryRead(void* buffer, size_t bytesToRead); //throw FileError; may return short, only 0 means EOF! => CONTRACT: bytesToRead > 0! - - FileHandle getHandle() { return fileHandle; } - -private: - FileHandle fileHandle; -}; - - -class FileOutput : public FileBase -{ -public: - enum AccessFlag - { - ACC_OVERWRITE, - ACC_CREATE_NEW - }; - - FileOutput(const Zstring& filePath, AccessFlag access); //throw FileError, ErrorTargetExisting - FileOutput(FileHandle handle, const Zstring& filePath); //takes ownership! - ~FileOutput(); - - FileOutput(FileOutput&& tmp); - - size_t getBlockSize() const { return 128 * 1024; } - size_t tryWrite(const void* buffer, size_t bytesToWrite); //throw FileError; may return short! CONTRACT: bytesToWrite > 0 - - void close(); //throw FileError -> optional, but good place to catch errors when closing stream! - FileHandle getHandle() { return fileHandle; } - -private: - FileHandle fileHandle; -}; - - -//native stream I/O convenience functions: - -template <class BinContainer> inline -BinContainer loadBinContainer(const Zstring& filePath, //throw FileError - const std::function<void(std::int64_t bytesDelta)>& notifyProgress) //optional -{ - FileInput streamIn(filePath); //throw FileError, ErrorFileLocked - return unbufferedLoad<BinContainer>(streamIn, notifyProgress); //throw FileError -} - - -template <class BinContainer> inline -void saveBinContainer(const Zstring& filePath, const BinContainer& buffer, //throw FileError - const std::function<void(std::int64_t bytesDelta)>& notifyProgress) //optional -{ - FileOutput fileOut(filePath, FileOutput::ACC_OVERWRITE); // - unbufferedSave(buffer, fileOut, notifyProgress); //throw FileError - fileOut.close(); // -} -} - -#endif //FILE_IO_H_89578342758342572345 +// *****************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
+// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
+// *****************************************************************************
+
+#ifndef FILE_IO_H_89578342758342572345
+#define FILE_IO_H_89578342758342572345
+
+#include "file_error.h"
+#include "serialize.h"
+
+
+namespace zen
+{
+ const char LINE_BREAK[] = "\n"; //since OS X apple uses newline, too
+
+/*
+OS-buffered file IO optimized for
+ - sequential read/write accesses
+ - better error reporting
+ - long path support
+ - follows symlinks
+ */
+class FileBase
+{
+public:
+ const Zstring& getFilePath() const { return filePath_; }
+
+ using FileHandle = int;
+
+ FileHandle getHandle() { return fileHandle_; }
+
+ //Windows: use 64kB ?? https://technet.microsoft.com/en-us/library/cc938632
+ //Linux: use st_blksize?
+ static size_t getBlockSize() { return 128 * 1024; };
+
+protected:
+ FileBase(FileHandle handle, const Zstring& filePath) : fileHandle_(handle), filePath_(filePath) {}
+ ~FileBase();
+
+ void close(); //throw FileError -> optional, but good place to catch errors when closing stream!
+ static const FileHandle invalidHandleValue;
+
+private:
+ FileBase (const FileBase&) = delete;
+ FileBase& operator=(const FileBase&) = delete;
+
+ FileHandle fileHandle_ = invalidHandleValue;
+ const Zstring filePath_;
+};
+
+//-----------------------------------------------------------------------------------------------
+
+class FileInput : public FileBase
+{
+public:
+ FileInput(const Zstring& filePath, const IOCallback& notifyUnbufferedIO); //throw FileError, ErrorFileLocked
+ FileInput(FileHandle handle, const Zstring& filePath, const IOCallback& notifyUnbufferedIO); //takes ownership!
+
+ size_t read(void* buffer, size_t bytesToRead); //throw FileError, X; return "bytesToRead" bytes unless end of stream!
+
+private:
+ size_t tryRead(void* buffer, size_t bytesToRead); //throw FileError; may return short, only 0 means EOF! => CONTRACT: bytesToRead > 0!
+
+ std::vector<char> memBuf_;
+ const IOCallback notifyUnbufferedIO_; //throw X
+};
+
+
+class FileOutput : public FileBase
+{
+public:
+ enum AccessFlag
+ {
+ ACC_OVERWRITE,
+ ACC_CREATE_NEW
+ };
+ FileOutput(const Zstring& filePath, AccessFlag access, const IOCallback& notifyUnbufferedIO); //throw FileError, ErrorTargetExisting
+ FileOutput(FileHandle handle, const Zstring& filePath, const IOCallback& notifyUnbufferedIO); //takes ownership!
+ ~FileOutput();
+
+ void preAllocateSpaceBestEffort(uint64_t expectedSize); //throw FileError
+
+ void write(const void* buffer, size_t bytesToWrite); //throw FileError, X
+ void flushBuffers(); //throw FileError, X
+ void finalize(); /*= flushBuffers() + close()*/ //throw FileError, X
+
+private:
+ size_t tryWrite(const void* buffer, size_t bytesToWrite); //throw FileError; may return short! CONTRACT: bytesToWrite > 0
+
+ std::vector<char> memBuf_;
+ const IOCallback notifyUnbufferedIO_; //throw X
+};
+
+//-----------------------------------------------------------------------------------------------
+
+//native stream I/O convenience functions:
+
+template <class BinContainer> inline
+BinContainer loadBinContainer(const Zstring& filePath, //throw FileError
+ const IOCallback& notifyUnbufferedIO)
+{
+ FileInput streamIn(filePath, notifyUnbufferedIO); //throw FileError, ErrorFileLocked
+ return bufferedLoad<BinContainer>(streamIn); //throw FileError, X;
+}
+
+
+template <class BinContainer> inline
+void saveBinContainer(const Zstring& filePath, const BinContainer& buffer, //throw FileError
+ const IOCallback& notifyUnbufferedIO)
+{
+ FileOutput fileOut(filePath, FileOutput::ACC_OVERWRITE, notifyUnbufferedIO); //throw FileError, (ErrorTargetExisting)
+ if (!buffer.empty())
+ {
+ /*snake oil?*/ fileOut.preAllocateSpaceBestEffort(buffer.size()); //throw FileError
+ fileOut.write(&*buffer.begin(), buffer.size()); //throw FileError, X
+ }
+ fileOut.finalize(); //throw FileError, X
+}
+}
+
+#endif //FILE_IO_H_89578342758342572345
|