Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

508 lines
11 KiB

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1999 **/
/**********************************************************************/
/*
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
MCourage 12-Feb-1999 Another rewrite. All unicode of course.
*/
#ifndef _STRING_HXX_
#define _STRING_HXX_
# include <irtlmisc.h>
# include <buffer.hxx>
LONG
CompareStringNoCase(
IN const WCHAR * String1,
IN const WCHAR * String2,
IN DWORD cchString1 = 0,
IN DWORD cchString2 = 0
);
class IRTL_DLLEXP STRU;
/*++
class STRU:
Intention:
A light-weight string class supporting encapsulated string class.
This object is derived from BUFFER class.
It maintains following state:
m_cchLen - string length cached when we update the string.
--*/
class STRU
{
public:
STRU()
: m_Buff(),
m_cchLen( 0)
{
*QueryStr() = L'\0';
}
//
// creates a stack version of the STR object - uses passed in stack buffer
// STR does not free this pbInit on its own.
//
STRU(
WCHAR * pbInit,
DWORD cbInit
) : m_Buff( (BYTE *) pbInit, cbInit),
m_cchLen(0)
{
DBG_ASSERT(cbInit > 0);
*pbInit = L'\0';
}
//
// Checks and returns TRUE if this string has no valid data else FALSE
//
BOOL
IsEmpty(
VOID
) const
{ return ( m_cchLen == 0 ); }
//
// Returns TRUE if str has the same value as this string.
//
BOOL
Equals(
const STRU & str
) const
{
return (str.QueryCCH() == QueryCCH()) &&
(wcscmp(str.QueryStr(), QueryStr()) == 0);
}
//
// Returns TRUE if str has the same value as this string.
//
BOOL
Equals(
const WCHAR * pchInit
) const
{
if (pchInit == NULL || pchInit[0] == '\0')
{
return (IsEmpty());
}
return (wcscmp(pchInit, QueryStr()) == 0);
}
//
// Returns TRUE if str has the same value as this string.
//
BOOL
EqualsNoCase(
const STRU & str
) const
{
return (str.QueryCCH() == QueryCCH()) &&
( CompareStringNoCase(str.QueryStr(),
QueryStr(),
str.QueryCCH(),
QueryCCH()) == 0 );
}
//
// Returns TRUE if str has the same value as this string.
//
BOOL
EqualsNoCase(
const WCHAR * pchInit
) const
{
if (pchInit == NULL || pchInit[0] == '\0')
{
return (IsEmpty());
}
return ( CompareStringNoCase( pchInit,
QueryStr(),
0, // the function will calculate the length
QueryCCH()) == 0 );
}
//
// Returns the number of bytes in the string excluding the terminating
// NUL
//
UINT
QueryCB(
VOID
) const
{ return ( m_cchLen * sizeof(WCHAR)); }
//
// Returns # of characters in the string excluding the terminating NUL
//
UINT
QueryCCH(
VOID
) const
{ return (m_cchLen); }
//
// Return the string buffer
//
WCHAR *
QueryStr(
VOID
)
{ return ((WCHAR *) m_Buff.QueryPtr()); }
const WCHAR *
QueryStr(
VOID
) const
{ return ((const WCHAR *) m_Buff.QueryPtr()); }
//
// Resets the internal string to be NULL string. Buffer remains cached.
//
VOID
Reset(
VOID
)
{
DBG_ASSERT( QueryStr() );
*(QueryStr()) = L'\0';
m_cchLen = 0;
}
//
// Resize the internal buffer
//
HRESULT Resize( DWORD cbSize )
{
if (!m_Buff.Resize( cbSize ) )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
return S_OK;
}
//
// Append something to the end of the string
//
HRESULT
Append(
const WCHAR * pchInit
)
{
if (pchInit) {
return AuxAppend(
(const BYTE *) pchInit,
(ULONG) ::wcslen(pchInit) * sizeof(WCHAR),
QueryCB()
);
} else {
return S_OK;
}
}
HRESULT
Append(
const WCHAR * pchInit,
DWORD cchLen
)
{
if (pchInit && cchLen) {
return AuxAppend(
(const BYTE *) pchInit,
cchLen * sizeof(WCHAR),
QueryCB()
);
} else {
return S_OK;
}
}
HRESULT
Append(
const STRU & str
)
{
if (str.QueryCCH()) {
return AuxAppend(
(const BYTE *) str.QueryStr(),
str.QueryCCH() * sizeof(WCHAR),
QueryCB()
);
} else {
return S_OK;
}
}
HRESULT
AppendA(
const CHAR * pchInit
)
{
return AuxAppendA(
(const BYTE*) pchInit,
(ULONG) strlen( pchInit ),
QueryCB()
);
}
//
// Copy the contents of another string to this one
//
HRESULT
Copy(
const WCHAR * pchInit
)
{
if (pchInit) {
return AuxAppend(
(const BYTE *) pchInit,
(ULONG) ::wcslen(pchInit) * sizeof(WCHAR),
0
);
} else {
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
}
HRESULT
Copy(
const WCHAR * pchInit,
DWORD cchLen
)
{
if (pchInit) {
return AuxAppend(
(const BYTE *) pchInit,
cchLen * sizeof(WCHAR),
0
);
} else {
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
}
HRESULT
Copy(
const STRU & str
)
{
return AuxAppend(
(const BYTE *) str.QueryStr(),
str.QueryCCH() * sizeof(WCHAR),
0
);
}
HRESULT
CopyA(
const CHAR * pchInit
)
{
return AuxAppendA(
(const BYTE*) pchInit,
(ULONG) strlen( pchInit ),
0
);
}
HRESULT
CopyA(
const CHAR * pchInit,
DWORD cchLen
)
{
return AuxAppendA(
(const BYTE*) pchInit,
cchLen,
0
);
}
//
// Allow access to the internal buffer, for direct manipulation.
//
BUFFER *
QueryBuffer(
VOID
)
{
return &m_Buff;
}
//
// Recalculate the length of the string, etc. because we've modified
// the buffer directly.
//
VOID
SyncWithBuffer(
VOID
)
{
m_cchLen = (LONG) wcslen( QueryStr() );
}
//
// Makes a copy of the stored string into the given buffer
// NYI
//
HRESULT
CopyToBuffer(
WCHAR * lpszBuffer,
LPDWORD lpcb
) const;
//
//
BOOL
SetLen(
IN DWORD cchLen
)
/*++
Routine Description:
Set the length of the string and null terminate, if there
is sufficient buffer already allocated. Will not reallocate.
NOTE: The actual wcslen may be less than cchLen if you are
expanding the string. If this is the case SyncWithBuffer
should be called to ensure consistency. The real use of this
method is to truncate.
Arguments:
cchLen - The number of characters in the new string.
Return Value:
TRUE - if the buffer size is sufficient to hold the string.
FALSE - insufficient buffer.
--*/
{
if( cchLen >= m_Buff.QuerySize() / sizeof(WCHAR) )
{
return FALSE;
}
*((WCHAR *) m_Buff.QueryPtr() + cchLen) = L'\0';
m_cchLen = cchLen;
return TRUE;
}
//
// Useful for unescaping URL, QueryString etc
//
HRESULT Unescape();
HRESULT Escape();
private:
//
// Avoid C++ errors. This object should never go through a copy
// constructor, unintended cast or assignment.
//
STRU( const STRU & )
{}
STRU( const WCHAR * )
{}
STRU( WCHAR * )
{}
STRU & operator = ( const STRU & )
{ return *this; }
HRESULT
STRU::AuxAppend(
const BYTE * pStr,
ULONG cbStr,
ULONG cbOffset,
BOOL fAddSlop = TRUE
);
HRESULT
STRU::AuxAppendA(
const BYTE * pStr,
ULONG cbStr,
ULONG cbOffset,
BOOL fAddSlop = TRUE
);
BUFFER m_Buff;
LONG m_cchLen;
};
//
// 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_STRU( name, size ) WCHAR __ach##name[size]; \
STRU name( __ach##name, sizeof( __ach##name ))
//
// Macros for declaring and initializing a STRU that will use inline memory
// of <size> bytes as a member of an object.
//
#define INLINE_STRU(name, size) WCHAR __ach##name[size]; \
STRU name;
#define INLINE_STRU_INIT(name) name( __ach##name, sizeof( __ach##name ) )
//
// General string utilities
//
#define ISWHITEW( wch ) ((wch) == L' ' || (wch) == L'\t' || (wch) == L'\r')
WCHAR * SkipWhite(
WCHAR * pwch
);
WCHAR * SkipTo(
WCHAR * pwch, WCHAR wch
);
WCHAR *
FlipSlashes(
WCHAR * pszPath
);
HRESULT
MakePathCanonicalizationProof(
IN LPWSTR pszName,
OUT STRU * pstrPath
);
#endif // !_STRING_HXX_