Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1365 lines
24 KiB

/*++
Copyright (c) 1992-2000 Microsoft Corporation
Module Name:
wstring.hxx
Abstract:
This module defines the new WSTRING hierarchy:
WSTRING
FSTRING
DSTRING
WSTRING provides all of the desired methods on a string.
FSTRING provides an implementation of a WSTRING with fixed
size, user provided buffer.
DSTRING provides an implementation of a WSTRING with a
dynamic heap based buffer.
WSTRING is an abstract classes who's methods depend on the
implementation of two pure virtual methods: 'Resize' and 'NewBuf'.
A derived class must make use of the protected 'PutString' methods
in order to supply WSTRING with its string buffer. Use of
'PutString' is constrained as follows:
1. Supplying just a PWSTR to 'PutString' implies that
the PWSTR is null-terminated.
2. Supplying a PWSTR and length to 'PutString' implies that
the PWSTR points to a buffer of characters that is at
least one longer than the given length.
All implementations of 'Resize' and 'NewBuf' must:
1. Allocate an extra character for the NULL.
2. NULL-terminate the buffer allocated.
3. Always succeed if size <= current buffer size.
4. Always work as soon as the derived class is initialized (i.e.
WSTRING::Initialize method need not be called.).
5. Supply the buffer to WSTRING via 'PutString'.
Additionally 'Resize' must:
1. Preserve the contents of the current buffer.
All of the comparison operators supplied by WSTRING are
case insensitive.
--*/
#if !defined(_WSTRING_DEFN_)
#define _WSTRING_DEFN_
//
// The type of the index used to access individual characters within
// a generic string.
//
DEFINE_TYPE( ULONG, CHNUM );
//
// Magic constants
//
#define INVALID_CHAR ((WCHAR)-1)
#define INVALID_CHNUM ((CHNUM)-1)
#define TO_END INVALID_CHNUM
//
// Prefixes used in various names.
// (This should really be in path.hxx.)
//
#define GUID_VOLNAME_PREFIX L"Volume{"
#define DOS_GUIDNAME_PREFIX L"\\\\?\\"
#define NT_NAME_PREFIX L"\\??\\"
DECLARE_CLASS( WSTRING );
class ULIB_EXPORT WSTRING : public OBJECT {
public:
NONVIRTUAL
BOOLEAN
Initialize(
IN PCWSTRING InitialString,
IN CHNUM Position DEFAULT 0,
IN CHNUM Length DEFAULT TO_END
);
NONVIRTUAL
BOOLEAN
Initialize(
IN PCWSTR InitialString,
IN CHNUM StringLength DEFAULT TO_END
);
NONVIRTUAL
BOOLEAN
Initialize(
IN PCSTR InitialString,
IN CHNUM StringLength DEFAULT TO_END
);
NONVIRTUAL
BOOLEAN
Initialize(
);
NONVIRTUAL
BOOLEAN
Initialize(
IN LONG Number
);
NONVIRTUAL
PWSTRING
QueryString(
IN CHNUM Position DEFAULT 0,
IN CHNUM Length DEFAULT TO_END
) CONST;
NONVIRTUAL
BOOLEAN
QueryNumber(
OUT PLONG Number,
IN CHNUM Position DEFAULT 0,
IN CHNUM Length DEFAULT TO_END
) CONST;
NONVIRTUAL
CHNUM
QueryChCount(
) CONST;
#ifdef FE_SB
NONVIRTUAL
CHNUM
QueryByteCount(
) CONST;
#endif
NONVIRTUAL
CHNUM
SyncLength(
);
NONVIRTUAL
WCHAR
QueryChAt(
IN CHNUM Position
) CONST;
NONVIRTUAL
WCHAR
SetChAt(
IN WCHAR Char,
IN CHNUM Position
);
NONVIRTUAL
VOID
DeleteChAt(
IN CHNUM Position,
IN CHNUM Length DEFAULT 1
);
NONVIRTUAL
BOOLEAN
InsertString(
IN CHNUM AtPosition,
IN PCWSTRING String,
IN CHNUM FromPosition DEFAULT 0,
IN CHNUM FromLength DEFAULT TO_END
);
NONVIRTUAL
BOOLEAN
Replace(
IN CHNUM AtPosition,
IN CHNUM AtLength,
IN PCWSTRING String,
IN CHNUM FromPosition DEFAULT 0,
IN CHNUM FromLength DEFAULT TO_END
);
NONVIRTUAL
BOOLEAN
ReplaceWithChars(
IN CHNUM AtPosition,
IN CHNUM AtLength,
IN WCHAR Character,
IN CHNUM FromLength
);
NONVIRTUAL
PCWSTR
GetWSTR(
) CONST;
NONVIRTUAL
PWSTR
QueryWSTR(
IN CHNUM Position DEFAULT 0,
IN CHNUM Length DEFAULT TO_END,
OUT PWSTR Buffer DEFAULT NULL,
IN CHNUM BufferLength DEFAULT 0,
IN BOOLEAN ForceNull DEFAULT TRUE
) CONST;
NONVIRTUAL
PSTR
QuerySTR(
IN CHNUM Position DEFAULT 0,
IN CHNUM Length DEFAULT TO_END,
OUT PSTR Buffer DEFAULT NULL,
IN CHNUM BufferLength DEFAULT 0,
IN BOOLEAN ForceNull DEFAULT TRUE
) CONST;
NONVIRTUAL
LONG
Strcmp(
IN PCWSTRING String
) CONST;
STATIC
INT
Strcmp(
IN PWSTR String1,
IN PWSTR String2
) ;
STATIC
INT
Stricmp(
IN PWSTR String1,
IN PWSTR String2
) ;
NONVIRTUAL
LONG
Strcmp(
IN PCWSTRING String,
IN CHNUM LeftPosition
) CONST;
NONVIRTUAL
LONG
Strcmp(
IN PCWSTRING String,
IN CHNUM LeftPosition,
IN CHNUM LeftLength,
IN CHNUM RightPosition DEFAULT 0,
IN CHNUM RightLength DEFAULT TO_END
) CONST;
NONVIRTUAL
LONG
Stricmp(
IN PCWSTRING String
) CONST;
NONVIRTUAL
LONG
Stricmp(
IN PCWSTRING String,
IN CHNUM LeftPosition
) CONST;
NONVIRTUAL
LONG
Stricmp(
IN PCWSTRING String,
IN CHNUM LeftPosition,
IN CHNUM LeftLength,
IN CHNUM RightPosition DEFAULT 0,
IN CHNUM RightLength DEFAULT TO_END
) CONST;
STATIC
INT
Strcmps(
IN PWSTR p1,
IN PWSTR p2
);
STATIC
INT
Strcmpis(
IN PWSTR p1,
IN PWSTR p2
);
STATIC
PWSTR
SkipWhite(
IN PWSTR p
);
NONVIRTUAL
BOOLEAN
Strcat(
IN PCWSTRING String
);
NONVIRTUAL
PWSTRING
Strupr(
);
NONVIRTUAL
PWSTRING
Strupr(
IN CHNUM StartPosition,
IN CHNUM Length DEFAULT TO_END
);
NONVIRTUAL
PWSTRING
Strlwr(
);
NONVIRTUAL
PWSTRING
Strlwr(
IN CHNUM StartPosition,
IN CHNUM Length DEFAULT TO_END
);
NONVIRTUAL
CHNUM
Strchr(
IN WCHAR Char,
IN CHNUM StartPosition DEFAULT 0
) CONST;
NONVIRTUAL
CHNUM
Strrchr(
IN WCHAR Char,
IN CHNUM StartPosition DEFAULT 0
) CONST;
NONVIRTUAL
CHNUM
Strstr(
IN PCWSTRING String
) CONST;
NONVIRTUAL
CHNUM
Strspn(
IN PCWSTRING String,
IN CHNUM StartPosition DEFAULT 0
) CONST;
NONVIRTUAL
CHNUM
Strcspn(
IN PCWSTRING String,
IN CHNUM StartPosition DEFAULT 0
) CONST;
NONVIRTUAL
BOOLEAN
operator==(
IN RCWSTRING String
) CONST;
NONVIRTUAL
BOOLEAN
operator!=(
IN RCWSTRING String
) CONST;
NONVIRTUAL
BOOLEAN
operator<(
IN RCWSTRING String
) CONST;
NONVIRTUAL
BOOLEAN
operator>(
IN RCWSTRING String
) CONST;
NONVIRTUAL
BOOLEAN
operator<=(
IN RCWSTRING String
) CONST;
NONVIRTUAL
BOOLEAN
operator>=(
IN RCWSTRING String
) CONST;
VIRTUAL
BOOLEAN
Resize(
IN CHNUM NewStringLength
) PURE;
VIRTUAL
BOOLEAN
NewBuf(
IN CHNUM NewStringLength
) PURE;
NONVIRTUAL
CHNUM
Truncate(
IN CHNUM Position DEFAULT 0
);
STATIC
VOID
SetAnsiConversions(
);
STATIC
VOID
SetOemConversions(
);
STATIC
VOID
SetConsoleConversions(
);
#if defined FE_SB
STATIC
VOID
ResetConversions(
);
#endif
protected:
DECLARE_CONSTRUCTOR( WSTRING );
NONVIRTUAL
VOID
Construct(
);
NONVIRTUAL
VOID
PutString(
IN OUT PWSTR String
);
NONVIRTUAL
VOID
PutString(
IN OUT PWSTR String,
IN CHNUM Length
);
private:
STATIC BOOLEAN _UseAnsiConversions;
STATIC BOOLEAN _UseConsoleConversions;
#if defined FE_SB
STATIC BOOLEAN _UseAnsiConversionsPrev;
STATIC BOOLEAN _UseConsoleConversionsPrev;
#endif
#if defined FE_SB
STATIC
INT
CheckSpace(
IN PWSTR p
);
#endif
STATIC
BOOLEAN
ConvertOemToUnicodeN(
PWSTR UnicodeString,
ULONG MaxBytesInUnicodeString,
PULONG BytesInUnicodeString,
PCHAR OemString,
ULONG BytesInOemString
);
STATIC
BOOLEAN
ConvertUnicodeToOemN(
PCHAR OemString,
ULONG MaxBytesInOemString,
PULONG BytesInOemString,
PWSTR UnicodeString,
ULONG BytesInUnicodeString
);
PWSTR _s; // Beginning of string.
CHNUM _l; // Strlen of string.
};
INLINE
VOID
WSTRING::PutString(
IN OUT PWSTR String
)
/*++
Routine Description:
This routine initializes this string with the given null
terminated buffer.
Arguments:
String - Supplies the buffer to initialize the string with.
Return Value:
None.
--*/
{
_s = String;
_l = wcslen(_s);
}
INLINE
VOID
WSTRING::PutString(
IN OUT PWSTR String,
IN CHNUM Length
)
/*++
Routine Description:
This routine initializes this string with the given buffer
and string length.
Arguments:
String - Supplies the buffer to initialize the string with.
Length - Supplies the length of the string.
Return Value:
None.
--*/
{
_s = String;
_l = Length;
_s[_l] = 0;
}
INLINE
BOOLEAN
WSTRING::Initialize(
)
/*++
Routine Description:
This routine initializes this string to an empty null-terminated
string.
Arguments:
None.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
return Resize(0);
}
INLINE
CHNUM
WSTRING::QueryChCount(
) CONST
/*++
Routine Description:
This routine returns the number of characters in the string.
Arguments:
None.
Return Value:
The number of characters in this string.
--*/
{
return _l;
}
INLINE
CHNUM
WSTRING::SyncLength(
)
/*++
Routine Description:
This routine recalculates the correct length of the string.
Arguments:
None.
Return Value:
The recomputed length of the string.
--*/
{
return _l = wcslen(_s);
}
INLINE
WCHAR
WSTRING::QueryChAt(
IN CHNUM Position
) CONST
/*++
Routine Description:
This routine returns the character at the given position.
The position is a zero-based index into the string.
The position must be in the range of the string.
Arguments:
Position - Supplies an index into the string.
Return Value:
The character at the given position.
--*/
{
return (Position < _l) ? _s[Position] : INVALID_CHAR;
}
INLINE
WCHAR
WSTRING::SetChAt(
IN WCHAR Char,
IN CHNUM Position
)
/*++
Routine Description:
This routine sets the given character at the given position in
the string.
Arguments:
Char - Supplies the character to set into the string.
Position - Supplies the position at which to set the character.
Return Value:
The character that was set.
--*/
{
DebugAssert(Position < _l);
return _s[Position] = Char;
}
INLINE
PCWSTR
WSTRING::GetWSTR(
) CONST
/*++
Routine Description:
This routine returns this string internal buffer.
Arguments:
None.
Return Value:
A pointer to the strings buffer.
--*/
{
return _s;
}
INLINE
LONG
WSTRING::Strcmp(
IN PCWSTRING String
) CONST
/*++
Routine Description:
This routine compares two strings.
Arguments:
String - Supplies the string to compare to.
Return Value:
< 0 - This string is less than the given string.
0 - This string is equal to the given string.
> 0 - This string is greater than the given string.
--*/
{
return wcscmp(_s, String->_s);
}
INLINE
INT
WSTRING::Strcmp(
IN PWSTR String1,
IN PWSTR String2
)
{
return wcscmp( String1, String2 );
}
INLINE
INT
WSTRING::Stricmp(
IN PWSTR String1,
IN PWSTR String2
)
{
return _wcsicmp( String1, String2 );
}
INLINE
LONG
WSTRING::Strcmp(
IN PCWSTRING String,
IN CHNUM LeftPosition
) CONST
/*++
Routine Description:
This routine compares two strings. It starts comparing the
current string at the given position.
Arguments:
String - Supplies the string to compare to.
LeftPosition - Supplies the starting position to start comparison
on the current string.
Return Value:
< 0 - This string is less than the given string.
0 - This string is equal to the given string.
> 0 - This string is greater than the given string.
--*/
{
return wcscmp(_s + LeftPosition, String->_s);
}
INLINE
LONG
WSTRING::Stricmp(
IN PCWSTRING String
) CONST
/*++
Routine Description:
This routine compares two strings insensitive of case.
Arguments:
String - Supplies the string to compare to.
Return Value:
< 0 - This string is less than the given string.
0 - This string is equal to the given string.
> 0 - This string is greater than the given string.
--*/
{
return _wcsicmp(_s, String->_s);
}
INLINE
LONG
WSTRING::Stricmp(
IN PCWSTRING String,
IN CHNUM LeftPosition
) CONST
/*++
Routine Description:
This routine compares two strings insensitive of case.
Arguments:
String - Supplies the string to compare to.
LeftPosition - Supplies the position in this string to start
comparison.
Return Value:
< 0 - This string is less than the given string.
0 - This string is equal to the given string.
> 0 - This string is greater than the given string.
--*/
{
return _wcsicmp(_s + LeftPosition, String->_s);
}
INLINE
PWSTRING
WSTRING::Strupr(
)
/*++
Routine Description:
This routine uppercases this string.
Arguments:
None.
Return Value:
None.
--*/
{
#if !defined( _EFICHECK_ )
// BUGBUG there's no upcase function in the EFI library
// hopefully this won't have terrible side effects
_wcsupr(_s);
#endif
return this;
}
INLINE
PWSTRING
WSTRING::Strlwr(
)
/*++
Routine Description:
This routine lowercases this string.
Arguments:
None.
Return Value:
None.
--*/
{
#if !defined( _EFICHECK_ )
// BUGBUG no lowercase function in EFI library
// hopefully this won't result in bad side effects
_wcslwr(_s);
#endif
return this;
}
INLINE
CHNUM
WSTRING::Strchr(
IN WCHAR Char,
IN CHNUM StartPosition
) CONST
/*++
Routine Description:
This routine returns the position of the first occurance of
the given character.
Arguments:
Char - Supplies the character to find.
Return Value:
The position of the given character or INVALID_CHNUM.
--*/
{
#if !defined( _EFICHECK_ )
PWSTR p;
DebugAssert(StartPosition <= _l);
p = wcschr(_s + StartPosition, Char);
return p ? (CHNUM)(p - _s) : INVALID_CHNUM;
#else
UINT32 charnum;
for( charnum = 0; charnum <= _l; charnum++ ) {
if( _s[charnum] == Char ) {
break;
}
}
if ( charnum >= _l ) {
return INVALID_CHNUM;
} else {
return charnum;
}
#endif
}
INLINE
CHNUM
WSTRING::Strrchr(
IN WCHAR Char,
IN CHNUM StartPosition
) CONST
/*++
Routine Description:
This routine returns the position of the last occurance of
the given character.
Arguments:
Char - Supplies the character to find.
Return Value:
The position of the given character or INVALID_CHNUM.
--*/
{
#if !defined( _EFICHECK_)
PWSTR p;
p = wcsrchr(_s + StartPosition, Char);
return p ? (CHNUM)(p - _s) : INVALID_CHNUM;
#else
UINT32 charnum;
for( charnum = _l; charnum >= StartPosition; charnum-- ) {
if( _s[charnum] == Char ) {
break;
}
}
if( (CHNUM)charnum < StartPosition ) {
return INVALID_CHNUM;
} else {
return charnum;
}
#endif
}
INLINE
CHNUM
WSTRING::Strstr(
IN PCWSTRING String
) CONST
/*++
Routine Description:
This routine finds the given string withing this string.
Arguments:
String - Supplies the string to find.
Return Value:
The position of the given string in this string or INVALID_CHNUM.
--*/
{
#if !defined( _EFICHECK_ )
PWSTR p;
p = wcsstr(_s, String->_s);
return p ? (CHNUM)(p - _s) : INVALID_CHNUM;
#else
UINT32 pos;
UINT32 pos2;
UINT32 pos3;
UINT32 len;
UINT32 match = FALSE;
len = (UINT32)StrLen(String->_s);
// if the string is short than the substr, no match
if (len > _l ) {
return (CHNUM)INVALID_CHNUM;
}
// iterate from start to start - len
for (pos=0; pos < _l - len; pos++ ) {
// iterate from pos to pos+len
match = TRUE;
for(pos2 = pos,pos3=0; pos2 < pos+len; pos2++,pos3++ ) {
// if we ever get a mismatch, break and advance the start of the compare.
if(_s[pos2] != String->_s[pos3]) {
match = FALSE;
break;
}
}
if( match == TRUE ) {
return (CHNUM)pos;
}
}
return (CHNUM)INVALID_CHNUM;
#endif
}
INLINE
CHNUM
WSTRING::Strspn(
IN PCWSTRING String,
IN CHNUM StartPosition
) CONST
/*++
Routine Description:
This routine returns the position of the first character in this
string that does not belong to the set of characters in the given
string.
Arguments:
String - Supplies the list of characters to search for.
Return Value:
The position of the first character found that does not belong
to the given string.
--*/
{
#if !defined( _EFICHECK_ )
CHNUM r;
DebugAssert(StartPosition <= _l);
r = wcsspn(_s + StartPosition, String->_s) + StartPosition;
return r < _l ? r : INVALID_CHNUM;
#else
UINT32 match = FALSE;
UINT32 pos;
UINT32 pos2;
UINT32 length = (UINT32)StrLen(String->_s);
if (StartPosition > _l ) {
return INVALID_CHNUM;
}
for( pos = StartPosition; pos < _l; pos++ ) {
for( pos2 = 0; pos2 < length; pos2++) {
if( String->_s[pos2] == _s[pos] ) {
match = TRUE;
}
}
if (match == FALSE) {
break;
}
}
if (match = FALSE) {
return pos;
} else {
return INVALID_CHNUM;
}
#endif
}
INLINE
CHNUM
WSTRING::Strcspn(
IN PCWSTRING String,
IN CHNUM StartPosition
) CONST
/*++
Routine Description:
This routine returns the position of the first character in this
string that belongs to the set of characters in the given
string.
Arguments:
String - Supplies the list of characters to search for.
Return Value:
Returns the position of the first character in this string
belonging to the given string or INVALID_CHNUM.
--*/
{
#if !defined( _EFICHECK_ )
CHNUM r;
DebugAssert(StartPosition <= _l);
r = wcscspn(_s + StartPosition, String->_s) + StartPosition;
return r < _l ? r : INVALID_CHNUM;
#else
UINT32 nomatch = FALSE;
UINT32 pos;
UINT32 pos2;
UINT32 length = (UINT32)StrLen(String->_s);
if (StartPosition > _l ) {
return INVALID_CHNUM;
}
for( pos = StartPosition; pos < _l; pos++ ) {
for( pos2 = 0; pos2 < length; pos2++) {
if( String->_s[pos2] != _s[pos] ) {
nomatch = TRUE;
}
}
if (nomatch == FALSE) {
break;
}
}
if (nomatch = FALSE) {
return pos;
} else {
return INVALID_CHNUM;
}
#endif
}
INLINE
BOOLEAN
WSTRING::operator==(
IN RCWSTRING String
) CONST
{
return Stricmp(&String) == 0;
}
INLINE
BOOLEAN
WSTRING::operator!=(
IN RCWSTRING String
) CONST
{
return Stricmp(&String) != 0;
}
INLINE
BOOLEAN
WSTRING::operator<(
IN RCWSTRING String
) CONST
{
return Stricmp(&String) < 0;
}
INLINE
BOOLEAN
WSTRING::operator>(
IN RCWSTRING String
) CONST
{
return Stricmp(&String) > 0;
}
INLINE
BOOLEAN
WSTRING::operator<=(
IN RCWSTRING String
) CONST
{
return Stricmp(&String) <= 0;
}
INLINE
BOOLEAN
WSTRING::operator>=(
IN RCWSTRING String
) CONST
{
return Stricmp(&String) >= 0;
}
INLINE
CHNUM
WSTRING::Truncate(
IN CHNUM Position
)
{
DebugAssert(Position <= _l);
Resize(Position);
return _l;
}
DECLARE_CLASS( FSTRING );
class ULIB_EXPORT FSTRING : public WSTRING {
public:
DECLARE_CONSTRUCTOR( FSTRING );
NONVIRTUAL
PWSTRING
Initialize(
IN OUT PWSTR InitialString,
IN CHNUM BufferLength DEFAULT TO_END
);
VIRTUAL
BOOLEAN
Resize(
IN CHNUM NewStringLength
);
VIRTUAL
BOOLEAN
NewBuf(
IN CHNUM NewStringLength
);
private:
CHNUM _buffer_length;
};
INLINE
PWSTRING
FSTRING::Initialize(
IN OUT PWSTR InitialString,
IN CHNUM BufferLength
)
/*++
Routine Description:
This routine initializes this class with a null-terminated
unicode string. This routine does not make a copy of the string
but uses it as is.
Arguments:
NullTerminatedString - Supplies a null-terminated unicode string.
BufferLength - Supplies the buffer length.
Return Value:
A pointer to this class.
--*/
{
PutString(InitialString);
_buffer_length = ((BufferLength == TO_END) ?
(QueryChCount() + 1) : BufferLength);
return this;
}
DECLARE_CLASS( DSTRING );
class ULIB_EXPORT DSTRING : public WSTRING {
public:
DECLARE_CONSTRUCTOR( DSTRING );
VIRTUAL
~DSTRING(
);
VIRTUAL
BOOLEAN
Resize(
IN CHNUM NewStringLength
);
VIRTUAL
BOOLEAN
NewBuf(
IN CHNUM NewStringLength
);
private:
VOID
Construct(
);
PWSTR _buf; // String buffer.
CHNUM _length; // Number of characters in buffer.
};
#endif // _WSTRING_DEFN_