diff options
Diffstat (limited to 'libs/glibmm2/glibmm/fileutils.h')
-rw-r--r-- | libs/glibmm2/glibmm/fileutils.h | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/libs/glibmm2/glibmm/fileutils.h b/libs/glibmm2/glibmm/fileutils.h new file mode 100644 index 0000000000..67f1106a64 --- /dev/null +++ b/libs/glibmm2/glibmm/fileutils.h @@ -0,0 +1,475 @@ +// -*- c++ -*- +// Generated by gtkmmproc -- DO NOT MODIFY! +#ifndef _GLIBMM_FILEUTILS_H +#define _GLIBMM_FILEUTILS_H + + +/* $Id$ */ + +/* Copyright (C) 2002 The gtkmm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +extern "C" { typedef struct _GDir GDir; } +#endif + +#include <iterator> +#include <string> + +#include <glibmmconfig.h> +#include <glibmm/error.h> + +GLIBMM_USING_STD(input_iterator_tag) +GLIBMM_USING_STD(string) + + +namespace Glib +{ + +/** @addtogroup glibmmEnums Enums and Flags */ + +/** + * @ingroup glibmmEnums + * @par Bitwise operators: + * <tt>%FileTest operator|(FileTest, FileTest)</tt><br> + * <tt>%FileTest operator&(FileTest, FileTest)</tt><br> + * <tt>%FileTest operator^(FileTest, FileTest)</tt><br> + * <tt>%FileTest operator~(FileTest)</tt><br> + * <tt>%FileTest& operator|=(FileTest&, FileTest)</tt><br> + * <tt>%FileTest& operator&=(FileTest&, FileTest)</tt><br> + * <tt>%FileTest& operator^=(FileTest&, FileTest)</tt><br> + */ +enum FileTest +{ + FILE_TEST_IS_REGULAR = 1 << 0, + FILE_TEST_IS_SYMLINK = 1 << 1, + FILE_TEST_IS_DIR = 1 << 2, + FILE_TEST_IS_EXECUTABLE = 1 << 3, + FILE_TEST_EXISTS = 1 << 4 +}; + +/** @ingroup glibmmEnums */ +inline FileTest operator|(FileTest lhs, FileTest rhs) + { return static_cast<FileTest>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); } + +/** @ingroup glibmmEnums */ +inline FileTest operator&(FileTest lhs, FileTest rhs) + { return static_cast<FileTest>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); } + +/** @ingroup glibmmEnums */ +inline FileTest operator^(FileTest lhs, FileTest rhs) + { return static_cast<FileTest>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); } + +/** @ingroup glibmmEnums */ +inline FileTest operator~(FileTest flags) + { return static_cast<FileTest>(~static_cast<unsigned>(flags)); } + +/** @ingroup glibmmEnums */ +inline FileTest& operator|=(FileTest& lhs, FileTest rhs) + { return (lhs = static_cast<FileTest>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); } + +/** @ingroup glibmmEnums */ +inline FileTest& operator&=(FileTest& lhs, FileTest rhs) + { return (lhs = static_cast<FileTest>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); } + +/** @ingroup glibmmEnums */ +inline FileTest& operator^=(FileTest& lhs, FileTest rhs) + { return (lhs = static_cast<FileTest>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); } + + +/** @defgroup FileUtils File Utilities + * Various file-related classes and functions. + */ + +/** Exception class for file-related errors. + * @ingroup FileUtils + */ +class FileError : public Glib::Error +{ +public: + enum Code + { + EXISTS, + IS_DIRECTORY, + ACCESS_DENIED, + NAME_TOO_LONG, + NO_SUCH_ENTITY, + NOT_DIRECTORY, + NO_SUCH_DEVICE, + NOT_DEVICE, + READONLY_FILESYSTEM, + TEXT_FILE_BUSY, + FAULTY_ADDRESS, + SYMLINK_LOOP, + NO_SPACE_LEFT, + NOT_ENOUGH_MEMORY, + TOO_MANY_OPEN_FILES, + FILE_TABLE_OVERFLOW, + BAD_FILE_DESCRIPTOR, + INVALID_ARGUMENT, + BROKEN_PIPE, + TRYAGAIN, + INTERRUPTED, + IO_ERROR, + NOT_OWNER, + NOSYS, + FAILED + }; + + FileError(Code error_code, const Glib::ustring& error_message); + explicit FileError(GError* gobject); + Code code() const; + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +private: + static void throw_func(GError* gobject); + friend void wrap_init(); // uses throw_func() +#endif +}; + + +/** @enum FileError::Code + * Values corresponding to <tt>errno</tt> codes returned from file operations + * on UNIX. + * Unlike <tt>errno</tt> codes, FileError::Code values are available on all + * systems, even Windows. The exact meaning of each code depends on what sort + * of file operation you were performing; the UNIX documentation gives more + * details. The following error code descriptions come from the GNU C Library + * manual, and are under the copyright of that manual. + * + * It's not very portable to make detailed assumptions about exactly which + * errors will be returned from a given operation. Some errors don't occur on + * some systems, etc., sometimes there are subtle differences in when a system + * will report a given error, etc. + */ + +/** @var FileError::Code FileError::EXISTS + * <tt>(EEXIST)</tt> Operation not permitted; only the owner of the file (or + * other resource) or processes with special privileges can perform the operation. + * <br><br> + */ +/** @var FileError::Code FileError::IS_DIRECTORY + * <tt>(EISDIR)</tt> File is a directory; you cannot open a directory for writing, + * or create or remove hard links to it. + * <br><br> + */ +/** @var FileError::Code FileError::ACCESS_DENIED + * <tt>(EACCES)</tt> Permission denied; the file permissions do not allow the + * attempted operation. + * <br><br> + */ +/** @var FileError::Code FileError::NAME_TOO_LONG + * <tt>(ENAMETOOLONG)</tt> Filename too long. + * <br><br> + */ +/** @var FileError::Code FileError::NO_SUCH_ENTITY + * <tt>(ENOENT)</tt> No such file or directory. This is a "file doesn't exist" + * error for ordinary files that are referenced in contexts where they are expected + * to already exist. + * <br><br> + */ +/** @var FileError::Code FileError::NOT_DIRECTORY + * <tt>(ENOTDIR)</tt> A file that isn't a directory was specified when a directory + * is required. + * <br><br> + */ +/** @var FileError::Code FileError::NO_SUCH_DEVICE + * <tt>(ENXIO)</tt> No such device or address. The system tried to use the device + * represented by a file you specified, and it couldn't find the device. This can + * mean that the device file was installed incorrectly, or that the physical device + * is missing or not correctly attached to the computer. + * <br><br> + */ +/** @var FileError::Code FileError::NOT_DEVICE + * <tt>(ENODEV)</tt> This file is of a type that doesn't support mapping. + * <br><br> + */ +/** @var FileError::Code FileError::READONLY_FILESYSTEM + * <tt>(EROFS)</tt> The directory containing the new link can't be modified + * because it's on a read-only file system. + * <br><br> + */ +/** @var FileError::Code FileError::TEXT_FILE_BUSY + * <tt>(ETXTBSY)</tt> Text file busy. + * <br><br> + */ +/** @var FileError::Code FileError::FAULTY_ADDRESS + * <tt>(EFAULT)</tt> You passed in a pointer to bad memory. (Glib won't + * reliably return this, don't pass in pointers to bad memory.) + * <br><br> + */ +/** @var FileError::Code FileError::SYMLINK_LOOP + * <tt>(ELOOP)</tt> Too many levels of symbolic links were encountered in + * looking up a file name. This often indicates a cycle of symbolic links. + * <br><br> + */ +/** @var FileError::Code FileError::NO_SPACE_LEFT + * <tt>(ENOSPC)</tt> No space left on device; write operation on a file failed + * because the disk is full. + * <br><br> + */ +/** @var FileError::Code FileError::NOT_ENOUGH_MEMORY + * <tt>(ENOMEM)</tt> No memory available. The system cannot allocate more + * virtual memory because its capacity is full. + * <br><br> + */ +/** @var FileError::Code FileError::TOO_MANY_OPEN_FILES + * <tt>(EMFILE)</tt> The current process has too many files open and can't + * open any more. Duplicate descriptors do count toward this limit. + * <br><br> + */ +/** @var FileError::Code FileError::FILE_TABLE_OVERFLOW + * <tt>(ENFILE)</tt> There are too many distinct file openings in the + * entire system. + * <br><br> + */ +/** @var FileError::Code FileError::BAD_FILE_DESCRIPTOR + * <tt>(EBADF)</tt> Bad file descriptor; for example, I/O on a descriptor + * that has been closed or reading from a descriptor open only for writing + * (or vice versa). + * <br><br> + */ +/** @var FileError::Code FileError::INVALID_ARGUMENT + * <tt>(EINVAL)</tt> Invalid argument. This is used to indicate various kinds + * of problems with passing the wrong argument to a library function. + * <br><br> + */ +/** @var FileError::Code FileError::BROKEN_PIPE + * <tt>(EPIPE)</tt> Broken pipe; there is no process reading from the other + * end of a pipe. Every library function that returns this error code also + * generates a <tt>SIGPIPE</tt> signal; this signal terminates the program + * if not handled or blocked. Thus, your program will never actually see + * this code unless it has handled or blocked <tt>SIGPIPE</tt>. + * <br><br> + */ +/** @var FileError::Code FileError::TRYAGAIN + * <tt>(EAGAIN)</tt> Resource temporarily unavailable; the call might work + * if you try again later. + * We used TRYAGAIN instead of TRY_AGAIN, because that is a defined as a macro by a Unix header. + * <br><br> + */ +/** @var FileError::Code FileError::INTERRUPTED + * <tt>(EINTR)</tt> Interrupted function call; an asynchronous signal occurred + * and prevented completion of the call. When this happens, you should try + * the call again. + * <br><br> + */ +/** @var FileError::Code FileError::IO_ERROR + * <tt>(EIO)</tt> Input/output error; usually used for physical read or write + * errors. I.e. the disk or other physical device hardware is returning errors. + * <br><br> + */ +/** @var FileError::Code FileError::NOT_OWNER + * <tt>(EPERM)</tt> Operation not permitted; only the owner of the file (or other + * resource) or processes with special privileges can perform the operation. + * <br><br> + */ +/** @var FileError::Code FileError::FAILED + * Does not correspond to a UNIX error code; this is the standard "failed for + * unspecified reason" error code present in all Glib::Error error code + * enumerations. Returned if no specific code applies. + */ + +class Dir; + +/** The iterator type of Glib::Dir. + * @ingroup FileUtils + */ +class DirIterator +{ +public: + typedef std::input_iterator_tag iterator_category; + typedef std::string value_type; + typedef int difference_type; + typedef value_type reference; + typedef void pointer; + + DirIterator(); + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + DirIterator(GDir* gobject, const char* current); +#endif + + std::string operator*() const; + DirIterator& operator++(); + + /** @note DirIterator has input iterator semantics, which means real + * postfix increment is impossible. The return type is @c void to + * prevent surprising behaviour. + */ + void operator++(int); + + bool operator==(const DirIterator& rhs) const; + bool operator!=(const DirIterator& rhs) const; + +private: + GDir* gobject_; + const char* current_; +}; + + +/** Utility class representing an open directory. + * @ingroup FileUtils + * It's highly recommended to use the iterator interface. With iterators, + * reading an entire directory into a STL container is really easy: + * @code + * Glib::Dir dir (directory_path); + * std::list<std::string> entries (dir.begin(), dir.end()); + * @endcode + * @note The encoding of the directory entries isn't necessarily UTF-8. + * Use Glib::filename_to_utf8() if you need to display them. + */ +class Dir +{ +public: + typedef DirIterator iterator; + typedef DirIterator const_iterator; + + /** Opens a directory for reading. The names of the files in the + * directory can then be retrieved using read_name(). + * @param path The path to the directory you are interested in. + * @throw Glib::FileError + */ + explicit Dir(const std::string& path); + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + explicit Dir(GDir* gobject); +#endif + + /** Closes the directory and deallocates all related resources. + */ + ~Dir(); + + /** Retrieves the name of the next entry in the directory. + * The <tt>'.'</tt> and <tt>'..'</tt> entries are omitted. + * @return The entry's name or <tt>""</tt> if there are no more entries. + * @see begin(), end() + */ + std::string read_name(); + + /** Resets the directory. The next call to + * read_name() will return the first entry again. + */ + void rewind(); + + /** Closes the directory and deallocates all related resources. + * Note that close() is implicitely called by ~Dir(). Thus you don't + * need to call close() yourself unless you want to close the directory + * before the destructor runs. + */ + void close(); + + /** Get the begin of an input iterator sequence. + * @return An input iterator pointing to the first directory entry. + */ + DirIterator begin(); + + /** Get the end of an input iterator sequence. + * @return An input iterator pointing behind the last directory entry. + */ + DirIterator end(); + +private: + GDir* gobject_; + + // noncopyable + Dir(const Dir&); + Dir& operator=(const Dir&); +}; + + +/** Returns @c true if any of the tests in the bitfield @a test are true. + * @ingroup FileUtils + * For example, <tt>(Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_DIR)</tt> will + * return @c true if the file exists; the check whether it's a directory + * doesn't matter since the existence test is true. With the current set of + * available tests, there's no point passing in more than one test at a time. + * + * Apart from <tt>Glib::FILE_TEST_IS_SYMLINK</tt> all tests follow symbolic + * links, so for a symbolic link to a regular file file_test() will return + * @c true for both <tt>Glib::FILE_TEST_IS_SYMLINK</tt> and + * <tt>Glib::FILE_TEST_IS_REGULAR</tt>. + * + * @note For a dangling symbolic link file_test() will return @c true for + * <tt>Glib::FILE_TEST_IS_SYMLINK</tt> and @c false for all other flags. + * + * @param filename A filename to test. + * @param test Bitfield of Glib::FileTest flags. + * @return Whether a test was true. + */ +bool file_test(const std::string& filename, FileTest test); + +/** Opens a temporary file. + * @ingroup FileUtils + * See the %mkstemp() documentation on most UNIX-like systems. This is a + * portability wrapper, which simply calls %mkstemp() on systems that have + * it, and implements it in GLib otherwise. + * @param filename_template A string that should match the rules for + * %mkstemp(), i.e. end in <tt>"XXXXXX"</tt>. The <tt>X</tt> string + * will be modified to form the name of a file that didn't exist. + * @return A file handle (as from open()) to the file opened for reading + * and writing. The file is opened in binary mode on platforms where there + * is a difference. The file handle should be closed with close(). In + * case of errors, <tt>-1</tt> is returned. + */ +int mkstemp(std::string& filename_template); + +/** Opens a file for writing in the preferred directory for temporary files + * (as returned by Glib::get_tmp_dir()). + * @ingroup FileUtils + * @a prefix should a basename template; it'll be suffixed by 6 characters + * in order to form a unique filename. No directory components are allowed. + * + * The actual name used is returned in @a name_used. + * + * @param prefix Template for file name, basename only. + * @retval name_used The actual name used. + * @return A file handle (as from <tt>open()</tt>) to the file opened for reading + * and writing. The file is opened in binary mode on platforms where there is a + * difference. The file handle should be closed with <tt>close()</tt>. + * @throw Glib::FileError + */ +int file_open_tmp(std::string& name_used, const std::string& prefix); + +/** Opens a file for writing in the preferred directory for temporary files + * (as returned by Glib::get_tmp_dir()). + * @ingroup FileUtils + * This function works like file_open_tmp(std::string&, const std::string&) + * but uses a default basename prefix. + * + * @retval name_used The actual name used. + * @return A file handle (as from <tt>open()</tt>) to the file opened for reading + * and writing. The file is opened in binary mode on platforms where there is a + * difference. The file handle should be closed with <tt>close()</tt>. + * @throw Glib::FileError + */ +int file_open_tmp(std::string& name_used); + +/** Reads an entire file into a string, with good error checking. + * @ingroup FileUtils + * @param filename A file to read contents from. + * @return The file contents. + * @throw Glib::FileError + */ +std::string file_get_contents(const std::string& filename); + +} // namespace Glib + + +#endif /* _GLIBMM_FILEUTILS_H */ + |