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

📄 basicstr.h

📁 winddk src目录下的WDM源码压缩!
💻 H
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************
*
*  (C) COPYRIGHT MICROSOFT CORPORATION, 1998
*
*  Copyright (c) 2003 Microsoft Corporation.  All Rights Reserved.
*
*  DESCRIPTION: Simple string classes
*
*******************************************************************************/
#ifndef _SIMSTR_H_INCLUDED
#define _SIMSTR_H_INCLUDED

/*
* Simple string class.
*
* Template class:
*   CBasicStringBase<CharType>
* Implementations:
*   CBasicStringBase<wchar_t> CBasicStringWide
*   CBasicStringBase<char> CBasicStringAnsi
*   CBasicString = CBasicString[Ansi|Wide] depending on UNICODE macro
* Inline functions:
*   CBasicStringAnsi CBasicStringConvert::AnsiString(CharType n)
*   CBasicStringWide CBasicStringConvert::WideString(CharType n)
* Macros:
*   IS_CHAR(CharType)
*   IS_WCHAR(CharType)
*/

#include <windows.h>
#include <stdarg.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>

//
// Disable the "conditional expression is constant" warning that is caused by
// the IS_CHAR and IS_WCHAR macros
//
#pragma warning( push )
#pragma warning( disable : 4127 )

#define IS_CHAR(x)     (sizeof(x) & sizeof(char))
#define IS_WCHAR(x)    (sizeof(x) & sizeof(wchar_t))

#ifndef ARRAYSIZE
    #define ARRAYSIZE(x)   (sizeof(x) / sizeof(x[0]))
#endif

template <class CharType>
class CBasicStringBase
{
private:
    enum
    {
        c_nDefaultGranularity      = 16,   // Default number of extra characters to allocate when we have to grow
        c_nInitialLoadStringBuffer = 1024, // Initial length of .RC string
        c_nMaxAutoDataLength       = 128   // Length of non-dynamically allocated string
    };

private:    
    //
    // If the string is less than c_nMaxAutoDataLength characters, it will be
    // stored here, instead of in a dynamically allocated buffer
    //
    CharType m_pstrAutoData[c_nMaxAutoDataLength];
    
    //
    // If we have to allocate data, it will be stored here
    //
    CharType *m_pstrData;

    //
    // Current maximum buffer size
    //
    size_t m_nMaxSize;

    //
    // Amount of extra space we allocate when we have to grow the buffer
    //
    size_t m_nGranularity;

    //
    // Error flag.  This is set if an allocation fails.
    //
    bool m_bError;

private:

    //
    // Min, in case it isn't already defined
    //
    template <class NumberType>
    static NumberType Min( const NumberType &a, const NumberType &b )
    {
        return (a < b) ? a : b;
    }

private:

    //
    // Replacements (in some cases just wrappers) for strlen, strcpy, ...
    //
    static inline CharType   *GenericCopyLength( CharType *pstrTarget, const CharType *pstrSource, size_t nSize );
    static inline size_t      GenericLength( const CharType *pstrStr );
    static inline CharType   *GenericConcatenate( CharType *pstrTarget, const CharType *pstrSource );
    static inline int         GenericCompare( const CharType *pstrTarget, const CharType *pstrSource );
    static inline int         GenericCompareNoCase( const CharType *pstrStrA, const CharType *pstrStrB );
    static inline int         GenericCompareLength( const CharType *pstrTarget, const CharType *pstrSource, size_t cchLength );
    static inline LPSTR       GenericCharNext( LPCSTR );
    static inline LPWSTR      GenericCharNext( LPCWSTR );

private:
    //
    // Internal only helpers
    //
    bool EnsureLength( size_t nMaxSize );
    void DeleteStorage();
    CharType *CreateStorage( size_t nCount, size_t &nAllocated );
    void Destroy();

public:
    //
    // Constructors and destructor
    //
    CBasicStringBase();
    CBasicStringBase( const CBasicStringBase & );
    CBasicStringBase( const CharType *szStr );
    CBasicStringBase( CharType ch );
    CBasicStringBase( UINT nResId, HMODULE hModule );
    virtual ~CBasicStringBase();

    //
    // String state
    //
    bool OK() const
    {
        return (!Error() && String());
    }
    bool IsValid() const
    {
        return (String() != NULL);
    }
    bool Error() const
    {
        return m_bError;
    }
    HRESULT Status() const
    {
        return OK() ? S_OK : E_OUTOFMEMORY;
    }
    void ClearError()
    {
        m_bError = false;
    }

private:
    void PropagateError( const CBasicStringBase &other )
    {
        if (!Error() && other.Error())
        {
            m_bError = true;
        }
    }
    
public:
#if defined(SIMSTR_UNIT_TEST)
    bool m_bForceError;
    void ForceError( bool bForceError ) { m_bForceError = bForceError; }
#endif

