AtlIsapiBufferクラスの修正版 [ATL]

(2005.02.08)
#pragma once
 
namespace ATL {
 
/////////////////////////////////////////////////////////////////////////
// CFixedAtlIsapiBuffer
// オリジナルの CAtlIsapiBuffer は Win98 で
// 4MB を超えるバッファを扱うことができません。
 
template <DWORD dwSizeT=ATL_ISAPI_BUFFER_SIZE>
class CFixedAtlIsapiBuffer
{
protected:
    char m_szBuffer[dwSizeT];
    LPSTR m_pBuffer;
    DWORD m_dwLen;
    DWORD m_dwAlloc;
//    HANDLE m_hProcHeap;
 
public:
    CFixedAtlIsapiBuffer() throw()
    {
        if (dwSizeT > 0)
            m_szBuffer[0] = 0;
 
        m_pBuffer = m_szBuffer;
        m_dwLen = 0;
        m_dwAlloc = dwSizeT;
//        m_hProcHeap = GetProcessHeap();
    }
 
    CFixedAtlIsapiBuffer(LPCSTR sz)
    {
        m_pBuffer = m_szBuffer;
        m_dwLen = 0;
        m_dwAlloc = dwSizeT;
//        m_hProcHeap = GetProcessHeap();
 
        if (!Append(sz))
            AtlThrow(E_OUTOFMEMORY);
    }
 
    ~CFixedAtlIsapiBuffer() throw()
    {
        Free();
    }
 
    BOOL Alloc(DWORD dwSize) throw()
    {
        if (m_dwAlloc >= dwSize)
        {
            return TRUE;
        }
        if (m_pBuffer != m_szBuffer)
        {
//            HeapFree(m_hProcHeap, 0, m_pBuffer);
            CVirtualAllocator::Free(m_pBuffer);
            m_dwLen = 0;
            m_dwAlloc = 0;
        }
//        m_pBuffer = (LPSTR)HeapAlloc(m_hProcHeap, 0, dwSize);
        m_pBuffer = (LPSTR)CVirtualAllocator::Allocate(dwSize);
        if (m_pBuffer)
        {
            m_dwAlloc = dwSize;
            return TRUE;
        }
        return FALSE;
    }
 
    BOOL ReAlloc(DWORD dwNewSize) throw()
    {
        if (dwNewSize <= m_dwAlloc)
            return TRUE;
 
        if (m_pBuffer == m_szBuffer)
        {
            BOOL bRet = Alloc(dwNewSize);
            if (bRet)
                memcpy(m_pBuffer, m_szBuffer, m_dwLen);
            return bRet;
        }
 
//        LPSTR pvNew = (LPSTR )HeapReAlloc(m_hProcHeap, 0, m_pBuffer, dwNewSize);
        LPSTR pvNew = (LPSTR)CVirtualAllocator::Reallocate(m_pBuffer, dwNewSize);
        if (pvNew)
        {
            m_pBuffer = pvNew;
            m_dwAlloc = dwNewSize;
            return TRUE;
        }
        return FALSE;
    }
 
    void Free() throw()
    {
        if (m_pBuffer != m_szBuffer)
        {
//            HeapFree(m_hProcHeap,0 , m_pBuffer);
            CVirtualAllocator::Free(m_pBuffer);
            m_dwAlloc = dwSizeT;
            m_pBuffer = m_szBuffer;
        }
        Empty();
    }
 
    void Empty() throw()
    {
        if (m_pBuffer)
        {
            m_pBuffer[0]=0;
            m_dwLen  = 0;
        }
    }
 
    DWORD GetLength() throw()
    {
        return m_dwLen;
    }
 
    BOOL Append(LPCSTR sz, int nLen = -1) throw()
    {
        if (nLen == -1)
            nLen = (int) strlen(sz);
 
        if (m_dwLen + nLen + 1 > m_dwAlloc)
        {
            if (!ReAlloc(m_dwAlloc + (nLen+1 > ATL_ISAPI_BUFFER_SIZE ? nLen+1 : ATL_ISAPI_BUFFER_SIZE)))
                return FALSE;
        }
        memcpy(m_pBuffer + m_dwLen, sz, nLen);
        m_dwLen += nLen;
        m_pBuffer[m_dwLen]=0;
        return TRUE;
    }
 
    operator LPCSTR() throw()
    {
        return m_pBuffer;
    }
 
    CFixedAtlIsapiBuffer& operator+=(LPCSTR sz)
    {
        if (!Append(sz))
            AtlThrow(E_OUTOFMEMORY);
        return *this;
    }
}; // class CFixedAtlIsapiBuffer
 
} // namespace ATL
一覧に戻る
© 2003 WAC.com All Right Reserved.