windows-nt/Source/XPSP1/NT/shell/ext/ratings/common/string.cpp
2020-09-26 16:20:57 +08:00

355 lines
6.6 KiB
C++

/*****************************************************************/
/** Microsoft Windows for Workgroups **/
/** Copyright (C) Microsoft Corp., 1991-1992 **/
/*****************************************************************/
/*
string.cxx
NLS/DBCS-aware string class: essential core methods
This file contains those routines which every client of
the string classes will always need.
Most of the implementation has been exploded into other files,
so that an app linking to string doesn't end up dragging the
entire string runtime library along with it.
FILE HISTORY:
beng 10/23/90 Created
johnl 12/11/90 Remodeled beyond all recognizable form
beng 01/18/91 Most methods relocated into other files
beng 02/07/91 Uses lmui.hxx
beng 07/26/91 Replaced min with local inline
gregj 03/30/93 Removed ISTR to separate module
*/
#include "npcommon.h"
extern "C"
{
#include <netlib.h>
}
#if defined(DEBUG)
static const CHAR szFileName[] = __FILE__;
#define _FILENAME_DEFINED_ONCE szFileName
#endif
#include <npassert.h>
#include <npstring.h>
/*******************************************************************
NAME: NLS_STR::NLS_STR
SYNOPSIS: Constructor for NLS_STR
ENTRY: NLS_STR takes many (too many) ctor forms.
EXIT: String constructed
NOTES:
The default constructor creates an empty string.
HISTORY:
beng 10/23/90 Created
beng 04/26/91 Replaced 'CB' and USHORT with INT
beng 07/22/91 Uses member-init ctor forms
********************************************************************/
NLS_STR::NLS_STR()
: _pchData(0),
_cbData(0),
_cchLen(0),
_fsFlags(0)
{
if ( !Alloc(1) )
return;
*_pchData = '\0';
InitializeVers();
}
NLS_STR::NLS_STR( INT cchInitLen )
: _pchData(0),
_cbData(0),
_cchLen(0),
_fsFlags(0)
{
if (!Alloc(cchInitLen+1))
return;
::memsetf( _pchData, '\0', cchInitLen );
_cchLen = 0;
InitializeVers();
}
NLS_STR::NLS_STR( const CHAR * pchInit )
: _pchData(0),
_cbData(0),
_cchLen(0),
_fsFlags(0)
{
if (pchInit == NULL)
{
if (!Alloc(1))
ReportError( WN_OUT_OF_MEMORY );
else
{
*_pchData = '\0';
}
return;
}
INT iSourceLen = ::strlenf( pchInit );
if ( !Alloc( iSourceLen + 1 ) )
return;
::strcpyf( _pchData, pchInit );
_cchLen = iSourceLen;
InitializeVers();
}
NLS_STR::NLS_STR( const NLS_STR & nlsInit )
: _pchData(0),
_cbData(0),
_cchLen(0),
_fsFlags(0)
{
UIASSERT( !nlsInit.QueryError() );
if (!Alloc( nlsInit.strlen()+1 ) )
return;
::memcpyf( _pchData, nlsInit.QueryPch(), nlsInit.strlen()+1 );
_cchLen = nlsInit.strlen();
InitializeVers();
}
#ifdef EXTENDED_STRINGS
NLS_STR::NLS_STR( const CHAR * pchInit, INT iTotalLen )
: _pchData(0),
_cbData(0),
_cchLen(0),
_fsFlags(0)
{
if (pchInit == NULL)
{
if (!Alloc( 1 + iTotalLen ))
return;
*_pchData = '\0';
}
else
{
_cchLen = ::strlenf( pchInit );
if ( _cchLen > iTotalLen )
{
_cchLen = 0;
ReportError( WN_OUT_OF_MEMORY );
return;
}
if ( !Alloc( iTotalLen ) )
{
_cchLen = 0;
return;
}
::memcpyf( _pchData, pchInit, _cchLen+1 );
}
InitializeVers();
}
#endif // EXTENDED_STRINGS
NLS_STR::NLS_STR( unsigned stralloc, CHAR *pchInit, INT cbSize )
: _pchData(0),
_cbData(0),
_cchLen(0),
_fsFlags(SF_OWNERALLOC)
{
UIASSERT( stralloc == STR_OWNERALLOC || stralloc == STR_OWNERALLOC_CLEAR);
UIASSERT( pchInit != NULL );
if ( stralloc == STR_OWNERALLOC_CLEAR )
{
UIASSERT( cbSize > 0 );
*(_pchData = pchInit ) = '\0';
_cchLen = 0;
}
else
{
_pchData = pchInit;
_cchLen = ::strlenf( pchInit );
}
if ( cbSize == -1 )
_cbData = _cchLen + 1;
else
_cbData = cbSize;
InitializeVers();
}
#ifdef EXTENDED_STRINGS
NLS_STR::NLS_STR( unsigned stralloc, CHAR *pchBuff, INT cbSize,
const CHAR *pchInit )
: _pchData(0),
_cbData(0),
_cchLen(0),
_fsFlags(SF_OWNERALLOC)
{
UIASSERT( stralloc == STR_OWNERALLOC );
UIASSERT( stralloc != STR_OWNERALLOC_CLEAR );
UIASSERT( pchBuff != NULL || pchInit != NULL );
UIASSERT( cbSize > 0 && ::strlenf( pchInit ) <= cbSize );
UNREFERENCED( stralloc );
_pchData = pchBuff;
INT cbToCopy = min( ::strlenf( pchInit ), cbSize - 1 );
::memcpyf( _pchData, pchInit, cbToCopy );
*(_pchData + cbToCopy) = '\0';
_cchLen = cbToCopy;
_cbData = cbSize;
InitializeVers();
}
#endif
/*******************************************************************
NAME: NLS_STR::~NLS_STR
SYNOPSIS: Destructor for NLS_STR
ENTRY:
EXIT: Storage deallocated, if not owner-alloc
HISTORY:
beng 10/23/90 Created
beng 07/22/91 Zeroes only in debug version
********************************************************************/
NLS_STR::~NLS_STR()
{
if ( !IsOwnerAlloc() )
delete _pchData;
#if defined(DEBUG)
_pchData = NULL;
_cchLen = 0;
_cbData = 0;
#endif
}
/*******************************************************************
NAME: NLS_STR::Alloc
SYNOPSIS: Common code for constructors.
ENTRY:
cb - number of bytes desired in string storage
EXIT:
Returns TRUE if successful:
_pchData points to allocated storage of "cb" bytes.
_cbData set to cb.
Allocated storage set to 0xF2 in debug version
Returns FALSE upon allocation failure.
NOTES:
HISTORY:
beng 10/23/90 Created
johnl 12/11/90 Updated as per code review
beng 04/26/91 Changed USHORT parm to INT
********************************************************************/
BOOL NLS_STR::Alloc( INT cb )
{
UIASSERT( cb != 0 );
_pchData = new CHAR[cb];
if (_pchData == NULL)
{
// For now, assume not enough memory.
//
ReportError(WN_OUT_OF_MEMORY);
return FALSE;
}
#ifdef DEBUG
::memsetf(_pchData, 0xf2, cb);
#endif
_cbData = cb;
return TRUE;
}
/*******************************************************************
NAME: NLS_STR::Reset
SYNOPSIS: Attempts to clear the error state of the string
ENTRY: String is in error state
EXIT: If recoverable, string is correct again
RETURNS: TRUE if successful; FALSE otherwise
NOTES:
An operation on a string may fail, if this occurs, the error
flag is set and you can't use the string until the flag
is cleared. By calling Reset, you can clear the flag,
thus allowing you to get access to the string again. The
string will be in a consistent state. Reset will return
FALSE if the string couldn't be restored (for example, after
construction failure).
HISTORY:
Johnl 12/12/90 Created
********************************************************************/
BOOL NLS_STR::Reset()
{
UIASSERT( QueryError() ) ; // Make sure an error exists
if ( QueryError() == WN_OUT_OF_MEMORY && _pchData != NULL )
{
ReportError( WN_SUCCESS );
return TRUE;
}
return FALSE;
}