windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/iisrtl/multisz.cxx

299 lines
6.6 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1997 **/
/**********************************************************************/
/*
multisz.cxx
This module contains a light weight multi-string class
FILE HISTORY:
KeithMo 20-Jan-1997 Created from string.cxx
*/
#include "precomp.hxx"
# include <dbgutil.h>
# include <multisz.hxx>
# include <auxctrs.h>
# include <tchar.h>
//
// Private Definitions
//
//
// When appending data, this is the extra amount we request to avoid
// reallocations
//
#define STR_SLOP 128
DWORD
MULTISZ::CalcLength( const CHAR * str,
LPDWORD pcStrings )
{
DWORD count = 0;
DWORD total = 1;
DWORD len;
while( *str ) {
len = ::strlen( str ) + 1;
total += len;
str += len;
count++;
}
if( pcStrings != NULL ) {
*pcStrings = count;
}
return total;
} // MULTISZ::CalcLength
BOOL
MULTISZ::FindString( const CHAR * str )
{
CHAR * multisz;
//
// Sanity check.
//
DBG_ASSERT( QueryStr() != NULL );
DBG_ASSERT( str != NULL );
DBG_ASSERT( *str != '\0' );
//
// Scan it.
//
multisz = QueryStr();
while( *multisz != '\0' ) {
if( !::strcmp( multisz, str ) ) {
return TRUE;
}
multisz += ::strlen( multisz ) + 1;
}
return FALSE;
} // MULTISZ::FindString
VOID
MULTISZ::AuxInit( const BYTE * pInit )
{
BOOL fRet;
if ( pInit )
{
DWORD cStrings;
int cbCopy = CalcLength( (const CHAR *)pInit, &cStrings ) * sizeof(CHAR);
fRet = Resize( cbCopy );
if ( fRet ) {
CopyMemory( QueryPtr(), pInit, cbCopy );
m_cchLen = (cbCopy)/sizeof(CHAR);
m_cStrings = cStrings;
} else {
BUFFER::SetValid( FALSE);
}
} else {
Reset();
}
} // MULTISZ::AuxInit()
/*******************************************************************
NAME: MULTISZ::AuxAppend
SYNOPSIS: Appends the string onto the multisz.
ENTRY: Object to append
********************************************************************/
BOOL MULTISZ::AuxAppend( const BYTE * pStr, UINT cbStr, BOOL fAddSlop )
{
DBG_ASSERT( pStr != NULL );
UINT cbThis = QueryCB();
DBG_ASSERT( cbThis >= 2 );
if( cbThis == 2 ) {
//
// It's empty, so start at the beginning.
//
cbThis = 0;
} else {
//
// It's not empty, so back up over the final terminating NULL.
//
cbThis--;
}
//
// Only resize when we have to. When we do resize, we tack on
// some extra space to avoid extra reallocations.
//
// Note: QuerySize returns the requested size of the string buffer,
// *not* the strlen of the buffer
//
AcIncrement( CacMultiszAppend);
if ( QuerySize() < cbThis + cbStr + 1)
{
if ( !Resize( cbThis + cbStr + 1 + (fAddSlop ? STR_SLOP : 0 )) )
return FALSE;
}
// copy the exact string and tack on the double terminator
memcpy( (BYTE *) QueryPtr() + cbThis,
pStr,
cbStr);
*((BYTE *)QueryPtr() + cbThis + cbStr) = '\0';
m_cchLen = CalcLength( (const CHAR *)QueryPtr(), &m_cStrings );
return TRUE;
} // MULTISZ::AuxAppend()
#if 0
BOOL
MULTISZ::CopyToBuffer( WCHAR * lpszBuffer, LPDWORD lpcch) const
/*++
Description:
Copies the string into the WCHAR buffer passed in if the buffer
is sufficient to hold the translated string.
If the buffer is small, the function returns small and sets *lpcch
to contain the required number of characters.
Arguments:
lpszBuffer pointer to WCHAR buffer which on return contains
the UNICODE version of string on success.
lpcch pointer to DWORD containing the length of the buffer.
If *lpcch == 0 then the function returns TRUE with
the count of characters required stored in *lpcch.
Also in this case lpszBuffer is not affected.
Returns:
TRUE on success.
FALSE on failure. Use GetLastError() for further details.
History:
MuraliK 11-30-94
--*/
{
BOOL fReturn = TRUE;
if ( lpcch == NULL) {
SetLastError( ERROR_INVALID_PARAMETER);
return ( FALSE);
}
if ( *lpcch == 0) {
//
// Inquiring the size of buffer alone
//
*lpcch = QueryCCH() + 1; // add one character for terminating null
} else {
//
// Copy after conversion from ANSI to Unicode
//
int iRet;
iRet = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
QueryStrA(), QueryCCH() + 1,
lpszBuffer, (int )*lpcch);
if ( iRet == 0 || iRet != (int ) *lpcch) {
//
// Error in conversion.
//
fReturn = FALSE;
}
}
return ( fReturn);
} // MULTISZ::CopyToBuffer()
#endif
BOOL
MULTISZ::CopyToBuffer( CHAR * lpszBuffer, LPDWORD lpcch) const
/*++
Description:
Copies the string into the CHAR buffer passed in if the buffer
is sufficient to hold the translated string.
If the buffer is small, the function returns small and sets *lpcch
to contain the required number of characters.
Arguments:
lpszBuffer pointer to CHAR buffer which on return contains
the string on success.
lpcch pointer to DWORD containing the length of the buffer.
If *lpcch == 0 then the function returns TRUE with
the count of characters required stored in *lpcch.
Also in this case lpszBuffer is not affected.
Returns:
TRUE on success.
FALSE on failure. Use GetLastError() for further details.
History:
MuraliK 20-Nov-1996
--*/
{
BOOL fReturn = TRUE;
if ( lpcch == NULL) {
SetLastError( ERROR_INVALID_PARAMETER);
return ( FALSE);
}
register DWORD cch = QueryCCH() + 1;
if ( *lpcch >= cch) {
DBG_ASSERT( lpszBuffer);
CopyMemory( lpszBuffer, QueryStrA(), cch);
} else {
DBG_ASSERT( *lpcch < cch);
SetLastError( ERROR_INSUFFICIENT_BUFFER);
fReturn = FALSE;
}
*lpcch = cch;
return ( fReturn);
} // MULTISZ::CopyToBuffer()