From bdd81004f47b0927c310b354cd139d9e17f03226 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Wed, 12 Oct 2011 11:36:52 +0000 Subject: [PATCH] [RTL] - Rewrite RtlFindCharInUnicodeString. Fixes timeout in ntdll:rtlstr test. svn path=/trunk/; revision=54091 --- reactos/include/ndk/rtlfuncs.h | 2 +- reactos/include/ndk/rtltypes.h | 2 + reactos/lib/rtl/unicode.c | 131 +++++++++++++++------------------ 3 files changed, 61 insertions(+), 74 deletions(-) diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index 0204a019f0d..30a3897e175 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -2026,7 +2026,7 @@ NTSTATUS NTAPI RtlFindCharInUnicodeString( IN ULONG Flags, - IN PUNICODE_STRING SearchString, + IN PCUNICODE_STRING SearchString, IN PCUNICODE_STRING MatchString, OUT PUSHORT Position ); diff --git a/reactos/include/ndk/rtltypes.h b/reactos/include/ndk/rtltypes.h index 5f9a99d94ee..67a45b8f22e 100644 --- a/reactos/include/ndk/rtltypes.h +++ b/reactos/include/ndk/rtltypes.h @@ -242,6 +242,8 @@ C_ASSERT(HEAP_CREATE_VALID_MASK == 0x0007F0FF); // // 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 // diff --git a/reactos/lib/rtl/unicode.c b/reactos/lib/rtl/unicode.c index 8eb7b13c404..c91d04cbd81 100644 --- a/reactos/lib/rtl/unicode.c +++ b/reactos/lib/rtl/unicode.c @@ -2486,6 +2486,31 @@ RtlpEnsureBufferSize(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3) 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 @@ NTSTATUS NTAPI RtlFindCharInUnicodeString( IN ULONG Flags, - IN PUNICODE_STRING SearchString, + IN PCUNICODE_STRING SearchString, IN PCUNICODE_STRING MatchString, OUT PUSHORT Position) { - USHORT i, j; + 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; - switch (Flags) - { - case 0: - { - for (i = 0; i < SearchString->Length / sizeof(WCHAR); i++) - { - for (j = 0; j < MatchString->Length / sizeof(WCHAR); j++) - { - if (SearchString->Buffer[i] == MatchString->Buffer[j]) - { - *Position = (i + 1) * sizeof(WCHAR); - return STATUS_SUCCESS; - } - } - } + DPRINT("RtlFindCharInUnicodeString(%u, '%wZ', '%wZ', %p)\n", + Flags, SearchString, MatchString, Position); - *Position = 0; - return STATUS_NOT_FOUND; - } + /* Parameter checks */ + if (Position == NULL) + return STATUS_INVALID_PARAMETER; - case 1: - { - for (i = SearchString->Length / sizeof(WCHAR) - 1; (i + 1) > 0; i--) - { - for (j = 0; j < MatchString->Length / sizeof(WCHAR); j++) - { - if (SearchString->Buffer[i] == MatchString->Buffer[j]) - { - *Position = i * sizeof(WCHAR); - return STATUS_SUCCESS; - } - } - } + *Position = 0; - *Position = 0; - return STATUS_NOT_FOUND; - } + 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; - case 2: + /* Search */ + Length = SearchString->Length / sizeof(WCHAR); + if (Flags & RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END) + { + for (i = Length - 1; i >= 0; i--) { - for (i = 0; i < SearchString->Length / sizeof(WCHAR); i++) + Found = RtlpIsCharInUnicodeString(SearchString->Buffer[i], MatchString, CaseInSensitive); + if (Found == WantToFind) { - 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 = i * sizeof(WCHAR); + return STATUS_SUCCESS; } - - *Position = 0; - return STATUS_NOT_FOUND; } - - case 3: + } + else + { + for (i = 0; i < Length; i++) { - for (i = SearchString->Length / sizeof(WCHAR) - 1; (i + 1) > 0; i--) + Found = RtlpIsCharInUnicodeString(SearchString->Buffer[i], MatchString, CaseInSensitive); + if (Found == WantToFind) { - 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 = (i + 1) * sizeof(WCHAR); + return STATUS_SUCCESS; } - - *Position = 0; - return STATUS_NOT_FOUND; } } -- 2.17.1