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

266 lines
5.8 KiB
C++

/*****************************************************************/
/** Microsoft Windows for Workgroups **/
/** Copyright (C) Microsoft Corp., 1991-1992 **/
/*****************************************************************/
/*
strassgn.cxx
NLS/DBCS-aware string class: assignment operator
This file contains the implementation of the assignment operator
for the STRING class. It is separate so that clients of STRING which
do not use this operator need not link to it.
FILE HISTORY:
beng 01/18/91 Separated from original monolithic .cxx
beng 02/07/91 Uses lmui.hxx
beng 07/26/91 Replaced min with local inline
gregj 04/02/93 Do buffer overflow checks for OWNERALLOC strings
instead of asserting
*/
#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::operator=
SYNOPSIS: Assignment operator
ENTRY: Either NLS_STR or CHAR*.
EXIT: If successful, contents of string overwritten.
If failed, the original contents of the string remain.
RETURNS: Reference to self.
HISTORY:
beng 10/23/90 Created
johnl 11/13/90 Added UIASSERTion checks for using bad
strings
beng 02/05/91 Uses CHAR * instead of PCH
Johnl 03/06/91 Removed assertion check for *this
being valid
johnl 04/12/91 Resets error variable on PCH assignment
if successful.
beng 07/22/91 Allow assignment of an erroneous string;
reset error on nls assignment as well
gregj 04/02/93 Do buffer overflow checks for OWNERALLOC strings
instead of asserting
********************************************************************/
NLS_STR& NLS_STR::operator=( const NLS_STR& nlsSource )
{
if ( this == &nlsSource )
return *this;
if (!nlsSource)
{
// Assignment of an erroneous string
//
ReportError((unsigned short)nlsSource.QueryError());
return *this;
}
INT cbToCopy = nlsSource.strlen();
if ( !IsOwnerAlloc() )
{
if ( QueryAllocSize() < nlsSource.strlen()+1 )
{
/* Don't use Realloc because we want to retain the contents
* of the string if we fail to get the memory.
*/
CHAR * pchNew = new CHAR[nlsSource.strlen()+1];
if ( pchNew == NULL )
{
ReportError( WN_OUT_OF_MEMORY );
return *this;
}
delete _pchData;
_pchData = pchNew;
_cbData = nlsSource.strlen()+1;
}
}
else
{
if (::fDBCSEnabled) {
if (QueryAllocSize() <= cbToCopy) {
cbToCopy = QueryAllocSize() - 1; /* leave room for the null */
const CHAR *p = nlsSource.QueryPch();
while (p < nlsSource.QueryPch() + cbToCopy)
p += nlsSource.IsDBCSLeadByte(*p) ? 2 : 1;
if (p - nlsSource.QueryPch() != cbToCopy) /* last char was DB */
cbToCopy--; /* don't copy lead byte either */
}
}
else {
if (QueryAllocSize() <= cbToCopy)
cbToCopy = QueryAllocSize() - 1;
}
}
if (nlsSource.IsOEM())
SetOEM();
else
SetAnsi();
::memcpyf( _pchData, nlsSource.QueryPch(), cbToCopy ); /* copy string data */
_pchData[cbToCopy] = '\0'; /* terminate the string */
_cchLen = cbToCopy;
IncVers();
/* Reset the error state, since the string is now valid.
*/
ReportError( WN_SUCCESS );
return *this;
}
NLS_STR& NLS_STR::operator=( const CHAR *pchSource )
{
if ( pchSource == NULL )
{
if ( !IsOwnerAlloc() && !QueryAllocSize() )
{
if ( !Alloc(1) )
ReportError( WN_OUT_OF_MEMORY );
return *this;
}
UIASSERT( QueryAllocSize() > 0 );
*_pchData = '\0';
_cchLen = 0;
}
else
{
INT iSourceLen = ::strlenf( pchSource );
INT cbToCopy;
if ( !IsOwnerAlloc() )
{
if ( QueryAllocSize() < iSourceLen + 1 )
{
CHAR * pchNew = new CHAR[iSourceLen + 1];
if ( pchNew == NULL )
{
ReportError( WN_OUT_OF_MEMORY );
return *this;
}
delete _pchData;
_pchData = pchNew;
_cbData = iSourceLen + 1;
}
cbToCopy = iSourceLen;
}
else
{
if (QueryAllocSize() <= iSourceLen) {
if (::fDBCSEnabled) {
cbToCopy = QueryAllocSize() - 1; /* leave room for the null */
const CHAR *p = pchSource;
while (p < pchSource + cbToCopy)
p += IsDBCSLeadByte(*p) ? 2 : 1;
if (p - pchSource != cbToCopy) /* last char was DB */
cbToCopy--; /* don't copy lead byte either */
}
else
cbToCopy = QueryAllocSize() - 1;
}
else
cbToCopy = iSourceLen;
}
::memcpyf( _pchData, pchSource, cbToCopy );
_pchData[cbToCopy] = '\0'; /* terminate the string */
_cchLen = cbToCopy;
}
IncVers();
/* Reset the error state, since the string is now valid.
*/
ReportError( WN_SUCCESS );
return *this;
}
#ifdef EXTENDED_STRINGS
/*******************************************************************
NAME: NLS_STR::CopyFrom()
SYNOPSIS: Assignment method which returns an error code
ENTRY:
nlsSource - source argument, either a nlsstr or char vector.
achSource
EXIT:
Copied argument into this. Error code of string set.
RETURNS:
Error code of string - WN_SUCCESS if successful.
NOTES:
If the CopyFrom fails, the current string will retain its
original contents and error state.
HISTORY:
beng 09/18/91 Created
beng 09/19/91 Added content-preserving behavior
********************************************************************/
APIERR NLS_STR::CopyFrom( const NLS_STR & nlsSource )
{
if (!nlsSource)
return nlsSource.QueryError();
*this = nlsSource;
APIERR err = QueryError();
if (err)
Reset();
else {
if (nlsSource.IsOEM())
SetOEM();
else
SetAnsi();
}
return err;
}
APIERR NLS_STR::CopyFrom( const CHAR * achSource )
{
*this = achSource;
APIERR err = QueryError();
if (err)
Reset();
return err;
}
#endif // EXTENDED_STRINGS