📄 filesystem_traits.hpp
字号:
/* /////////////////////////////////////////////////////////////////////////
* File: unixstl/filesystem/filesystem_traits.hpp
*
* Purpose: Contains the filesystem_traits template class, and ANSI and
* Unicode specialisations thereof.
*
* Created: 15th November 2002
* Updated: 12th March 2007
*
* Home: http://stlsoft.org/
*
* Copyright (c) 2002-2007, Matthew Wilson and Synesis Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - 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.
* - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
* any contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 unixstl/filesystem/filesystem_traits.hpp
*
* \brief [C++ only] Definition of the unixstl::filesystem_traits traits
* class
* (\ref group__library__filesystem "File System" Library).
*/
#ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
#define UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MAJOR 4
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MINOR 3
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_REVISION 2
# define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_EDIT 99
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
* Includes
*/
#ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
# include <unixstl/unixstl.h>
#endif /* !UNIXSTL_INCL_UNIXSTL_H_UNIXSTL */
#ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
# include <stlsoft/memory/auto_buffer.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
#ifndef UNIXSTL_INCL_UNIXSTL_SYSTEM_HPP_SYSTEM_TRAITS
# include <unixstl/system/system_traits.hpp>
#endif /* !UNIXSTL_INCL_UNIXSTL_SYSTEM_HPP_SYSTEM_TRAITS */
#ifdef _WIN32
# include <ctype.h>
#endif /* _WIN32 */
#include <errno.h>
#include <fcntl.h>
#ifdef _WIN32
# include <io.h>
# if defined(STLSOFT_COMPILER_IS_INTEL) || \
defined(STLSOFT_COMPILER_IS_MSVC)
# include <direct.h>
# endif /* os && compiler */
#endif /* _WIN32 */
#include <dlfcn.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wchar.h>
#include <sys/types.h>
#include <sys/stat.h>
/* /////////////////////////////////////////////////////////////////////////
* Namespace
*/
#ifndef _UNIXSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
/* There is no stlsoft namespace, so must define ::unixstl */
namespace unixstl
{
# else
/* Define stlsoft::unixstl_project */
namespace stlsoft
{
namespace unixstl_project
{
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_UNIXSTL_NO_NAMESPACE */
/* /////////////////////////////////////////////////////////////////////////
* Classes
*/
#ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
/** \brief Traits class for file-system operations
*
* \ingroup group__library__filesystem
*
* filesystem_traits is a traits class for determining the correct file-system
* structures and functions for a given character type.
*
* \param C The character type (e.g. \c char, \c wchar_t)
*/
template <ss_typename_param_k C>
struct filesystem_traits
: public system_traits<C>
{
/// \name Types
/// @{
private:
typedef system_traits<C> parent_class_type;
public:
/// \brief The character type
typedef C char_type;
/// \brief The size type
typedef us_size_t size_type;
/// \brief The difference type
typedef us_ptrdiff_t difference_type;
/// \brief The stat data type
typedef struct stat stat_data_type;
/// \brief The fstat data type
typedef struct stat fstat_data_type;
/// \brief The current instantion of the type
typedef filesystem_traits<C> class_type;
/// \brief The (signed) integer type
typedef us_int_t int_type;
/// \brief The Boolean type
typedef us_bool_t bool_type;
/// \brief The type of a system file handle
typedef int file_handle_type;
/// \brief The type of a handle to a dynamically loaded module
typedef void *module_type;
/// \brief The type of system error codes
typedef int error_type;
/// \brief The mode type
#ifdef _WIN32
typedef unsigned short mode_type;
#else /* ? _WIN32 */
typedef mode_t mode_type;
#endif /* _WIN32 */
/// @}
#ifdef PATH_MAX
/// \name Member Constants
/// @{
public:
enum
{
maxPathLength = 1 + PATH_MAX //!< The maximum length of a path for the current file system
};
/// @}
#endif /* PATH_MAX */
/// \name File-system entry names
/// @{
public:
/// \brief Appends a path name separator to \c dir if one does not exist
///
/// \see \link #path_name_separator path_name_separator() \endlink
static char_type *ensure_dir_end(char_type *dir);
/// \brief Removes the path name separator from the end of \c dir, if it has it
///
/// \see \link #path_name_separator path_name_separator() \endlink
static char_type *remove_dir_end(char_type *dir);
/// \brief Returns \c true if \c dir has trailing path name separator
///
/// \see \link #path_name_separator path_name_separator() \endlink
static bool_type has_dir_end(char_type const* dir);
/// \brief Returns \c true if dir is \c "." or \c ".."
static bool_type is_dots(char_type const* dir);
/// \brief Returns \c true if path is rooted
///
/// \note Only enough characters of the path pointed to by \c path as are
/// necessary to detect the presence or absence of the operating system's
/// root character sequence(s).
static bool_type is_path_rooted(char_type const* path);
/// \brief Returns \c true if path is an absolute path
///
/// \note Only enough characters of the path pointed to by \c path as are
/// necessary to detect the presence or absence of the operating system's
/// absolute path character sequence(s).
static bool_type is_path_absolute(char_type const* path);
/// \brief Returns \c true if path is a UNC path
///
/// \note Only enough characters of the path pointed to by \c path as are
/// necessary to detect the presence or absence of the UNC character sequence(s).
static bool_type is_path_UNC(char_type const* path);
/// \brief Indicates whether the given path is the root designator.
///
/// The root designator is one of the following:
/// - the slash character <code>/</code>
///
/// The function returns false if the path contains any part of a
/// file name (or extension), directory, or share.
static bool_type is_root_designator(char_type const* path);
/// \brief Returns \c true if the character is a path-name separator
static bool_type is_path_name_separator(char_type ch);
/// \brief Returns the path separator
///
/// This is the separator that is used to separate multiple paths on the operating system. On UNIX it is ':'
static char_type path_separator();
/// \brief Returns the path name separator
///
/// This is the separator that is used to separate parts of a path on the operating system. On UNIX it is '/'
static char_type path_name_separator();
/// \brief Returns the wildcard pattern that represents all possible matches
///
/// \note On UNIX it is '*'
static char_type const* pattern_all();
/// \brief The maximum length of a path on the file-system
///
/// \note Because not all systems support fixed maximum path lengths, the value of this function is notionally dynamic
static size_type path_max();
/// \brief Gets the full path name into the given buffer, returning a pointer to the file-part
static size_type get_full_path_name(char_type const* fileName, size_type cchBuffer, char_type* buffer, char_type **ppFile);
/// \brief Gets the full path name into the given buffer
static size_type get_full_path_name(char_type const* fileName, char_type* buffer, size_type cchBuffer);
/// \brief Gets the full path name into the given buffer
///
/// \deprecated The other overload is now the preferred form
static size_type get_full_path_name(char_type const* fileName, size_type cchBuffer, char_type* buffer);
/// \brief Gets the short path name into the given buffer
static size_type get_short_path_name(char_type const* fileName, size_type cchBuffer, char_type* buffer);
/// @}
/// \name File-system enumeration
/// @{
public:
// opendir/readdir API
/// \brief Initiate a file-system search
static DIR *open_dir(char_type const* dir);
/// \brief Read an entry from the file-system search
static struct dirent const *read_dir(DIR *h);
/// \brief Closes the handle of the file-system search
static void close_dir(DIR *h);
/// @}
/// \name File-system control
/// @{
public:
/// \brief Sets the current directory to \c dir
static bool_type set_current_directory(char_type const* dir);
/// \brief Retrieves the name of the current directory into \c buffer up to a maximum of \c cchBuffer characters
///
/// \deprecated The other overload is now the preferred form
static size_type get_current_directory(size_type cchBuffer, char_type* buffer);
/// \brief Retrieves the name of the current directory into \c buffer up to a maximum of \c cchBuffer characters
static size_type get_current_directory(char_type *buffer, size_type cchBuffer);
/// @}
/// \name File-system state
/// @{
public:
/// \brief Returns whether a file exists or not
static bool_type file_exists(char_type const* path);
/// \brief Returns whether the given path represents a file
static bool_type is_file(char_type const* path);
/// \brief Returns whether the given path represents a directory
static bool_type is_directory(char_type const* path);
/// \brief Gets the information for a particular file system entry
static bool_type stat(char_type const* path, stat_data_type *stat_data);
/// \brief Gets the information for a particular file system entry
static bool_type lstat(char_type const* path, stat_data_type *stat_data);
/// \brief Gets the information for a particular open file
static bool_type fstat(file_handle_type fd, fstat_data_type *fstat_data);
/// \brief Returns whether the given stat info represents a file
static bool_type is_file(stat_data_type const* stat_data);
/// \brief Returns whether the given stat info represents a directory
static bool_type is_directory(stat_data_type const* stat_data);
/// \brief Returns whether the given stat info represents a link
static bool_type is_link(stat_data_type const* stat_data);
/// \brief Returns whether the given stat info represents a read-only entry
static bool_type is_readonly(stat_data_type const* stat_data);
/// @}
/// \name File-system control
/// @{
public:
/// \brief Creates a directory
static bool_type create_directory(char_type const* dir);
/// \brief Deletes a directory
static bool_type remove_directory(char_type const* dir);
/// \brief Delete a file
static bool_type unlink_file(char_type const* file);
/// \brief Delete a file
///
/// \deprecated Users should use unlink_file()
static bool_type delete_file(char_type const* file);
/// \brief Rename a file
static bool_type rename_file(char_type const* currentName, char_type const* newName);
/// \brief Copy a file
// static bool_type copy_file(char_type const* sourceName, char_type const* newName, bool_type bFailIfExists = false);
/// \brief Create / open a file
static file_handle_type open_file(char_type const* fileName, int oflag, int pmode);
/// \brief Closes the given operating system handle
static bool_type close_file(file_handle_type fd);
/// \brief Create / open a file
///
/// \deprecated Users should use open_file()
static file_handle_type open(char_type const* fileName, int oflag, int pmode);
/// \brief Closes the given operating system handle
///
/// \deprecated Users should use close_file()
static bool_type close(file_handle_type fd);
#ifdef STLSOFT_CF_64BIT_INT_SUPPORT
/// \brief Gets the size of the file
static us_uint64_t get_file_size(file_handle_type fd);
#endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
/// @}
};
#else /* ? STLSOFT_DOCUMENTATION_SKIP_SECTION */
template <ss_typename_param_k C>
struct filesystem_traits;
STLSOFT_TEMPLATE_SPECIALISATION
struct filesystem_traits<us_char_a_t>
: public system_traits<us_char_a_t>
{
public:
typedef us_char_a_t char_type;
typedef us_size_t size_type;
typedef us_ptrdiff_t difference_type;
typedef struct stat stat_data_type;
typedef struct stat fstat_data_type;
typedef filesystem_traits<us_char_a_t> class_type;
typedef us_int_t int_type;
typedef us_bool_t bool_type;
typedef int file_handle_type;
typedef void *module_type;
typedef int error_type;
#ifdef _WIN32
typedef unsigned short mode_type;
#else /* ? _WIN32 */
typedef mode_t mode_type;
#endif /* _WIN32 */
private:
typedef stlsoft_ns_qual(auto_buffer_old)<char_type> buffer_type_;
public:
#ifdef PATH_MAX
enum
{
maxPathLength = 1 + PATH_MAX //!< The maximum length of a path for the current file system
};
#endif /* PATH_MAX */
public:
static char_type *ensure_dir_end(char_type *dir)
{
UNIXSTL_ASSERT(NULL != dir);
char_type *end = str_end(dir);
if( dir < end &&
!is_path_name_separator(*(end - 1)))
{
*end = path_name_separator();
*(end + 1) = '\0';
}
return dir;
}
static char_type *remove_dir_end(char_type *dir)
{
UNIXSTL_ASSERT(NULL != dir);
#ifdef _WIN32
// Don't trim drive roots ...
if( isalpha(dir[0]) &&
':' == dir[1] &&
is_path_name_separator(dir[2]) &&
'\0' == dir[3])
{
return dir;
}
// ... or UNC roots
if( '\\' == dir[0] &&
'\\' == dir[1] &&
'\0' == dir[3])
{
return dir;
}
#endif /* _WIN32 */
char_type *end = str_end(dir);
if( dir < end &&
is_path_name_separator(*(end - 1)))
{
*(end - 1) = '\0';
}
return dir;
}
static bool_type has_dir_end(char_type const* dir)
{
UNIXSTL_ASSERT(NULL != dir);
size_type len = str_len(dir);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -