299 lines
6.6 KiB
C++
299 lines
6.6 KiB
C++
/**********************************************************************/
|
||
/** 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()
|
||
|