313 lines
8.6 KiB
C++
313 lines
8.6 KiB
C++
|
/**********************************************************************/
|
||
|
/** Microsoft Windows NT **/
|
||
|
/** Copyright(c) Microsoft Corp., 1994 **/
|
||
|
/**********************************************************************/
|
||
|
|
||
|
/*
|
||
|
string.hxx
|
||
|
|
||
|
This module contains a light weight string class
|
||
|
|
||
|
|
||
|
FILE HISTORY:
|
||
|
Johnl 15-Aug-1994 Created
|
||
|
MuraliK 09-July-1996 Rewrote for efficiency with no unicode support
|
||
|
*/
|
||
|
|
||
|
|
||
|
#ifndef _STRING_HXX_
|
||
|
#define _STRING_HXX_
|
||
|
|
||
|
# include <buffer.hxx>
|
||
|
|
||
|
|
||
|
//
|
||
|
// Maximum number of characters a loadable string resource can be
|
||
|
//
|
||
|
|
||
|
# define STR_MAX_RES_SIZE ( 320)
|
||
|
|
||
|
|
||
|
|
||
|
class dllexp STR;
|
||
|
|
||
|
//
|
||
|
// If an application defines STR_MODULE_NAME, it will be used
|
||
|
// as the default module name on string loads
|
||
|
//
|
||
|
|
||
|
#ifndef STR_MODULE_NAME
|
||
|
#define STR_MODULE_NAME NULL
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// These are the characters that are considered to be white space
|
||
|
//
|
||
|
#define ISWHITE( ch ) ((ch) == L'\t' || (ch) == L' ' || (ch) == L'\r')
|
||
|
#define ISWHITEA( ch ) ((ch) == '\t' || (ch) == ' ' || (ch) == '\r')
|
||
|
|
||
|
|
||
|
//
|
||
|
// Removes useless segments from the URL and makes sure it doesn't go
|
||
|
// past the root of the tree (i.e., "/foo/../..")
|
||
|
//
|
||
|
|
||
|
INT CanonURL( CHAR * pszPath, BOOL fIsDBCS = FALSE );
|
||
|
|
||
|
//
|
||
|
// Map these string functions to appropriate RT call depending on the code
|
||
|
// page of the system. Thus we only use DBCS operations when necessary.
|
||
|
//
|
||
|
|
||
|
DWORD InitializeStringFunctions( VOID );
|
||
|
UCHAR * IISstrupr( UCHAR * pszString );
|
||
|
UCHAR * IISstrlwr( UCHAR * pszString );
|
||
|
INT IISstrnicmp( UCHAR * pszString1, UCHAR * pszString2, size_t iSize );
|
||
|
size_t IISstrlen( UCHAR * pszString1 );
|
||
|
char * IISstrncpy (char * dest, const char * source, size_t count);
|
||
|
INT IISstricmp( UCHAR * pszString1, UCHAR * pszString2);
|
||
|
UCHAR *IISstrrchr(const UCHAR * pszString, UINT c);
|
||
|
|
||
|
|
||
|
/*++
|
||
|
class STR:
|
||
|
|
||
|
Intention:
|
||
|
A light-weight string class supporting encapsulated string class.
|
||
|
|
||
|
This object is derived from BUFFER class.
|
||
|
It maintains following state:
|
||
|
|
||
|
m_fValid - whether this object is valid -
|
||
|
used only by STR() init functions
|
||
|
* NYI: I need to kill this someday *
|
||
|
m_cchLen - string length cached when we update the string.
|
||
|
|
||
|
Member Functions:
|
||
|
There are two categories of functions:
|
||
|
1) Safe Functions - which do integrity checking of state
|
||
|
2) UnSafe Functions - which do not do integrity checking, but
|
||
|
enable writing to the data stream freely.
|
||
|
(someday this will be enabled as Safe versions without
|
||
|
problem for users)
|
||
|
|
||
|
--*/
|
||
|
class dllexp STR : public BUFFER
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
STR()
|
||
|
: BUFFER (),
|
||
|
m_cchLen ( 0)
|
||
|
{}
|
||
|
|
||
|
// creates a stack version of the STR object - uses passed in stack buffer
|
||
|
// STR does not free this pbInit on its own.
|
||
|
STR( CHAR * pbInit, DWORD cbInit)
|
||
|
: BUFFER( (BYTE *) pbInit, cbInit),
|
||
|
m_cchLen (0)
|
||
|
{}
|
||
|
|
||
|
STR( DWORD cbInit)
|
||
|
: BUFFER( cbInit),
|
||
|
m_cchLen (0)
|
||
|
{}
|
||
|
|
||
|
STR( const CHAR * pchInit )
|
||
|
: BUFFER (),
|
||
|
m_cchLen ( 0)
|
||
|
{ AuxInit( (const BYTE * ) pchInit); }
|
||
|
|
||
|
STR( const STR & str )
|
||
|
: BUFFER (),
|
||
|
m_cchLen ( 0)
|
||
|
{ AuxInit( (const BYTE * ) str.QueryStr()); }
|
||
|
|
||
|
BOOL SetLen( IN DWORD cchLen)
|
||
|
{
|
||
|
return ( ( cchLen >= QuerySize())? FALSE :
|
||
|
( *((CHAR *) QueryPtr() + cchLen) = '\0', // null terminate
|
||
|
m_cchLen = cchLen, // set the length
|
||
|
TRUE
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
BOOL IsValid(VOID) const { return ( BUFFER::IsValid()) ; }
|
||
|
//
|
||
|
// Checks and returns TRUE if this string has no valid data else FALSE
|
||
|
//
|
||
|
BOOL IsEmpty( VOID) const { return ( *QueryStr() == '\0'); }
|
||
|
|
||
|
BOOL Append( const CHAR * pchInit ) {
|
||
|
return ((pchInit != NULL) ? (AuxAppend( (const BYTE * ) pchInit,
|
||
|
::strlen(pchInit))) :
|
||
|
TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL Append( const CHAR * pchInit, DWORD cchLen ) {
|
||
|
return ((pchInit != NULL) ? (AuxAppend( (const BYTE * ) pchInit,
|
||
|
cchLen)) :
|
||
|
TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL Append( const STR & str )
|
||
|
{ return AuxAppend( (const BYTE * ) str.QueryStr(), str.QueryCCH()); }
|
||
|
|
||
|
// Resets the internal string to be NULL string. Buffer remains cached.
|
||
|
VOID Reset( VOID)
|
||
|
{ DBG_ASSERT( QueryPtr() != NULL);
|
||
|
*(QueryStr()) = '\0'; m_cchLen = 0;
|
||
|
}
|
||
|
|
||
|
BOOL Copy( const CHAR * pchInit ) {
|
||
|
if ( QueryPtr() ) { *(QueryStr()) = '\0'; m_cchLen = 0; }
|
||
|
return ( (pchInit != NULL) ?
|
||
|
AuxAppend( (const BYTE *) pchInit, ::strlen( pchInit ), FALSE ):
|
||
|
TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL SafeCopy( const CHAR * pchInit );
|
||
|
|
||
|
BOOL Copy( const CHAR * pchInit, IN DWORD cchLen ) {
|
||
|
if ( QueryPtr() ) { *(QueryStr()) = '\0'; m_cchLen = 0; }
|
||
|
return ( (pchInit != NULL) ?
|
||
|
AuxAppend( (const BYTE *) pchInit, cchLen, FALSE ):
|
||
|
TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL Copy( const STR & str )
|
||
|
{ return ( Copy(str.QueryStr(), str.QueryCCH())); }
|
||
|
|
||
|
//
|
||
|
// Loads a string from this module's string resource table
|
||
|
//
|
||
|
|
||
|
BOOL LoadString( IN DWORD dwResID,
|
||
|
IN LPCTSTR lpszModuleName = STR_MODULE_NAME,
|
||
|
IN DWORD dwLangID = 0);
|
||
|
|
||
|
BOOL LoadString( IN DWORD dwResID,
|
||
|
IN HMODULE hModule);
|
||
|
|
||
|
//
|
||
|
// Loads a string with insert params from this module's .mc resource
|
||
|
// table. Pass zero for the resource ID to use *this.
|
||
|
//
|
||
|
|
||
|
BOOL
|
||
|
FormatString( IN DWORD dwResID,
|
||
|
IN LPCTSTR apszInsertParams[],
|
||
|
IN LPCTSTR lpszModuleName = STR_MODULE_NAME OPTIONAL,
|
||
|
IN DWORD cbMaxMsg = 1024 OPTIONAL );
|
||
|
|
||
|
//
|
||
|
// Inserts and removes any odd ranged Latin-1 characters with the
|
||
|
// escaped hexadecimal equivalent (%xx)
|
||
|
//
|
||
|
|
||
|
BOOL Escape();
|
||
|
BOOL EscapeSpaces();
|
||
|
BOOL Unescape();
|
||
|
|
||
|
//
|
||
|
// Returns the number of bytes in the string excluding the terminating
|
||
|
// NULL
|
||
|
//
|
||
|
UINT QueryCB( VOID ) const
|
||
|
{ return ( m_cchLen * sizeof(CHAR)); }
|
||
|
|
||
|
//
|
||
|
// Returns # of characters in the string excluding the terminating NULL
|
||
|
//
|
||
|
UINT QueryCCH( VOID ) const { return (m_cchLen); }
|
||
|
|
||
|
//
|
||
|
// Makes a copy of the stored string in given buffer
|
||
|
//
|
||
|
BOOL CopyToBuffer( WCHAR * lpszBuffer, LPDWORD lpcch) const;
|
||
|
BOOL CopyToBuffer( CHAR * lpszBuffer, LPDWORD lpcch) const;
|
||
|
|
||
|
//
|
||
|
// Return the string buffer
|
||
|
//
|
||
|
CHAR * QueryStrA( VOID ) const { return ( QueryStr()); }
|
||
|
CHAR * QueryStr( VOID ) const { return ((CHAR *) QueryPtr()); }
|
||
|
|
||
|
|
||
|
//
|
||
|
// Makes a clone of the current string in the string pointer passed in.
|
||
|
//
|
||
|
BOOL
|
||
|
Clone( OUT STR * pstrClone) const
|
||
|
{
|
||
|
return ((pstrClone == NULL) ?
|
||
|
(SetLastError(ERROR_INVALID_PARAMETER), FALSE) :
|
||
|
(pstrClone->Copy( *this))
|
||
|
);
|
||
|
} // STR::Clone()
|
||
|
|
||
|
|
||
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
|
// UNSAFE FUNCTIONS - make sure you have enough space here
|
||
|
// Use these only if you have been dumping bytes to string
|
||
|
// object by considering it as a buffer object
|
||
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
|
|
||
|
// Append a single character
|
||
|
VOID Append( CHAR ch)
|
||
|
{
|
||
|
register CHAR * pch = ((CHAR *) QueryPtr()) + (m_cchLen++);
|
||
|
*pch = ch; *(pch+1) = '\0';
|
||
|
}
|
||
|
|
||
|
// Append two characters
|
||
|
VOID Append( CHAR ch1, CHAR ch2)
|
||
|
{
|
||
|
register CHAR * pch = ((CHAR *) QueryPtr()) + (m_cchLen += 2);
|
||
|
*(pch-2) = ch1; *(pch-1) = ch2; *pch = '\0';
|
||
|
}
|
||
|
|
||
|
// Append CRLF pattern \r\n --> use two character append function
|
||
|
VOID AppendCRLF(VOID) { Append( '\r', '\n'); }
|
||
|
|
||
|
private:
|
||
|
|
||
|
DWORD m_cchLen;
|
||
|
VOID AuxInit( const BYTE * pInit );
|
||
|
BOOL AuxAppend( const BYTE * pInit,
|
||
|
UINT cbStr, BOOL fAddSlop = TRUE );
|
||
|
};
|
||
|
|
||
|
|
||
|
//
|
||
|
// Quick macro for declaring a STR that will use stack memory of <size>
|
||
|
// bytes. If the buffer overflows then a heap buffer will be allocated
|
||
|
//
|
||
|
|
||
|
#define STACK_STR( name, size ) \
|
||
|
CHAR __ach##name[size]; \
|
||
|
STR name( __ach##name, sizeof( __ach##name ))
|
||
|
|
||
|
|
||
|
//
|
||
|
// Unlike the STACK_STR macro, this template can be used for member
|
||
|
// variables in classes.
|
||
|
//
|
||
|
|
||
|
template <size_t N>
|
||
|
class dllexp Str : public STR
|
||
|
{
|
||
|
private:
|
||
|
CHAR m_achData[N]; // Actual data
|
||
|
|
||
|
public:
|
||
|
Str()
|
||
|
: STR(m_achData, N)
|
||
|
{}
|
||
|
}; // class Str<N>
|
||
|
|
||
|
|
||
|
#endif // !_STRING_HXX_
|