342 lines
8.5 KiB
C
342 lines
8.5 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__
|