#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