📄 filesystem_traits.hpp
字号:
/* /////////////////////////////////////////////////////////////////////////
* File: winstl/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 winstl/filesystem/filesystem_traits.hpp
*
* \brief [C++ only] Definition of the winstl::filesystem_traits traits
* class
* (\ref group__library__filesystem "File System" Library).
*/
#ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
#define WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define WINSTL_VER_WINSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MAJOR 4
# define WINSTL_VER_WINSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MINOR 4
# define WINSTL_VER_WINSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_REVISION 2
# define WINSTL_VER_WINSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_EDIT 104
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
* Includes
*/
#ifndef WINSTL_INCL_WINSTL_H_WINSTL
# include <winstl/winstl.h>
#endif /* !WINSTL_INCL_WINSTL_H_WINSTL */
#ifndef STLSOFT_INCL_STLSOFT_HPP_MEMORY_AUTO_BUFFER
# include <stlsoft/memory/auto_buffer.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_HPP_MEMORY_AUTO_BUFFER */
#ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS
# include <winstl/system/system_traits.hpp>
#endif /* !WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS */
#include <string.h>
#include <wchar.h>
/* /////////////////////////////////////////////////////////////////////////
* FindVolume API declarations
*
* The FindVolume API is not visible in the Windows headers unless _WIN32_WINNT
* is defined as 0x0500 or greater. Where this definition is not present, the
* functions are declared here, unless _WINSTL_NO_FINDVOLUME_API is defined.
*
* Where _WINSTL_NO_FINDVOLUME_API is defined, the requisite members of the
* traits classes are undeclared.
*/
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
#if !defined(_WINSTL_NO_FINDVOLUME_API)
# if !defined(_WIN32_WINNT) || \
(_WIN32_WINNT < 0x0500) || \
!defined(FindFirstVolume) || \
!defined(FindNextVolume)
# define WINSTL_FINDVOLUME_API_NOT_DECLARED
HANDLE WINAPI FindFirstVolumeA(
LPSTR lpszVolumeName, // output buffer
DWORD cchBufferLength // size of output buffer
);
HANDLE WINAPI FindFirstVolumeW(
LPWSTR lpszVolumeName, // output buffer
DWORD cchBufferLength // size of output buffer
);
BOOL WINAPI FindNextVolumeA(
HANDLE hFindVolume, // volume search handle
LPSTR lpszVolumeName, // output buffer
DWORD cchBufferLength // size of output buffer
);
BOOL WINAPI FindNextVolumeW(
HANDLE hFindVolume, // volume search handle
LPWSTR lpszVolumeName, // output buffer
DWORD cchBufferLength // size of output buffer
);
BOOL WINAPI FindVolumeClose(
HANDLE hFindVolume
);
# endif
# endif /* !_WINSTL_NO_FINDVOLUME_API */
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
* Namespace
*/
#ifndef _WINSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
/* There is no stlsoft namespace, so must define ::winstl */
namespace winstl
{
# else
/* Define stlsoft::winstl_project */
namespace stlsoft
{
namespace winstl_project
{
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_WINSTL_NO_NAMESPACE */
/* /////////////////////////////////////////////////////////////////////////
* Classes
*/
#ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
/** \brief Traits for accessing the correct file-system functions for a given character type
*
* \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 ws_size_t size_type;
/// \brief The difference type
typedef ws_ptrdiff_t difference_type;
/// \brief The find data type
typedef WIN32_FIND_DATA find_data_type; // Placeholder only
/// \brief The stat data type
typedef WIN32_FIND_DATA stat_data_type;
/// \brief The fstat data type
typedef BY_HANDLE_FILE_INFORMATION fstat_data_type;
/// \brief The current instantion of the type
typedef filesystem_traits<C> class_type;
/// \brief The (signed) integer type
typedef ws_int_t int_type;
/// \brief The Boolean type
typedef ws_bool_t bool_type;
/// \brief The type of a system file handle
typedef HANDLE file_handle_type;
/// \brief The type of a handle to a dynamically loaded module
typedef HINSTANCE module_type;
/// \brief The type of system error codes
typedef DWORD error_type;
/// @}
/// \name Member Constants
/// @{
public:
enum
{
maxPathLength = 1 + _MAX_PATH //!< The maximum length of a path for the current file system
};
/// @}
/// \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, i.e. it begins with root directory
///
/// \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 backslash character <code>\\</code>
/// - a drive specification, e.g. <code>H:\\</code> or <code>H:/</code>
/// - a UNC host, e.g. <code>H:\\\\host</code> or <code>H:\\\\host\\</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
///
/// \note Both \c / and \c \\ are interpreted as 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 Win32 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
///
/// \deprecated The other overload is now the preferred form
static size_type get_short_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, char_type* buffer, size_type cchBuffer);
/// @}
/// \name File-system enumeration
/// @{
public:
// FindFirstFile/FindNextFile API
/// \brief Initiate a file-system search
static HANDLE find_first_file(char_type const* spec, find_data_type *findData);
#if _WIN32_WINNT >= 0x0400
/// \brief Initiate a file-system search - NT4+-only
static HANDLE find_first_file_ex(char_type const* spec, FINDEX_SEARCH_OPS flags, find_data_type *findData);
#endif /* _WIN32_WINNT >= 0x0400 */
/// \brief Advance a given file-system search
static bool_type find_next_file(HANDLE h, find_data_type *findData);
/// \brief Closes the handle of the file-system search
static void find_file_close(HANDLE h);
// FindFirstVolume/FindNextVolume API
#ifndef _WINSTL_NO_FINDVOLUME_API
/// \brief Initiate a file-system volume search
static HANDLE find_first_volume(char_type *volume_name, size_type cch_volume_name);
/// \brief Advance a given file-system volume search
static bool_type find_next_volume(HANDLE h, char_type *volume_name, size_type cch_volume_name);
/// \brief Closes the handle of the file-volume search
static void find_volume_close(HANDLE h);
#endif // !_WINSTL_NO_FINDVOLUME_API
/// @}
/// \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 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);
static bool_type is_file(fstat_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);
static bool_type is_directory(fstat_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);
static bool_type is_link(fstat_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);
static bool_type is_readonly(fstat_data_type const* stat_data);
/// \brief Indicates whether the given drive currently exists on the system
static bool_type drive_exists(char_type driveLetter);
/// \brief Returns a status code denoting the type of the drive
///
/// \return One of the return codes of the GetDriveType() API function
static DWORD get_drive_type(char_type driveLetter);
/// @}
/// \name File-system control
/// @{
public:
/// \brief Creates a directory
static bool_type create_directory(char_type const* dir);
/// \brief Creates a directory, with the given security attributes
static bool_type create_directory(char_type const* dir, LPSECURITY_ATTRIBUTES lpsa);
/// \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 create_file(char_type const* fileName, size_type desiredAccess, size_type shareMode, LPSECURITY_ATTRIBUTES sa, size_type creationDisposition, size_type flagAndAttributes, HANDLE hTemplateFile);
/// \brief Closes the given file handle
static bool_type close_file(file_handle_type h);
#ifdef STLSOFT_CF_64BIT_INT_SUPPORT
/// \brief Gets the size of the file
static ws_uint64_t get_file_size(file_handle_type h);
#endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
/// @}
};
#else /* ? STLSOFT_DOCUMENTATION_SKIP_SECTION */
template <ss_typename_param_k C>
struct filesystem_traits;
struct filesystem_traits_
: public system_traits_
{
public:
typedef ws_size_t size_type;
typedef ws_ptrdiff_t difference_type;
typedef filesystem_traits_ class_type;
typedef BY_HANDLE_FILE_INFORMATION fstat_data_type;
typedef ws_int_t int_type;
typedef ws_bool_t bool_type;
typedef HANDLE file_handle_type;
typedef HINSTANCE module_type;
typedef DWORD error_type;
enum
{
maxPathLength = 1 + _MAX_PATH //!< The maximum length of a path for the current file system
};
public:
static bool_type fstat(file_handle_type fd, fstat_data_type *fstat_data)
{
return FALSE != ::GetFileInformationByHandle(fd, fstat_data);
}
static bool_type is_file(fstat_data_type const* stat_data)
{
return FILE_ATTRIBUTE_DIRECTORY != (stat_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}
static bool_type is_directory(fstat_data_type const* stat_data)
{
return FILE_ATTRIBUTE_DIRECTORY == (stat_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}
static bool_type is_link(fstat_data_type const* /* stat_data */)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -