⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesystem_traits.hpp

📁 用STL的方式封装了WindowsAPI、COM调用、ACE、ATL、MFC、WTL等多种组件
💻 HPP
📖 第 1 页 / 共 5 页
字号:
    {
        if( is_path_name_separator(path[0]) &&
            '\0' == path[1])
        {
            return true;
        }

        return false;
    }
public:
    static bool_type is_root_designator(char_type const *path)
    {
        WINSTL_ASSERT(NULL != path);

        return is_root_directory_(path) || is_root_drive_(path) || is_root_UNC_(path);
    }

    static bool_type is_path_name_separator(char_type ch)
    {
        return '\\' == ch || '/' == ch;
    }

    static char_type path_separator()
    {
        return ';';
    }

    static char_type path_name_separator()
    {
        return '\\';
    }

    static char_type const *pattern_all()
    {
        return "*.*";
    }

    static size_type path_max()
    {
        return 1 + _MAX_PATH;
    }

#if defined(STLSOFT_COMPILER_IS_MSVC) && \
    _MSC_VER < 1200
    static ws_dword_t get_full_path_name(char_type const *fileName, ws_dword_t cchBuffer, char_type *buffer, char_type **ppFile)
    {
        WINSTL_MESSAGE_ASSERT("GetFullPathNameW() will crash when the file-name and buffer parameters are the same, so it's not a good idea to do this for ANSI compilation", fileName != buffer);

        if('"' == *fileName)
        {
            // This can only work if ...
            const size_type         len     =   class_type::str_len(fileName);
            char_type const *const  closing =   class_type::str_chr(fileName + 1, '"');

            // ... 1. the only other double quote is at the end of the string, and ...
            if( NULL != closing &&
                closing - fileName == static_cast<ptrdiff_t>(len - 1))
            {
                ws_dword_t  res = class_type::get_full_path_name(fileName + 1, cchBuffer, buffer, ppFile);

                // ... 2. the front-quote skipped string can be converted, and ...
                if( 0 != res &&
                    res < cchBuffer)
                {
                    WINSTL_ASSERT('\0' == buffer[res]);

                    char_type *const    closing2    =   class_type::str_chr(buffer, '"');

                    // ... 3. the front-quote skipped converted string contains a single trailing quote
                    if( NULL != closing2 &&
                        closing2 - buffer == static_cast<ptrdiff_t>(res - 1))
                    {
                        buffer[res-- - 1] = '\0';

                        return res;
                    }
                }
            }
        }

        return ::GetFullPathNameA(fileName, cchBuffer, buffer, ppFile);
    }
#else /* ? compiler */
private:
    static size_type get_full_path_name_impl2(char_type const *fileName, size_type len, char_type *buffer, size_type cchBuffer, char_type **ppFile)
    {
        size_type   r   =   ::GetFullPathNameA(fileName, cchBuffer, buffer, ppFile);

        if( 0 != r &&
            NULL != buffer &&
            r > cchBuffer)
        {
            buffer_type_    buffer_(1 + r);

            if(0 == buffer_.size())
            {
                *ppFile = NULL;

                return 0;
            }
            else
            {
                char_type   *pFile2;
                size_type   r2  =   get_full_path_name_impl2(fileName, len, &buffer_[0], buffer_.size(), &pFile2);

                if(0 == r2)
                {
                    return 0;
                }
                else
                {
                    if(r2 > cchBuffer)
                    {
                        r2 = cchBuffer;
                    }

                    str_n_copy(&buffer[0], &buffer_[0], r2);
                    if( NULL != pFile2 &&
                        r2 == (r - 1) &&
                        static_cast<size_type>(pFile2 - &buffer_[0]) < r2)
                    {
                        *ppFile = &buffer[0] + (pFile2 - &buffer_[0]);
                    }
                    else
                    {
                        *ppFile = NULL;
                    }

                    return r2;
                }
            }
        }
        else
        {
            return r;
        }
    }

    static size_type get_full_path_name_impl(char_type const *fileName, size_type len, char_type *buffer, size_type cchBuffer, char_type **ppFile)
    {
        WINSTL_ASSERT(len > 0);

        if('\0' != fileName[len])
        {
            buffer_type_    fileName_(1 + (len - 1));

            // May be being compiled absent exception support, so need to check the
            // file path buffers. (This _could_ be done with a compile-time #ifdef,
            // but it's best not, since some translators support exceptions but yet
            // don't throw on mem exhaustion, and in any case a user could change
            // ::new)
            if(0 == fileName_.size())
            {
                set_last_error(ERROR_OUTOFMEMORY);

                return 0;
            }
            else
            {
                fileName_[len] = '\0';

                return get_full_path_name_impl( str_n_copy(&fileName_[0], fileName, len)
                                            ,   len
                                            ,   buffer
                                            ,   cchBuffer
                                            ,   ppFile);
            }
        }
        else
        {
            return get_full_path_name_impl2(fileName, len, buffer, cchBuffer, ppFile);
        }
    }

public:
    static size_type get_full_path_name(char_type const *fileName, size_type cchBuffer, char_type *buffer, char_type **ppFile)
    {
        WINSTL_MESSAGE_ASSERT("GetFullPathNameW() will crash when the file-name and buffer parameters are the same, so it's not a good idea to do this for ANSI compilation", fileName != buffer);

        size_type       n   =   0;
        const size_type len =   class_type::str_len(fileName);

        if(NULL != class_type::str_pbrk(fileName, "<>|*?"))
        {
            ::SetLastError(ERROR_INVALID_NAME);

            return 0;
        }

        if('"' == *fileName)
        {
            // This can only work if:
            //
            // - the only other double-quote is at the end of the string
            // - the unquoted form successfully converts
            char_type const *const  closing =   class_type::str_chr(fileName + 1, '"');

            if( NULL == closing ||
                static_cast<size_type>(closing - fileName) != len - 1)
            {
                set_last_error(ERROR_INVALID_DATA);
            }
            else
            {
                size_type   r;

                if(NULL == buffer)
                {
                    r = get_full_path_name_impl(fileName, len, NULL, 0, ppFile);

                    if(0 != r)
                    {
                        n = 2 + r;
                    }
                }
                else if(cchBuffer == 0)
                {
                    n = 0;
                    *ppFile = NULL;
                }
                else if(cchBuffer == 1)
                {
                    // Have to check it's valid
                    r = get_full_path_name_impl(fileName, len, NULL, 0, ppFile);

                    if(0 != r)
                    {
                        buffer[0] = '"';
                        n = 1;
                        *ppFile = NULL;
                    }
                }
                else
                {
                    r = get_full_path_name_impl(fileName + 1, len - 2, buffer + 1, cchBuffer - 1, ppFile);

                    if(0 != r)
                    {
                        // Write the first quote character into the buffer
                        buffer[0] = '"';

                        if(r + 1 < cchBuffer)
                        {
                            // There's enough space for the result and the closing quote
                            buffer[r + 1] = '"';

                            if(r + 2 < cchBuffer)
                            {
                                // There's enough space for the result and the closing quote and the nul-terminator
                                buffer[r + 2] = '\0';

                                n = r + 2;
                            }
                            else
                            {
                                n = r + 2;
                            }
                        }
                        else
                        {
                            n = r + 1;
                        }
                    }
                }
            }
        }
        else
        {
            n = get_full_path_name_impl(fileName, len, buffer, cchBuffer, ppFile);
        }

        // Paths that exceed _MAX_PATH cause GetFullPathNameA() to fail, but it
        // does not (appear to) call SetLastError()
        if( 0 == n &&
            0 == ::GetLastError() &&
            str_len(fileName) > _MAX_PATH)
        {
            ::SetLastError(ERROR_FILENAME_EXCED_RANGE);
        }

        return n;
    }
#endif /* compiler */

    static size_type get_full_path_name(char_type const *fileName, size_type cchBuffer, char_type *buffer)
    {
        WINSTL_ASSERT(NULL != fileName);

        char_type *pFile;

        if('\0' == *fileName)
        {
            static const char   s_dot[2] = { '.', '\0' };

            fileName = s_dot;
        }

        return get_full_path_name(fileName, cchBuffer, buffer, &pFile);
    }

    static size_type get_short_path_name(char_type const *fileName, size_type cchBuffer, char_type *buffer)
    {
        return ::GetShortPathNameA(fileName, buffer, cchBuffer);
    }
    static size_type get_short_path_name(char_type const *fileName, char_type *buffer, size_type cchBuffer)
    {
        return ::GetShortPathNameA(fileName, buffer, cchBuffer);
    }

    // File-system enumeration

    static HANDLE find_first_file(char_type const *spec, find_data_type *findData)
    {
        return ::FindFirstFileA(spec, findData);
    }

#if defined(_WIN32_WINNT) && \
    _WIN32_WINNT >= 0x0400
    static HANDLE find_first_file_ex(char_type const *spec, FINDEX_SEARCH_OPS flags, find_data_type *findData)
    {
        return ::FindFirstFileExA(spec, FindExInfoStandard, findData, flags, NULL, 0);
    }
#endif /* _WIN32_WINNT >= 0x0400 */

    static bool_type find_next_file(HANDLE h, find_data_type *findData)
    {
        return ::FindNextFileA(h, findData) != FALSE;
    }

    static void find_file_close(HANDLE h)
    {
        WINSTL_ASSERT(INVALID_HANDLE_VALUE != h);

        ::FindClose(h);
    }

#ifndef _WINSTL_NO_FINDVOLUME_API
    static HANDLE find_first_volume(char_type *volume_name, size_type cch_volume_name)
    {
        return ::FindFirstVolumeA(volume_name, cch_volume_name);
    }

    static bool_type find_next_volume(HANDLE h, char_type *volume_name, size_type cch_volume_name)
    {
        return ::FindNextVolumeA(h, volume_name, cch_volume_name) != FALSE;
    }

    static void find_volume_close(HANDLE h)
    {
        WINSTL_ASSERT(INVALID_HANDLE_VALUE != h);

        ::FindVolumeClose(h);
    }
#endif // !_WINSTL_NO_FINDVOLUME_API

    // Modules

    static size_type get_module_filename(HINSTANCE hModule, char_type *buffer, size_type cchBuffer)
    {
        return ::GetModuleFileNameA(hModule, buffer, cchBuffer);
    }

    static size_type get_system_directory(char_type *buffer, size_type cchBuffer)
    {
        return ::GetSystemDirectoryA(buffer, cchBuffer);
    }

    static size_type get_windows_directory(char_type *buffer, size_type cchBuffer)
    {
        return ::GetWindowsDirectoryA(buffer, cchBuffer);
    }

    // Dynamic Loading

    static module_type load_library(char_type const *name)
    {
        return ::LoadLibraryA(name);
    }

    static bool_type free_library(module_type hModule)
    {
        return filesystem_traits_::free_library(hModule);
    }

    static FARPROC find_symbol(module_type hModule, char const *symbolName)
    {
        return filesystem_traits_::find_symbol(hModule, symbolName);
    }

    // File-system state
    static bool_type set_current_directory(char_type const *dir)
    {
        return ::SetCurrentDirectoryA(dir) != FALSE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -