X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FKM_fileio.h;h=60e1e6a3c37988d61e5968841e9e224f8eece206;hb=1c26f274039b5ccb93ba138482e5328de0c7df2e;hp=43b164df2c5fc58681dfdf12222712717a5ba228;hpb=3a3aa48a5a4f7324a9e4c2273d0747d7f58a2813;p=asdcplib.git diff --git a/src/KM_fileio.h b/src/KM_fileio.h index 43b164d..60e1e6a 100755 --- a/src/KM_fileio.h +++ b/src/KM_fileio.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2006, John Hurst +Copyright (c) 2004-2016, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef KM_WIN32 # include +# include "dirent_win.h" #else # include # include @@ -55,24 +56,54 @@ namespace Kumu class DirScanner { public: -#ifdef KM_WIN32 - __int64 m_Handle; - struct _finddatai64_t m_FileInfo; -#else DIR* m_Handle; -#endif - DirScanner() {}; + DirScanner(void); ~DirScanner() { Close(); } - Result_t Open(const char*); + Result_t Open(const std::string&); Result_t Close(); Result_t GetNext(char*); }; + + // + enum DirectoryEntryType_t { + DET_FILE, + DET_DIR, + DET_DEV, + DET_LINK + }; + + // + class DirScannerEx + { + std::string m_Dirname; + DIR* m_Handle; + + KM_NO_COPY_CONSTRUCT(DirScannerEx); + + public: + + DirScannerEx(); + ~DirScannerEx() { Close(); } + + Result_t Open(const std::string& dirname); + Result_t Close(); + + + inline Result_t GetNext(std::string& next_item_name) { + DirectoryEntryType_t ft; + return GetNext(next_item_name, ft); + } + + Result_t GetNext(std::string& next_item_name, DirectoryEntryType_t& next_item_type); + }; + #ifdef KM_WIN32 typedef __int64 fsize_t; typedef __int64 fpos_t; + typedef HANDLE FileHandle; enum SeekPos_t { SP_BEGIN = FILE_BEGIN, @@ -82,8 +113,8 @@ namespace Kumu #else typedef off_t fsize_t; typedef off_t fpos_t; - typedef int HANDLE; - const HANDLE INVALID_HANDLE_VALUE = -1L; + typedef int FileHandle; + const FileHandle INVALID_HANDLE_VALUE = -1L; enum SeekPos_t { SP_BEGIN = SEEK_SET, @@ -92,24 +123,53 @@ namespace Kumu }; #endif + // +#ifndef KM_SMALL_FILES_OK + template void compile_time_size_checker(); + template <> inline void compile_time_size_checker() {} + // + // READ THIS if your compiler is complaining about a previously declared implementation of + // compile_time_size_checker(). For example, GCC 4.0.1 looks like this: + // + // error: 'void Kumu::compile_time_size_checker() [with bool sizecheck = false]' previously declared here + // + // This is happening because the equality being tested below is false. The reason for this + // will depend on your OS, but on Linux it is probably because you have not used -D_FILE_OFFSET_BITS=64 + // Adding this magic macro to your CFLAGS will get you going again. If you are on a system that + // does not support 64-bit files, you can disable this check by using -DKM_SMALL_FILES_OK. You + // will then of course be limited to file sizes < 4GB. + // + template <> inline void compile_time_size_checker() {} +#endif + // + const ui32_t Kilobyte = 1024; const ui32_t Megabyte = Kilobyte * Kilobyte; const ui32_t Gigabyte = Megabyte * Kilobyte; const ui32_t MaxFilePath = Kilobyte; + + //------------------------------------------------------------------------------------------ // Path Manglers - // + //------------------------------------------------------------------------------------------ + + // types typedef std::list PathCompList_t; // a list of path components typedef std::list PathList_t; // a list of paths + // tests bool PathExists(const std::string& Path); // true if the path exists in the filesystem bool PathIsFile(const std::string& Path); // true if the path exists in the filesystem and is a file bool PathIsDirectory(const std::string& Path); // true if the path exists in the filesystem and is a directory fsize_t FileSize(const std::string& Path); // returns the size of a regular file, 0 for a directory or device + std::string PathCwd(); bool PathsAreEquivalent(const std::string& lhs, const std::string& rhs); // true if paths point to the same filesystem entry - // split and reassemble pats as lists of path components + // Returns free space and total space available for the given path + Result_t FreeSpaceForPath(const std::string& path, Kumu::fsize_t& free_space, Kumu::fsize_t& total_space); + + // split and reassemble paths as lists of path components PathCompList_t& PathToComponents(const std::string& Path, PathCompList_t& CList, char separator = '/'); // removes '//' std::string ComponentsToPath(const PathCompList_t& CList, char separator = '/'); std::string ComponentsToAbsolutePath(const PathCompList_t& CList, char separator = '/'); // add separator to the front @@ -119,13 +179,25 @@ namespace Kumu std::string PathMakeAbsolute(const std::string& Path, char separator = '/'); // compute position of relative path using getcwd() std::string PathMakeLocal(const std::string& Path, const std::string& Parent); // remove Parent from front of Path, if it exists std::string PathMakeCanonical(const std::string& Path, char separator = '/'); // remove '.' and '..' + bool PathResolveLinks(const std::string& link_path, std::string& resolved_path, char separator = '/'); + // common operations std::string PathBasename(const std::string& Path, char separator = '/'); // returns right-most path element (list back()) std::string PathDirname(const std::string& Path, char separator = '/'); // returns everything but the right-most element std::string PathGetExtension(const std::string& Path); // returns everything in the right-most element following the right-most '.' std::string PathSetExtension(const std::string& Path, const std::string& Extension); // empty extension removes '.' as well - // + std::string PathJoin(const std::string& Path1, const std::string& Path2, char separator = '/'); + std::string PathJoin(const std::string& Path1, const std::string& Path2, const std::string& Path3, char separator = '/'); + std::string PathJoin(const std::string& Path1, const std::string& Path2, + const std::string& Path3, const std::string& Path4, char separator = '/'); + + + //------------------------------------------------------------------------------------------ + // Path Search + //------------------------------------------------------------------------------------------ + + // An interface for a path matching function, used by FindInPath() and FindInPaths() below // class IPathMatch { @@ -134,13 +206,16 @@ namespace Kumu virtual bool Match(const std::string& s) const = 0; }; + // matches any pathname class PathMatchAny : public IPathMatch { public: virtual ~PathMatchAny() {} - inline bool Match(const std::string& s) const { return true; } + inline bool Match(const std::string&) const { return true; } }; +#ifndef KM_WIN32 + // matches pathnames using a regular expression class PathMatchRegex : public IPathMatch { regex_t m_regex; @@ -154,6 +229,7 @@ namespace Kumu bool Match(const std::string& s) const; }; + // matches pathnames using a Bourne shell glob expression class PathMatchGlob : public IPathMatch { regex_t m_regex; @@ -166,23 +242,77 @@ namespace Kumu virtual ~PathMatchGlob(); bool Match(const std::string& s) const; }; +#endif /* !KM_WIN32 */ // Search all paths in SearchPaths for filenames matching Pattern (no directories are returned). // Put results in FoundPaths. Returns after first find if one_shot is true. PathList_t& FindInPath(const IPathMatch& Pattern, const std::string& SearchDir, - PathList_t& FoundPaths, bool one_shot, char separator); + PathList_t& FoundPaths, bool one_shot = false, char separator = '/'); PathList_t& FindInPaths(const IPathMatch& Pattern, const PathList_t& SearchPaths, PathList_t& FoundPaths, bool one_shot = false, char separator = '/'); + std::string GetExecutablePath(const std::string& default_path); + + //------------------------------------------------------------------------------------------ + // Directory Manipulation + //------------------------------------------------------------------------------------------ + + // Create a directory, creates intermediate directories as necessary + Result_t CreateDirectoriesInPath(const std::string& Path); + + // Delete a file (fails if the path points to a directory) + Result_t DeleteFile(const std::string& filename); + + // Recursively remove a file or directory + Result_t DeletePath(const std::string& pathname); + + // Remove the path only if it is a directory that is empty. + Result_t DeleteDirectoryIfEmpty(const std::string& path); + + //------------------------------------------------------------------------------------------ + // File I/O Wrappers + //------------------------------------------------------------------------------------------ // Instant IO for strings // // Reads an entire file into a string. - Result_t ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size = 8 * Megabyte); + Result_t ReadFileIntoString(const std::string& filename, std::string& outString, ui32_t max_size = 8 * Megabyte); // Writes a string to a file, overwrites the existing file if present. - Result_t WriteStringIntoFile(const char* filename, const std::string& inString); + Result_t WriteStringIntoFile(const std::string& filename, const std::string& inString); + + // Instant IO for archivable objects + // + // Unarchives a file into an object + Result_t ReadFileIntoObject(const std::string& Filename, IArchive& Object, ui32_t max_size = 8 * Kumu::Megabyte); + + // Archives an object into a file + Result_t WriteObjectIntoFile(const IArchive& Object, const std::string& Filename); + + // Instant IO for memory buffers + // + // Unarchives a file into a buffer + Result_t ReadFileIntoBuffer(const std::string& Filename, Kumu::ByteString& Buffer, + ui32_t max_size = 8 * Kumu::Megabyte); + + // Archives a buffer into a file + Result_t WriteBufferIntoFile(const Kumu::ByteString& Buffer, const std::string& Filename); + + +#ifdef KM_WIN32_UTF8 + //------------------------------------------------------------------------------------------ + // wide char support for win32 file I/O + //------------------------------------------------------------------------------------------ + + // + Result_t wbstr_to_utf8(const Kumu::ByteString& in, std::string& out); + Result_t utf8_to_wbstr(const std::string& in, Kumu::ByteString& out); +#endif + + //------------------------------------------------------------------------------------------ + // File I/O + //------------------------------------------------------------------------------------------ // class FileReader @@ -191,13 +321,13 @@ namespace Kumu protected: std::string m_Filename; - HANDLE m_Handle; + FileHandle m_Handle; public: FileReader() : m_Handle(INVALID_HANDLE_VALUE) {} virtual ~FileReader() { Close(); } - Result_t OpenRead(const char*) const; // open the file for reading + Result_t OpenRead(const std::string&) const; // open the file for reading Result_t Close() const; // close the file fsize_t Size() const; // returns the file's current size Result_t Seek(Kumu::fpos_t = 0, SeekPos_t = SP_BEGIN) const; // move the file pointer @@ -227,8 +357,8 @@ namespace Kumu FileWriter(); virtual ~FileWriter(); - Result_t OpenWrite(const char*); // open a new file, overwrites existing - Result_t OpenModify(const char*); // open a file for read/write + Result_t OpenWrite(const std::string&); // open a new file, overwrites existing + Result_t OpenModify(const std::string&); // open a file for read/write // this part of the interface takes advantage of the iovec structure on // platforms that support it. For each call to Writev(const byte_t*, ui32_t, ui32_t*), @@ -243,6 +373,11 @@ namespace Kumu Result_t Write(const byte_t*, ui32_t, ui32_t* = 0); // write buffer to disk }; + Result_t CreateDirectoriesInPath(const std::string& Path); + Result_t FreeSpaceForPath(const std::string& path, Kumu::fsize_t& free_space, Kumu::fsize_t& total_space); + Result_t DeleteFile(const std::string& filename); + Result_t DeletePath(const std::string& pathname); + } // namespace Kumu