/*++ Copyright (c) 1994 Microsoft Corporation All rights reserved. Module Name: String.cxx Abstract: Short strings Author: Albert Ting (AlbertT) 9-June-1994 Revision History: --*/ #include "spllibp.hxx" #pragma hdrstop // // Class specific NULL state. // TCHAR TString::gszNullState[2] = {0,0}; // // Default construction. // TString:: TString( VOID ) : _pszString( &TString::gszNullState[kValid] ) { } // // Construction using an existing LPCTSTR string. // TString:: TString( IN LPCTSTR psz ) : _pszString( &TString::gszNullState[kValid] ) { bUpdate( psz ); } // // Destruction, insure we don't free our NULL state. // TString:: ~TString( VOID ) { vFree( _pszString ); } // // Copy constructor. // TString:: TString( const TString &String ) : _pszString( &TString::gszNullState[kValid] ) { bUpdate( String._pszString ); } // // Indicates if a string has any usable data. // BOOL TString:: bEmpty( VOID ) const { return _pszString[0] == 0; } // // Indicates if a string object is valid. // BOOL TString:: bValid( VOID ) const { return _pszString != &TString::gszNullState[kInValid]; } // // Return the length of the string. // UINT TString:: uLen( VOID ) const { return lstrlen( _pszString ); } BOOL TString:: bCat( IN LPCTSTR psz ) /*++ Routine Description: Safe concatenation of the specified string to the string object. If the allocation fails, return FALSE and the original string is not modified. Arguments: psz - Input string, may be NULL. Return Value: TRUE = update successful FALSE = update failed --*/ { BOOL bStatus = FALSE; // // If a valid string was passed. // if( psz ){ LPTSTR pszTmp = _pszString; // // Allocate the new buffer consisting of the size of the orginal // string plus the sizeof of the new string plus the null terminator. // _pszString = (LPTSTR)AllocMem( ( lstrlen( pszTmp ) + lstrlen( psz ) + 1 ) * sizeof ( pszTmp[0] ) ); // // If memory was not available. // if( !_pszString ){ // // Release the original buffer. // vFree( pszTmp ); // // Mark the string object as invalid. // _pszString = &TString::gszNullState[kInValid]; } else { // // Copy the string and concatenate the passed string. // lstrcpy( _pszString, pszTmp ); lstrcat( _pszString, psz ); // // Release the original buffer. // vFree( pszTmp ); // // Indicate success. // bStatus = TRUE; } // // Skip null pointers, not an error. // } else { bStatus = TRUE; } return bStatus; } BOOL TString:: bUpdate( IN LPCTSTR psz ) /*++ Routine Description: Safe updating of string. If the allocation fails, return FALSE and leave the string as is. Arguments: psz - Input string, may be NULL. Return Value: TRUE = update successful FALSE = update failed --*/ { // // Check if the null pointer is passed. // if( !psz ){ // // If not pointing to the gszNullState // vFree( _pszString ); // // Mark the object as valid. // _pszString = &TString::gszNullState[kValid]; return TRUE; } // // Create temp pointer and allocate the new string. // LPTSTR pszTmp = _pszString; _pszString = (LPTSTR) AllocMem(( lstrlen(psz)+1 ) * sizeof( psz[0] )); // // If memory was not available. // if( !_pszString ){ // // Mark the string object as invalid. // _pszString = &TString::gszNullState[kInValid]; return FALSE; } // // Copy the string and // lstrcpy( _pszString, psz ); // // If the old string object was not pointing to our // class specific gszNullStates then release the memory. // vFree( pszTmp ); return TRUE; } BOOL TString:: bLoadString( IN HINSTANCE hInst, IN UINT uID ) /*++ Routine Description: Safe load of a string from a resources file. Arguments: hInst - Instance handle of resource file. uId - Resource id to load. Return Value: TRUE = load successful FALSE = load failed --*/ { TCHAR szScratch[kStrMax*2]; if ( !LoadString( hInst, uID, szScratch, COUNTOF( szScratch ))){ DBGMSG( DBG_ERROR, ( "String.vLoadString: failed to load IDS 0x%x, %d\n", uID, GetLastError() )); return FALSE; } return bUpdate( szScratch ); } VOID TString:: vFree( IN LPTSTR pszString ) /*++ Routine Description: Safe free, frees the string memory. Ensures we do not try an free our global memory block. Arguments: pszString pointer to string meory to free. Return Value: Nothing. --*/ { // // If this memory was not pointing to our // class specific gszNullStates then release the memory. // if( pszString != &TString::gszNullState[kValid] && pszString != &TString::gszNullState[kInValid] ){ FreeMem( pszString ); } } LPTSTR pszLoadString( IN HINSTANCE hInst, IN UINT uID ) /*++ Routine Description: Load the string from resource file using the specified resource id. If this routine fails it will return a NULL. Arguments: hInst - Instance handel uID - Resource ID of string to load Return Value: Pointer to newly allocated loaded string. NULL if load resource string fails. --*/ { TCHAR szScratch[kStrMax*2]; LPTSTR pszStr; if ( !LoadString( hInst, uID, szScratch, COUNTOF( szScratch ))){ DBGMSG( DBG_ERROR, ( "pszLoadString: failed to load IDS 0x%x, %d\n", uID, GetLastError() )); return NULL; } pszStr = (LPTSTR)AllocMem(( lstrlen( szScratch ) + 1 ) * sizeof( pszStr[0] )); lstrcpy( pszStr, szScratch ); return pszStr; }