summaryrefslogtreecommitdiff
path: root/zen/file_io.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <shieldwed@outlook.com>2017-02-13 21:25:04 -0700
committerDaniel Wilhelm <shieldwed@outlook.com>2017-02-13 21:25:04 -0700
commit9d071d2a2cec9a7662a02669488569a017f0ea35 (patch)
treec83a623fbdff098339b66d21ea2e81f3f67344ae /zen/file_io.h
parent8.8 (diff)
downloadFreeFileSync-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.h240
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
bgstack15