    //
    // Various helpers
    //
    size_t Length() const;
    void Concat( const CBasicStringBase &other );
    bool Assign( const CharType *szStr );
    bool Assign( const CBasicStringBase & );
    void SetAt( size_t nIndex, CharType chValue );
    CharType GetAt( size_t nIndex ) const;
    CharType &operator[](int index);
    const CharType &operator[](int index) const;

    //
    // Handy Win32 wrappers
    //
    CBasicStringBase &Format( const CharType *strFmt, ... );
    CBasicStringBase &Format( int nResId, HINSTANCE hInst, ... );
    bool LoadString( UINT nResId, HMODULE hModule );

    //
    // Operators
    //
    CBasicStringBase &operator=( const CBasicStringBase &other );
    CBasicStringBase &operator=( const CharType *other );
    CBasicStringBase &operator+=( const CBasicStringBase &other );


    //
    // Convert this string and return the converted string
    //
    CBasicStringBase ToUpper() const;
    CBasicStringBase ToLower() const;

    //
    // Convert in place
    //
    CBasicStringBase &MakeUpper();
    CBasicStringBase &MakeLower();

    //
    // Remove leading and trailing spaces
    //
    CBasicStringBase &TrimRight();
    CBasicStringBase &TrimLeft();
    CBasicStringBase &Trim();

    //
    // Searching
    //
    int Find( CharType cChar ) const;
    int Find( const CBasicStringBase &other, size_t nStart=0 ) const;
    int ReverseFind( CharType cChar ) const;
    int ReverseFind( const CBasicStringBase &other ) const;

    //
    // Substring copies
    //
    CBasicStringBase SubStr( size_t nStart, size_t nCount ) const;
    CBasicStringBase SubStr( size_t nStart ) const;

    CBasicStringBase Left( size_t nCount ) const
    { 
        return SubStr( 0, (int)nCount );
    }
    CBasicStringBase Right( size_t nCount ) const
    {
        return SubStr( Length()-nCount );
    }

    //
    // Comparison functions
    //
    int CompareNoCase( const CBasicStringBase &other, int cchLength=-1 ) const;
    int Compare( const CBasicStringBase &other, int cchLength=-1 ) const;

    //
    // Direct manipulation
    //
    CharType *GetBuffer( size_t cchLength )
    {
        //
        // If we are able to allocate a string of the
        // requested length, return a pointer to the actual data.
        //
        return EnsureLength(cchLength+1) ? m_pstrData : NULL;
    }

    //
    // Useful inlines
    //
    const CharType *String() const
    { 
        return m_pstrData;
    }
    size_t MaxSize() const
    {
        return m_nMaxSize;
    }
    size_t Granularity( size_t nGranularity )
    { 
        if (nGranularity>0)
        {
            m_nGranularity = nGranularity;
        }
        return m_nGranularity;
    }
    size_t Granularity() const
    {
        return m_nGranularity;
    }

    //
    // Implicit cast operator
    //
    operator const CharType *() const
    { 
        return String();
    }

    friend class CBasicStringBase;
};

template <>
inline LPSTR CBasicStringBase<CHAR>::GenericCharNext( LPCSTR pszStr )
{
    if (!pszStr)
    {
        return NULL;
    }
    return CharNextA(pszStr);
}

template <>
inline LPWSTR CBasicStringBase<WCHAR>::GenericCharNext( LPCWSTR pszStr )
{
    if (!pszStr)
    {
        return NULL;
    }
    return CharNextW(pszStr);
}

template <class CharType>
inline CharType *CBasicStringBase<CharType>::GenericCopyLength( CharType *pszTarget, const CharType *pszSource, size_t nCount )
{
    if (!pszTarget || !pszSource)
    {
        return NULL;
    }
    
    size_t nCopyLen = min( nCount, GenericLength(pszSource) + 1 );
    if (0 == nCopyLen)
    {
        return pszTarget;
    }

    CopyMemory( pszTarget, pszSource, nCopyLen * sizeof(CharType) );
    pszTarget[nCopyLen-1] = 0;
    return pszTarget;
}

template <>
inline size_t CBasicStringBase<CHAR>::GenericLength( LPCSTR pszString )
{
    if (!pszString)
    {
        return 0;
    }
    
    size_t nSize = 0;
    if (S_OK != StringCchLengthA( pszString, STRSAFE_MAX_CCH, &nSize ))
    {
        return 0;
    }
    
    return nSize;
}

