diff options
| author | Carl Hetherington <cth@carlh.net> | 2015-01-14 17:39:32 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2015-01-20 11:20:25 +0000 |
| commit | 3f630fb8334238ab8a58fbe1a0f513ae2c00de80 (patch) | |
| tree | 4b773b91029d6374bfd4f2194053d3e249d597cd /asdcplib/src/KM_fileio.h | |
| parent | 49cafda01b3e07c47e3b20dd5ee91e1426446aea (diff) | |
Simplify time representation; better in-tree DCP subtitle parser.
Diffstat (limited to 'asdcplib/src/KM_fileio.h')
| -rwxr-xr-x | asdcplib/src/KM_fileio.h | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/asdcplib/src/KM_fileio.h b/asdcplib/src/KM_fileio.h new file mode 100755 index 0000000..cb00acc --- /dev/null +++ b/asdcplib/src/KM_fileio.h @@ -0,0 +1,342 @@ +/* +Copyright (c) 2004-2009, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + /*! \file KM_fileio.h + \version $Id: KM_fileio.h,v 1.17 2009/06/22 05:49:02 jhurst Exp $ + \brief portable file i/o + */ + +#ifndef _KM_FILEIO_H_ +#define _KM_FILEIO_H_ + +#include <KM_util.h> +#include <string> +#include <boost/filesystem.hpp> +#include <openssl/md5.h> + +#ifdef KM_WIN32 +# include <io.h> +#else +# include <dirent.h> +# include <unistd.h> +# include <time.h> +# include <sys/types.h> +#include <regex.h> +#endif + +#include <sys/stat.h> + + + +namespace Kumu +{ + class DirScanner + { + public: + DirScanner(); + Result_t Open(const char *); + Result_t GetNext(char *); + Result_t Close(); + private: + boost::filesystem::directory_iterator _iterator; + }; + +#ifdef KM_WIN32 + typedef __int64 fsize_t; + typedef __int64 fpos_t; + typedef HANDLE FileHandle; + + enum SeekPos_t { + SP_BEGIN = FILE_BEGIN, + SP_POS = FILE_CURRENT, + SP_END = FILE_END + }; +#else + typedef off_t fsize_t; + typedef off_t fpos_t; + typedef int FileHandle; + const FileHandle INVALID_HANDLE_VALUE = -1L; + + enum SeekPos_t { + SP_BEGIN = SEEK_SET, + SP_POS = SEEK_CUR, + SP_END = SEEK_END + }; +#endif + + // +#ifndef KM_SMALL_FILES_OK + template <bool sizecheck> void compile_time_size_checker(); + template <> inline void compile_time_size_checker<false>() {} + // + // 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<sizeof(Kumu::fsize_t)==sizeof(ui64_t)>() {} +#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<std::string> PathCompList_t; // a list of path components + typedef std::list<std::string> 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 + bool PathsAreEquivalent(const std::string& lhs, const std::string& rhs); // true if paths point to the same filesystem entry + + // 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 + bool PathHasComponents(const std::string& Path, char separator = '/'); // true if paths starts with separator + + bool PathIsAbsolute(const std::string& Path, char separator = '/'); // true if path begins with separator + 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 '..' + + // 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 + { + public: + virtual ~IPathMatch() {} + 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&) const { return true; } + }; + +#ifndef KM_WIN32 + // matches pathnames using a regular expression + class PathMatchRegex : public IPathMatch + { + regex_t m_regex; + PathMatchRegex(); + const PathMatchRegex& operator=(const PathMatchRegex&); + + public: + PathMatchRegex(const std::string& Pattern); + PathMatchRegex(const PathMatchRegex&); + virtual ~PathMatchRegex(); + bool Match(const std::string& s) const; + }; + + // matches pathnames using a Bourne shell glob expression + class PathMatchGlob : public IPathMatch + { + regex_t m_regex; + PathMatchGlob(); + const PathMatchGlob& operator=(const PathMatchGlob&); + + public: + PathMatchGlob(const std::string& Pattern); + PathMatchGlob(const PathMatchGlob&); + 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 = false, char separator = '/'); + + PathList_t& FindInPaths(const IPathMatch& Pattern, const PathList_t& SearchPaths, + PathList_t& FoundPaths, bool one_shot = false, char separator = '/'); + + //------------------------------------------------------------------------------------------ + // 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); + + //------------------------------------------------------------------------------------------ + // 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); + + // Writes a string to a file, overwrites the existing file if present. + Result_t WriteStringIntoFile(const char* 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); + + + //------------------------------------------------------------------------------------------ + // File I/O + //------------------------------------------------------------------------------------------ + + // + class FileReader + { + KM_NO_COPY_CONSTRUCT(FileReader); + + protected: + std::string m_Filename; + 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 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 + Result_t Tell(Kumu::fpos_t* pos) const; // report the file pointer's location + Result_t Read(byte_t*, ui32_t, ui32_t* = 0) const; // read a buffer of data + + inline Kumu::fpos_t Tell() const // report the file pointer's location + { + Kumu::fpos_t tmp_pos; + Tell(&tmp_pos); + return tmp_pos; + } + + inline bool IsOpen() { // returns true if the file is open + return (m_Handle != INVALID_HANDLE_VALUE); + } + }; + + // + class FileWriter : public FileReader + { + class h__iovec; + mem_ptr<h__iovec> m_IOVec; + KM_NO_COPY_CONSTRUCT(FileWriter); + bool m_Hashing; + MD5_CTX m_MD5Context; + + public: + 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 + + // 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*), + // the given buffer is added to an internal iovec struct. All items on the list + // are written to disk by a call to Writev(); + Result_t Writev(const byte_t*, ui32_t); // queue buffer for "gather" write + Result_t Writev(ui32_t* = 0); // write all queued buffers + + // if you call this while there are unwritten items on the iovec list, + // the iovec list will be written to disk before the given buffer,as though + // you had called Writev() first. + Result_t Write(const byte_t*, ui32_t, ui32_t* = 0); // write buffer to disk + + void StartHashing(); + void MaybeHash(void const *, int); + std::string StopHashing(); + }; + + 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 + + +#endif // _KM_FILEIO_H_ + + +// +// end KM_fileio.h +// |
