355 lines
6.6 KiB
C++
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;
|
||
|
}
|
||
|
|