/**********************************************************************/ /** 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 // // Maximum number of characters a loadable string resource can be // # define STR_MAX_RES_SIZE ( 320) class IRTL_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. m_fNoRealloc - does not allow resize of the buffer. if overflow - return error / truncate 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 IRTL_DLLEXP STR : public BUFFER { public: STR() : BUFFER (), m_cchLen ( 0), m_fNoRealloc (FALSE) {} // 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, BOOL fNoRealloc = FALSE) : BUFFER( (BYTE *) pbInit, cbInit), m_cchLen (0), m_fNoRealloc (fNoRealloc) {} STR( DWORD cbInit) : BUFFER( cbInit), m_cchLen (0), m_fNoRealloc (FALSE) {} STR( const CHAR * pchInit ) : BUFFER (), m_cchLen ( 0), m_fNoRealloc (FALSE) { AuxInit( (const BYTE * ) pchInit); } STR( const STR & str ) : BUFFER (), m_cchLen ( 0), m_fNoRealloc (FALSE) { 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, (UINT) ::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; } // erase the internal string. Buffer remains cached. VOID Clear( VOID) { DBG_ASSERT( QueryPtr() != NULL); ZeroMemory( QueryPtr(), QueryCB()); Reset(); } BOOL Copy( const CHAR * pchInit ) { if ( QueryPtr() ) { *(QueryStr()) = '\0'; m_cchLen = 0; } return ( (pchInit != NULL) ? AuxAppend( (const BYTE *) pchInit, (UINT) ::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(); // // support for hashing the string for privacy purposes // VOID Hash(); VOID Unhash(); // // 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()); } CHAR QueryFirstChar( VOID ) const { return (m_cchLen > 0) ? *QueryStr() : '\0'; } CHAR QueryLastChar( VOID ) const { return (m_cchLen > 0) ? *(QueryStr() + m_cchLen - 1) : '\0'; } // // 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() BOOL Equ( const STR & strA) const { return (QueryCB() != strA.QueryCB()) ? FALSE : ( QueryCB() ? !IISstricmp((UCHAR *)QueryStr(), (UCHAR *)strA.QueryStr()) : TRUE ); } BOOL Equ( CHAR *pszA) const { return QueryCB() ? !IISstricmp((UCHAR *)QueryStr(), (UCHAR *)pszA) : *pszA == '\0'; } // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // 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; BOOL m_fNoRealloc; 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 // 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 )) // // Similar to STACK_STR, but suing the static buffer constructor, so no // realloc can occur // #define STACK_STATSTR( name, size ) \ CHAR __ach##name[size]; \ STR name( __ach##name, sizeof( __ach##name ), TRUE) // // Unlike the STACK_STR macro, this template can be used for member // variables in classes. // template class IRTL_DLLEXP Str : public STR { private: CHAR m_achData[N]; // Actual data public: Str() : STR(m_achData, N) {} }; // class Str // // this template is similar to Str, but initializes STR to static buffer usage (no realloc) // template class StatStr : public STR { private: CHAR m_achData[N]; // Actual data public: StatStr() : STR(m_achData, N, TRUE) {} }; // class Str #endif // !_STRING_HXX_