a313924b77
git-svn-id: svn://localhost/ardour2/trunk@2644 d708f5d6-7413-0410-9779-e7cbd77b26cf
483 lines
16 KiB
C++
483 lines
16 KiB
C++
// -*- c++ -*-
|
|
// Generated by gtkmmproc -- DO NOT MODIFY!
|
|
#ifndef _GLIBMM_FILEUTILS_H
|
|
#define _GLIBMM_FILEUTILS_H
|
|
|
|
|
|
/* $Id: fileutils.hg,v 1.3 2004/01/22 18:38:12 murrayc Exp $ */
|
|
|
|
/* 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:
|
|
|
|
#ifdef GLIBMM_EXCEPTIONS_ENABLED
|
|
static void throw_func(GError* gobject);
|
|
#else
|
|
//When not using exceptions, we just pass the Exception object around without throwing it:
|
|
static std::auto_ptr<Glib::Error> throw_func(GError* gobject);
|
|
#endif //GLIBMM_EXCEPTIONS_ENABLED
|
|
|
|
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 */
|
|
|