|
|
/*****************************************************************/ /** 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; }
|