windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/smtp/server/cbuffer.h
2020-09-26 16:20:57 +08:00

342 lines
8.1 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: cbuffer.h
//
// Contents: CHAR buffer definitions
//
// History: 02-16-93 SethuR -- Implemented
// 07-28-94 AlokS -- Added more methods
// 12-09-97 MilanS -- Ported to Exchange
// 01-18-99 MikeSwa -- Fixed Cat()
// Notes:
//
//--------------------------------------------------------------------------
#ifndef __CBUFFER_H__
#define __CBUFFER_H__
//+---------------------------------------------------------------------
//
// Class: CCHARBuffer
//
// Purpose: A CHAR buffer
//
// History:
//
// Notes: Very often we encounter the case in string manipulation wherein
// the length of the string is less than some value most of the time
// (99%). However, in order to reliably with the very rare case we
// are forced to either allocate the string on the heap or alternatively
// go through some bizarre code that avoids the heap allocation in the
// common case. This class is an abstraction of a WCHAR buffer and its
// implementation is an attempt at hiding the detail from all clients.
//
// As it is designed it is an ideal candidate for a temporary buffer
// for string manipulation.
//
//----------------------------------------------------------------------
#define MAX_CHAR_BUFFER_SIZE 260 // long enough to cover all path names
class CCHARBuffer
{
public:
inline CCHARBuffer(ULONG cwBuffer = 0);
inline ~CCHARBuffer();
inline DWORD Size();
inline PCHAR ReAlloc(DWORD cwBuffer = MAX_CHAR_BUFFER_SIZE);
inline void Set(PWCHAR pwszFrom);
inline void Set(PCHAR pszFrom);
inline BOOL Cat(PCHAR pszPlus);
inline operator PCHAR ();
inline operator PCHAR () const;
inline void operator =(PWCHAR pwszFrom)
{
Set(pwszFrom);
};
inline void operator =(PCHAR pszFrom)
{
Set(pszFrom);
};
private:
DWORD _cBuffer;
PCHAR pchBuffer; // buffer ptr;
CHAR _achBuffer[MAX_CHAR_BUFFER_SIZE];
};
//+---------------------------------------------------------------------------
//
// Member: CCHARBuffer::CCHARBuffer, inline public
//
// Synopsis: Constructor
//
// Arguments: [cBuffer] -- desired buffer length.
//
// History: 02-17-93 SethuR Created
//
// Notes:
//
//----------------------------------------------------------------------------
inline CCHARBuffer::CCHARBuffer(ULONG cBuffer) :
pchBuffer(NULL),
_cBuffer(cBuffer)
{
if (_cBuffer > MAX_CHAR_BUFFER_SIZE)
{
pchBuffer = new CHAR[_cBuffer];
}
else if (_cBuffer > 0)
{
pchBuffer = _achBuffer;
}
}
//+---------------------------------------------------------------------------
//
// Member: CCHARBuffer::~CCHARBuffer, inline public
//
// Synopsis: Destructor
//
// History: 02-17-93 SethuR Created
//
// Notes:
//
//----------------------------------------------------------------------------
inline CCHARBuffer::~CCHARBuffer()
{
if (_cBuffer > MAX_CHAR_BUFFER_SIZE)
{
delete pchBuffer;
}
}
//+---------------------------------------------------------------------------
//
// Member: CCHARBuffer::Size, inline public
//
// Synopsis: Retrieve the size of the buffer
//
// Returns: the size of the buffer as a DWORD
//
// History: 02-17-93 SethuR Created
//
// Notes:
//
//----------------------------------------------------------------------------
inline DWORD CCHARBuffer::Size()
{
return _cBuffer;
}
//+---------------------------------------------------------------------------
//
// Member: CCHARBuffer::ReAlloc, inline public
//
// Synopsis: Reallocates the buffer to accomdate the newly specified size
//
// Arguments: [cBuffer] -- the desired buffer size
//
// Returns: the ptr to the buffer (PCHAR)
//
// History: 02-17-93 SethuR Created
//
// Notes:
//
//----------------------------------------------------------------------------
inline PCHAR CCHARBuffer::ReAlloc(DWORD cBuffer)
{
if (_cBuffer > MAX_CHAR_BUFFER_SIZE)
{
delete pchBuffer;
}
if ((_cBuffer = cBuffer) > MAX_CHAR_BUFFER_SIZE)
{
pchBuffer = new CHAR[_cBuffer];
}
else if (_cBuffer > 0)
{
pchBuffer = _achBuffer;
}
else if (_cBuffer == 0)
{
pchBuffer = NULL;
}
return pchBuffer;
}
//+---------------------------------------------------------------------------
//
// Member: CCHARBuffer::operator PCHAR (), inline public
//
// Synopsis: casting operator to accomdate syntactic sugaring
//
// Returns: the ptr to the buffer (PCHAR)
//
// History: 02-17-93 SethuR Created
//
// Notes:
//
//----------------------------------------------------------------------------
inline CCHARBuffer::operator PCHAR ()
{
return (PCHAR)pchBuffer;
}
inline CCHARBuffer::operator PCHAR () const
{
return (PCHAR)pchBuffer;
}
//+---------------------------------------------------------------------------
//
// Member: CCHARBuffer::Set, inline public
//
// Synopsis: Copies the string to internal buffer. Reallocates
// in internal buffer, if necessary
//
// Arguments: [pwszFrom] -- Pointer to the string
//
// Returns: -none-
//
// History: 07-28-94 AlokS Created
//
// Notes:
//
//----------------------------------------------------------------------------
inline VOID CCHARBuffer::Set(PWCHAR pwszFrom)
{
if (pwszFrom==NULL)
{
if (_cBuffer > MAX_CHAR_BUFFER_SIZE)
{
delete pchBuffer;
}
_cBuffer=0;
pchBuffer = NULL;
}
else if (*pwszFrom)
{
DWORD len = wcslen(pwszFrom)+1;
if (len > _cBuffer)
{
(void)ReAlloc (len);
}
// Now copy
wcstombs(pchBuffer, pwszFrom, len);
}
else
{
*pchBuffer='\0';
}
return;
}
//+---------------------------------------------------------------------------
//
// Member: CCHARBuffer::Set, inline public
//
// Synopsis: Copies the string to internal buffer. Reallocates
// in internal buffer, if necessary
//
// Arguments: [pszFrom] -- Pointer to the string
//
// Returns: -none-
//
// History: 07-28-94 AlokS Created
//
// Notes:
//
//----------------------------------------------------------------------------
inline VOID CCHARBuffer::Set(PCHAR pszFrom)
{
if (pszFrom==NULL)
{
if (_cBuffer > MAX_CHAR_BUFFER_SIZE)
{
delete pchBuffer;
}
_cBuffer=0;
pchBuffer = NULL;
}
else if (*pszFrom)
{
DWORD len = strlen(pszFrom)+1;
if ( len > _cBuffer)
{
(void)ReAlloc (len);
}
// Now copy
memcpy(pchBuffer, pszFrom, len);
}
else
{
*pchBuffer=L'\0';
}
return;
}
//+---------------------------------------------------------------------------
//
// Member: CCHARBuffer::Cat, inline public
//
// Synopsis: Concatnates the string to internal buffer. Reallocates
// in internal buffer, if necessary
//
// Arguments: [pszPlus] -- Pointer to the string
//
// Returns: TRUE on success
// FALSE if memory allocation failed
//
// History: 07-28-94 AlokS Created
// 01-18-99 Mikeswa Fixed AV in checkin allocated ptr
//
// Notes:
//
//----------------------------------------------------------------------------
inline BOOL CCHARBuffer::Cat(PCHAR pszFrom)
{
DWORD len1 = strlen(pchBuffer),
len2 = strlen(pszFrom),
len3 = len1+len2 + 1;
if ( len3 > MAX_CHAR_BUFFER_SIZE)
{
PCHAR ptr = new CHAR [len3];
//Avoid AV'ing
if (!ptr)
return FALSE;
memcpy(ptr, pchBuffer, len1);
if (_cBuffer > MAX_CHAR_BUFFER_SIZE)
{
delete pchBuffer;
}
pchBuffer = ptr;
}
memcpy( ((LPWSTR)(pchBuffer)+len1), pszFrom, (len2+1) * sizeof(CHAR));
_cBuffer = len3;
return TRUE;
}
#endif // __CBUFFER_H__