From 9d071d2a2cec9a7662a02669488569a017f0ea35 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Mon, 13 Feb 2017 21:25:04 -0700 Subject: 8.9 --- zen/file_io.h | 240 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 123 insertions(+), 117 deletions(-) mode change 100644 => 100755 zen/file_io.h (limited to 'zen/file_io.h') diff --git a/zen/file_io.h b/zen/file_io.h old mode 100644 new mode 100755 index 4a135150..8a5e0f7f --- 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 inline -BinContainer loadBinContainer(const Zstring& filePath, //throw FileError - const std::function& notifyProgress) //optional -{ - FileInput streamIn(filePath); //throw FileError, ErrorFileLocked - return unbufferedLoad(streamIn, notifyProgress); //throw FileError -} - - -template inline -void saveBinContainer(const Zstring& filePath, const BinContainer& buffer, //throw FileError - const std::function& 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 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 memBuf_; + const IOCallback notifyUnbufferedIO_; //throw X +}; + +//----------------------------------------------------------------------------------------------- + +//native stream I/O convenience functions: + +template inline +BinContainer loadBinContainer(const Zstring& filePath, //throw FileError + const IOCallback& notifyUnbufferedIO) +{ + FileInput streamIn(filePath, notifyUnbufferedIO); //throw FileError, ErrorFileLocked + return bufferedLoad(streamIn); //throw FileError, X; +} + + +template 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 -- cgit