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=54091... ============================================================================== --- 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; } }