Author: tfaber
Date: Wed Oct 12 11:36:52 2011
New Revision: 54091
URL:
http://svn.reactos.org/svn/reactos?rev=54091&view=rev
Log:
[RTL]
- Rewrite RtlFindCharInUnicodeString. Fixes timeout in ntdll:rtlstr test.
Modified:
trunk/reactos/include/ndk/rtlfuncs.h
trunk/reactos/include/ndk/rtltypes.h
trunk/reactos/lib/rtl/unicode.c
Modified: trunk/reactos/include/ndk/rtlfuncs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtlfuncs.h?rev…
==============================================================================
--- trunk/reactos/include/ndk/rtlfuncs.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/rtlfuncs.h [iso-8859-1] Wed Oct 12 11:36:52 2011
@@ -2026,7 +2026,7 @@
NTAPI
RtlFindCharInUnicodeString(
IN ULONG Flags,
- IN PUNICODE_STRING SearchString,
+ IN PCUNICODE_STRING SearchString,
IN PCUNICODE_STRING MatchString,
OUT PUSHORT Position
);
Modified: trunk/reactos/include/ndk/rtltypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtltypes.h?rev…
==============================================================================
--- trunk/reactos/include/ndk/rtltypes.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/rtltypes.h [iso-8859-1] Wed Oct 12 11:36:52 2011
@@ -242,6 +242,8 @@
//
// RtlFindCharInUnicodeString Flags
//
+#define RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END 1
+#define RTL_FIND_CHAR_IN_UNICODE_STRING_COMPLEMENT_CHAR_SET 2
#define RTL_FIND_CHAR_IN_UNICODE_STRING_CASE_INSENSITIVE 4
//
Modified: trunk/reactos/lib/rtl/unicode.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/unicode.c?rev=5409…
==============================================================================
--- trunk/reactos/lib/rtl/unicode.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/unicode.c [iso-8859-1] Wed Oct 12 11:36:52 2011
@@ -2486,6 +2486,31 @@
return STATUS_NOT_IMPLEMENTED;
}
+static
+BOOLEAN
+RtlpIsCharInUnicodeString(
+ IN WCHAR Char,
+ IN PCUNICODE_STRING MatchString,
+ IN BOOLEAN CaseInSensitive)
+{
+ USHORT i;
+
+ if (CaseInSensitive)
+ Char = RtlUpcaseUnicodeChar(Char);
+
+ for (i = 0; i < MatchString->Length / sizeof(WCHAR); i++)
+ {
+ WCHAR OtherChar = MatchString->Buffer[i];
+ if (CaseInSensitive)
+ OtherChar = RtlUpcaseUnicodeChar(OtherChar);
+
+ if (Char == OtherChar)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/*
* @implemented
*/
@@ -2493,94 +2518,54 @@
NTAPI
RtlFindCharInUnicodeString(
IN ULONG Flags,
- IN PUNICODE_STRING SearchString,
+ IN PCUNICODE_STRING SearchString,
IN PCUNICODE_STRING MatchString,
OUT PUSHORT Position)
{
- USHORT i, j;
-
- switch (Flags)
- {
- case 0:
- {
- for (i = 0; i < SearchString->Length / sizeof(WCHAR); i++)
+ BOOLEAN Found;
+ const BOOLEAN WantToFind = (Flags &
RTL_FIND_CHAR_IN_UNICODE_STRING_COMPLEMENT_CHAR_SET) == 0;
+ const BOOLEAN CaseInSensitive = (Flags &
RTL_FIND_CHAR_IN_UNICODE_STRING_CASE_INSENSITIVE) != 0;
+ INT Length;
+ INT i;
+
+ DPRINT("RtlFindCharInUnicodeString(%u, '%wZ', '%wZ',
%p)\n",
+ Flags, SearchString, MatchString, Position);
+
+ /* Parameter checks */
+ if (Position == NULL)
+ return STATUS_INVALID_PARAMETER;
+
+ *Position = 0;
+
+ if (Flags & ~(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END |
+ RTL_FIND_CHAR_IN_UNICODE_STRING_COMPLEMENT_CHAR_SET |
+ RTL_FIND_CHAR_IN_UNICODE_STRING_CASE_INSENSITIVE))
+ return STATUS_INVALID_PARAMETER;
+
+ /* Search */
+ Length = SearchString->Length / sizeof(WCHAR);
+ if (Flags & RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END)
+ {
+ for (i = Length - 1; i >= 0; i--)
+ {
+ Found = RtlpIsCharInUnicodeString(SearchString->Buffer[i], MatchString,
CaseInSensitive);
+ if (Found == WantToFind)
{
- for (j = 0; j < MatchString->Length / sizeof(WCHAR); j++)
- {
- if (SearchString->Buffer[i] == MatchString->Buffer[j])
- {
- *Position = (i + 1) * sizeof(WCHAR);
- return STATUS_SUCCESS;
- }
- }
+ *Position = i * sizeof(WCHAR);
+ return STATUS_SUCCESS;
}
-
- *Position = 0;
- return STATUS_NOT_FOUND;
- }
-
- case 1:
- {
- for (i = SearchString->Length / sizeof(WCHAR) - 1; (i + 1) > 0; i--)
+ }
+ }
+ else
+ {
+ for (i = 0; i < Length; i++)
+ {
+ Found = RtlpIsCharInUnicodeString(SearchString->Buffer[i], MatchString,
CaseInSensitive);
+ if (Found == WantToFind)
{
- for (j = 0; j < MatchString->Length / sizeof(WCHAR); j++)
- {
- if (SearchString->Buffer[i] == MatchString->Buffer[j])
- {
- *Position = i * sizeof(WCHAR);
- return STATUS_SUCCESS;
- }
- }
+ *Position = (i + 1) * sizeof(WCHAR);
+ return STATUS_SUCCESS;
}
-
- *Position = 0;
- return STATUS_NOT_FOUND;
- }
-
- case 2:
- {
- for (i = 0; i < SearchString->Length / sizeof(WCHAR); i++)
- {
- j = 0;
-
- while (j < MatchString->Length / sizeof(WCHAR) &&
- SearchString->Buffer[i] != MatchString->Buffer[j])
- {
- j++;
- }
-
- if (j >= MatchString->Length / sizeof(WCHAR))
- {
- *Position = (i + 1) * sizeof(WCHAR);
- return STATUS_SUCCESS;
- }
- }
-
- *Position = 0;
- return STATUS_NOT_FOUND;
- }
-
- case 3:
- {
- for (i = SearchString->Length / sizeof(WCHAR) - 1; (i + 1) > 0; i--)
- {
- j = 0;
-
- while (j < MatchString->Length / sizeof(WCHAR) &&
- SearchString->Buffer[i] != MatchString->Buffer[j])
- {
- j++;
- }
-
- if (j >= MatchString->Length / sizeof(WCHAR))
- {
- *Position = i * sizeof(WCHAR);
- return STATUS_SUCCESS;
- }
- }
-
- *Position = 0;
- return STATUS_NOT_FOUND;
}
}