template <>
inline size_t CBasicStringBase<WCHAR>::GenericLength( LPCWSTR pszString )
{
    if (!pszString)
    {
        return 0;
    }
    
    size_t nSize = 0;
    if (S_OK != StringCchLengthW( pszString, STRSAFE_MAX_CCH, &nSize ))
    {
        return 0;
    }
    
    return nSize;
}

template <class CharType>
inline CharType*CBasicStringBase<CharType>::GenericConcatenate( CharType *pszTarget, const CharType *pszSource )
{
    if (!pszTarget || !pszSource)
    {
        return NULL;
    }

    CharType *pszCurr = pszTarget;

    while (*pszCurr)
    {
        pszCurr++;
    }

    CopyMemory( pszCurr, pszSource, sizeof(CharType) * (GenericLength(pszSource) + 1) );

    return pszTarget;
}


template <class CharType>
inline int CBasicStringBase<CharType>::GenericCompare( const CharType *pszSource, const CharType *pszTarget )
{
#if defined(DBG) && !defined(UNICODE) && !defined(_UNICODE)
    if (sizeof(CharType) == sizeof(wchar_t))
    {
        OutputDebugString(TEXT("CompareStringW is not supported under win9x, so this call is going to fail!"));
    }
#endif
    int nRes = IS_CHAR(*pszSource) ?
               CompareStringA( LOCALE_USER_DEFAULT, 0, (LPCSTR)pszSource, -1, (LPCSTR)pszTarget, -1 ) :
               CompareStringW( LOCALE_USER_DEFAULT, 0, (LPCWSTR)pszSource, -1, (LPCWSTR)pszTarget, -1 );
    switch (nRes)
    {
    case CSTR_LESS_THAN:
        return -1;
    case CSTR_GREATER_THAN:
        return 1;
    default:
        return 0;
    }
}



template <class CharType>
inline int CBasicStringBase<CharType>::GenericCompareNoCase( const CharType *pszSource, const CharType *pszTarget )
{
#if defined(DBG) && !defined(UNICODE) && !defined(_UNICODE)
    if (sizeof(CharType) == sizeof(wchar_t))
    {
        OutputDebugString(TEXT("CompareStringW is not supported under win9x, so this call is going to fail!"));
    }
#endif
    int nRes = IS_CHAR(*pszSource) ?
               CompareStringA( LOCALE_USER_DEFAULT, NORM_IGNORECASE, (LPCSTR)pszSource, -1, (LPCSTR)pszTarget, -1 ) :
               CompareStringW( LOCALE_USER_DEFAULT, NORM_IGNORECASE, (LPCWSTR)pszSource, -1, (LPCWSTR)pszTarget, -1 );
    switch (nRes)
    {
    case CSTR_LESS_THAN:
        return -1;
    case CSTR_GREATER_THAN:
        return 1;
    default:
        return 0;
    }
}

template <class CharType>
inline int CBasicStringBase<CharType>::GenericCompareLength( const CharType *pszStringA, const CharType *pszStringB, size_t cchLength )
{
#if defined(DBG) && !defined(UNICODE) && !defined(_UNICODE)
    if (sizeof(CharType) == sizeof(wchar_t))
    {
        OutputDebugString(TEXT("CompareStringW is not supported under win9x, so this call is going to fail!"));
    }
#endif
    if (!cchLength)
        return(0);
    int nRes = IS_CHAR(*pszStringA) ?
               CompareStringA( LOCALE_USER_DEFAULT, 0, (LPCSTR)pszStringA, (int)Min(cchLength,CBasicStringBase<CHAR>::GenericLength((LPCSTR)pszStringA)), (LPCSTR)pszStringB, (int)Min(cchLength,CBasicStringBase<CHAR>::GenericLength((LPCSTR)pszStringB)) ) :
               CompareStringW( LOCALE_USER_DEFAULT, 0, (LPWSTR)pszStringA, (int)Min(cchLength,CBasicStringBase<WCHAR>::GenericLength((LPCWSTR)pszStringA)), (LPCWSTR)pszStringB, (int)Min(cchLength,CBasicStringBase<WCHAR>::GenericLength((LPCWSTR)pszStringB)) );
    switch (nRes)
    {
    case CSTR_LESS_THAN:
        return -1;
    case CSTR_GREATER_THAN:
        return 1;
    default:
        return 0;
    }
}

⌨️ 快捷键说明

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