summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorErti-Chris Eelmaa <chriseelmaa@gmail.com>2017-02-14 16:35:16 +0000
committerTarek Mahmoud Sayed <tarekms@microsoft.com>2017-02-14 08:35:16 -0800
commitd0f8481cd42e58013879326871455586a86bec6e (patch)
tree39e51171f99801e56a9e167cd56dbb1ff4d40791 /src
parent3e7d8a5deb0cb761b848e0370e57cf64b283c4f4 (diff)
downloadcoreclr-d0f8481cd42e58013879326871455586a86bec6e.tar.gz
coreclr-d0f8481cd42e58013879326871455586a86bec6e.tar.bz2
coreclr-d0f8481cd42e58013879326871455586a86bec6e.zip
Add case-insensitive String.Replace overloads (#9316)
Added overloads for String.Replace so that they now accept StringComparison and CultureInfo as input parameters.
Diffstat (limited to 'src')
-rw-r--r--src/classlibnative/inc/nlsinfo.h3
-rw-r--r--src/classlibnative/nls/nlsinfo.cpp17
-rw-r--r--src/corefx/System.Globalization.Native/collation.cpp10
-rw-r--r--src/inc/newapis.h16
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs2
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs26
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.cs4
-rw-r--r--src/mscorlib/ref/mscorlib.cs2
-rw-r--r--src/mscorlib/src/System/Globalization/CompareInfo.cs37
-rw-r--r--src/mscorlib/src/System/String.Manipulation.cs90
-rw-r--r--src/utilcode/downlevel.cpp4
-rw-r--r--src/utilcode/newapis.cpp30
12 files changed, 200 insertions, 41 deletions
diff --git a/src/classlibnative/inc/nlsinfo.h b/src/classlibnative/inc/nlsinfo.h
index 67677c7576..3c17465655 100644
--- a/src/classlibnative/inc/nlsinfo.h
+++ b/src/classlibnative/inc/nlsinfo.h
@@ -165,7 +165,8 @@ public:
__in int cchSource, // number of characters lpStringSource after sourceIndex
__in int sourceIndex, // index from where the search will start in lpStringSource
__in_ecount(cchValue) LPCWSTR lpStringValue, // the string we search for
- __in int cchValue); // length of the string we search for
+ __in int cchValue, // length of the string we search for
+ __out_opt LPINT pcchFound); // length of the string we found in source
static int QCALLTYPE InternalGetSortKey(
__in_opt INT_PTR handle, // PSORTHANDLE
diff --git a/src/classlibnative/nls/nlsinfo.cpp b/src/classlibnative/nls/nlsinfo.cpp
index 507a18b221..b43b8f6b11 100644
--- a/src/classlibnative/nls/nlsinfo.cpp
+++ b/src/classlibnative/nls/nlsinfo.cpp
@@ -2452,7 +2452,8 @@ int QCALLTYPE COMNlsInfo::InternalFindNLSStringEx(
__in int cchSource, // number of characters lpStringSource after sourceIndex
__in int sourceIndex, // index from where the search will start in lpStringSource
__in_ecount(cchValue) LPCWSTR lpStringValue, // the string we search for
- __in int cchValue) // length of the string we search for
+ __in int cchValue, // length of the string we search for
+ __out_opt LPINT pcchFound) // length of the string we found in source
{
CONTRACTL {
QCALL_CHECK;
@@ -2496,7 +2497,8 @@ int QCALLTYPE COMNlsInfo::InternalFindNLSStringEx(
lpStringValue,
cchValue,
dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION,
- dwFindNLSStringFlags & FIND_ENDSWITH);
+ dwFindNLSStringFlags & FIND_ENDSWITH,
+ pcchFound);
if (retValue >= 0)
{
retValue += sourceIndex - cchSource + 1;
@@ -2511,7 +2513,8 @@ int QCALLTYPE COMNlsInfo::InternalFindNLSStringEx(
lpStringValue,
cchValue,
dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION,
- dwFindNLSStringFlags & FIND_STARTSWITH);
+ dwFindNLSStringFlags & FIND_STARTSWITH,
+ pcchFound);
if (retValue >= 0)
{
@@ -2530,7 +2533,9 @@ int QCALLTYPE COMNlsInfo::InternalFindNLSStringEx(
&lpStringSource[sourceIndex - cchSource + 1],
cchSource,
lpStringValue,
- cchValue, NULL, NULL, NULL, (LPARAM) handle);
+ cchValue,
+ pcchFound,
+ NULL, NULL, (LPARAM) handle);
}
if (retValue >= 0)
@@ -2547,7 +2552,9 @@ int QCALLTYPE COMNlsInfo::InternalFindNLSStringEx(
&lpStringSource[sourceIndex],
cchSource,
lpStringValue,
- cchValue, NULL, NULL, NULL, (LPARAM) handle);
+ cchValue,
+ pcchFound,
+ NULL, NULL, (LPARAM) handle);
}
if (retValue >= 0)
diff --git a/src/corefx/System.Globalization.Native/collation.cpp b/src/corefx/System.Globalization.Native/collation.cpp
index f37211208e..a8c24e16ad 100644
--- a/src/corefx/System.Globalization.Native/collation.cpp
+++ b/src/corefx/System.Globalization.Native/collation.cpp
@@ -440,7 +440,8 @@ extern "C" int32_t GlobalizationNative_IndexOf(
int32_t cwTargetLength,
const UChar* lpSource,
int32_t cwSourceLength,
- int32_t options)
+ int32_t options,
+ int32_t* pMatchedLength)
{
static_assert(USEARCH_DONE == -1, "managed side requires -1 for not found");
@@ -455,6 +456,13 @@ extern "C" int32_t GlobalizationNative_IndexOf(
if (U_SUCCESS(err))
{
result = usearch_first(pSearch, &err);
+
+ // if the search was successful,
+ // we'll try to get the matched string length.
+ if(result != USEARCH_DONE && pMatchedLength != NULL)
+ {
+ *pMatchedLength = usearch_getMatchedLength(pSearch);
+ }
usearch_close(pSearch);
}
}
diff --git a/src/inc/newapis.h b/src/inc/newapis.h
index dfe77a5000..e0e6d999e1 100644
--- a/src/inc/newapis.h
+++ b/src/inc/newapis.h
@@ -288,15 +288,17 @@ namespace NewApis
__in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
__in int cchCount2, // length of pString2
__in DWORD dwFlags, // search flags
- __in BOOL startWith);
+ __in BOOL startWith,
+ __out_opt LPINT pcchFound);
int LastIndexOfString(__in LPCWSTR lpLocaleName,
- __in_ecount(cchCount1) LPCWSTR pString1, // String to search in
- __in int cchCount1, // length of pString1
- __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
- __in int cchCount2, // length of pString2
- __in DWORD dwFlags,
- __in BOOL endWith);
+ __in_ecount(cchCount1) LPCWSTR pString1, // String to search in
+ __in int cchCount1, // length of pString1
+ __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
+ __in int cchCount2, // length of pString2
+ __in DWORD dwFlags,
+ __in BOOL endWith,
+ __out_opt LPINT pcchFound);
int FindNLSStringEx(__in LPCWSTR lpLocaleName,
__in DWORD dwFindNLSStringFlags,
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
index 25585c6dfb..79aedd74d3 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
+++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
@@ -21,7 +21,7 @@ internal static partial class Interop
internal unsafe static extern int CompareString(SafeSortHandle sortHandle, char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len, CompareOptions options);
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOf")]
- internal unsafe static extern int IndexOf(SafeSortHandle sortHandle, string target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options);
+ internal unsafe static extern int IndexOf(SafeSortHandle sortHandle, string target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options, int* matchLengthPtr);
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_LastIndexOf")]
internal unsafe static extern int LastIndexOf(SafeSortHandle sortHandle, string target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options);
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs
index 21c3c9f7e4..a5232b8883 100644
--- a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs
@@ -159,30 +159,46 @@ namespace System.Globalization
}
}
- private unsafe int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
+ internal unsafe int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options, int* matchLengthPtr)
{
Debug.Assert(!string.IsNullOrEmpty(source));
Debug.Assert(target != null);
Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
+ int index;
+
if (target.Length == 0)
{
+ if(matchLengthPtr != null)
+ *matchLengthPtr = 0;
return startIndex;
}
if (options == CompareOptions.Ordinal)
{
- return IndexOfOrdinal(source, target, startIndex, count, ignoreCase: false);
+ index = IndexOfOrdinal(source, target, startIndex, count, ignoreCase: false);
+ if(index != -1)
+ {
+ if(matchLengthPtr != null)
+ *matchLengthPtr = target.Length;
+ }
+ return index;
}
if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && target.IsFastSort())
{
- return IndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options));
+ index = IndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options));
+ if(index != -1)
+ {
+ if(matchLengthPtr != null)
+ *matchLengthPtr = target.Length;
+ }
+ return index;
}
-
+
fixed (char* pSource = source)
{
- int index = Interop.GlobalizationInterop.IndexOf(_sortHandle, target, target.Length, pSource + startIndex, count, options);
+ index = Interop.GlobalizationInterop.IndexOf(_sortHandle, target, target.Length, pSource + startIndex, count, options, matchLengthPtr);
return index != -1 ? index + startIndex : -1;
}
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.cs
index 64dbfe84f7..94cfcad709 100644
--- a/src/mscorlib/corefx/System/Globalization/CompareInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/CompareInfo.cs
@@ -694,7 +694,7 @@ namespace System.Globalization
if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal))
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
- return IndexOfCore(source, new string(value, 1), startIndex, count, options);
+ return IndexOfCore(source, new string(value, 1), startIndex, count, options, null);
}
@@ -741,7 +741,7 @@ namespace System.Globalization
if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal))
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
- return IndexOfCore(source, value, startIndex, count, options);
+ return IndexOfCore(source, value, startIndex, count, options, null);
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/mscorlib/ref/mscorlib.cs b/src/mscorlib/ref/mscorlib.cs
index 680bf20675..945e9689da 100644
--- a/src/mscorlib/ref/mscorlib.cs
+++ b/src/mscorlib/ref/mscorlib.cs
@@ -3245,6 +3245,8 @@ namespace System
[System.Security.SecuritySafeCriticalAttribute]
public System.String Replace(char oldChar, char newChar) { throw null; }
public System.String Replace(System.String oldValue, System.String newValue) { throw null; }
+ public System.String Replace(System.String oldValue, System.String newValue, System.StringComparison comparison) { throw null; }
+ public System.String Replace(System.String oldValue, System.String newValue, System.Boolean ignoreCase, System.Globalization.CultureInfo cultureInfo) { throw null; }
[System.Runtime.InteropServices.ComVisibleAttribute(false)]
public string[] Split(char separator, int count, System.StringSplitOptions options = (System.StringSplitOptions)(0)) { throw null; }
[System.Runtime.InteropServices.ComVisibleAttribute(false)]
diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.cs b/src/mscorlib/src/System/Globalization/CompareInfo.cs
index 6c2230b66b..dac7b0bf4e 100644
--- a/src/mscorlib/src/System/Globalization/CompareInfo.cs
+++ b/src/mscorlib/src/System/Globalization/CompareInfo.cs
@@ -564,11 +564,11 @@ namespace System.Globalization {
// to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to
// the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString.
-
return (InternalFindNLSStringEx(
m_dataHandle, m_handleOrigin, m_sortName,
GetNativeCompareFlags(options) | Win32Native.FIND_STARTSWITH | ((source.IsAscii() && prefix.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0),
- source, source.Length, 0, prefix, prefix.Length) > -1);
+ source, source.Length, 0, prefix, prefix.Length,
+ null) > -1);
}
public virtual bool IsPrefix(String source, String prefix)
@@ -618,7 +618,7 @@ namespace System.Globalization {
return InternalFindNLSStringEx(
m_dataHandle, m_handleOrigin, m_sortName,
GetNativeCompareFlags(options) | Win32Native.FIND_ENDSWITH | ((source.IsAscii() && suffix.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0),
- source, source.Length, source.Length - 1, suffix, suffix.Length) >= 0;
+ source, source.Length, source.Length - 1, suffix, suffix.Length, null) >= 0;
}
@@ -760,12 +760,16 @@ namespace System.Globalization {
return InternalFindNLSStringEx(
m_dataHandle, m_handleOrigin, m_sortName,
GetNativeCompareFlags(options) | Win32Native.FIND_FROMSTART | ((source.IsAscii() && (value <= '\x007f')) ? RESERVED_FIND_ASCII_STRING : 0),
- source, count, startIndex, new String(value, 1), 1);
+ source, count, startIndex, new String(value, 1), 1, null);
}
-
public unsafe virtual int IndexOf(String source, String value, int startIndex, int count, CompareOptions options)
{
+ return IndexOfCore(source, value, startIndex, count, options, null);
+ }
+
+ internal unsafe int IndexOfCore(String source, String value, int startIndex, int count, CompareOptions options, int* matchLengthPtr)
+ {
// Validate inputs
if (source == null)
throw new ArgumentNullException(nameof(source));
@@ -784,6 +788,8 @@ namespace System.Globalization {
{
if (value.Length == 0)
{
+ if(matchLengthPtr != null)
+ *matchLengthPtr = 0;
return 0;
}
return -1;
@@ -795,11 +801,17 @@ namespace System.Globalization {
}
if (count < 0 || startIndex > source.Length - count)
- throw new ArgumentOutOfRangeException(nameof(count),Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
if (options == CompareOptions.OrdinalIgnoreCase)
{
- return source.IndexOf(value, startIndex, count, StringComparison.OrdinalIgnoreCase);
+ int index = source.IndexOf(value, startIndex, count, StringComparison.OrdinalIgnoreCase);
+ if (index != -1)
+ {
+ if(matchLengthPtr != null)
+ *matchLengthPtr = value.Length;
+ }
+ return index;
}
// Validate CompareOptions
@@ -810,9 +822,9 @@ namespace System.Globalization {
// to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to
// the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString.
return InternalFindNLSStringEx(
- m_dataHandle, m_handleOrigin, m_sortName,
+ m_dataHandle, m_handleOrigin, m_sortName,
GetNativeCompareFlags(options) | Win32Native.FIND_FROMSTART | ((source.IsAscii() && value.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0),
- source, count, startIndex, value, value.Length);
+ source, count, startIndex, value, value.Length, matchLengthPtr);
}
////////////////////////////////////////////////////////////////////////
@@ -956,7 +968,7 @@ namespace System.Globalization {
return InternalFindNLSStringEx(
m_dataHandle, m_handleOrigin, m_sortName,
GetNativeCompareFlags(options) | Win32Native.FIND_FROMEND | ((source.IsAscii() && (value <= '\x007f')) ? RESERVED_FIND_ASCII_STRING : 0),
- source, count, startIndex, new String(value, 1), 1);
+ source, count, startIndex, new String(value, 1), 1, null);
}
@@ -1010,7 +1022,7 @@ namespace System.Globalization {
return InternalFindNLSStringEx(
m_dataHandle, m_handleOrigin, m_sortName,
GetNativeCompareFlags(options) | Win32Native.FIND_FROMEND | ((source.IsAscii() && value.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0),
- source, count, startIndex, value, value.Length);
+ source, count, startIndex, value, value.Length, null);
}
@@ -1292,7 +1304,8 @@ namespace System.Globalization {
// Call through to NewApis::FindNLSStringEx so we can get the right behavior
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
- private static extern int InternalFindNLSStringEx(IntPtr handle, IntPtr handleOrigin, String localeName, int flags, String source, int sourceCount, int startIndex, string target, int targetCount);
+ private unsafe static extern int InternalFindNLSStringEx(IntPtr handle, IntPtr handleOrigin, String localeName, int flags, String source, int sourceCount, int startIndex, string target, int targetCount, int* matchLengthPtr);
+
// Call through to NewAPis::LCMapStringEx so we can get appropriate behavior for all platforms
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
diff --git a/src/mscorlib/src/System/String.Manipulation.cs b/src/mscorlib/src/System/String.Manipulation.cs
index e06141d669..5a9be5c248 100644
--- a/src/mscorlib/src/System/String.Manipulation.cs
+++ b/src/mscorlib/src/System/String.Manipulation.cs
@@ -946,7 +946,95 @@ namespace System
Contract.EndContractBlock();
return Substring(0, startIndex);
- }
+ }
+
+ public string Replace(string oldValue, string newValue, bool ignoreCase, CultureInfo culture)
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ Contract.EndContractBlock();
+
+ return ReplaceCore(oldValue, newValue, culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);
+ }
+
+ public string Replace(string oldValue, string newValue, StringComparison comparisonType)
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ Contract.EndContractBlock();
+
+ switch (comparisonType)
+ {
+ case StringComparison.CurrentCulture:
+ return ReplaceCore(oldValue, newValue, CultureInfo.CurrentCulture, CompareOptions.None);
+
+ case StringComparison.CurrentCultureIgnoreCase:
+ return ReplaceCore(oldValue, newValue, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase);
+
+ case StringComparison.InvariantCulture:
+ return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.None);
+
+ case StringComparison.InvariantCultureIgnoreCase:
+ return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase);
+
+ case StringComparison.Ordinal:
+ return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.Ordinal);
+
+ case StringComparison.OrdinalIgnoreCase:
+ return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.OrdinalIgnoreCase);
+
+ default:
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
+ }
+ }
+
+ private unsafe String ReplaceCore(string oldValue, string newValue, CultureInfo culture, CompareOptions options)
+ {
+ if (oldValue == null)
+ throw new ArgumentNullException(nameof(oldValue));
+
+ // If they asked to replace oldValue with a null, replace all occurences
+ // with the empty string.
+ if (newValue == null)
+ newValue = string.Empty;
+
+ CultureInfo referenceCulture = culture ?? CultureInfo.CurrentCulture;
+ StringBuilder result = StringBuilderCache.Acquire();
+
+ int startIndex = 0;
+ int index = 0;
+
+ int matchLength = 0;
+
+ bool hasDoneAnyReplacements = false;
+
+ do
+ {
+ index = referenceCulture.CompareInfo.IndexOfCore(this, oldValue, startIndex, m_stringLength - startIndex, options, &matchLength);
+ if (index >= 0)
+ {
+ // append the unmodified portion of string
+ result.Append(this, startIndex, index - startIndex);
+
+ // append the replacement
+ result.Append(newValue);
+
+ startIndex = index + matchLength;
+ hasDoneAnyReplacements = true;
+ }
+ else if (!hasDoneAnyReplacements)
+ {
+ // small optimization,
+ // if we have not done any replacements,
+ // we will return the original string
+ return this;
+ }
+ else
+ {
+ result.Append(this, startIndex, m_stringLength - startIndex);
+ }
+ } while (index >= 0);
+
+ return StringBuilderCache.GetStringAndRelease(result);
+ }
// Replaces all instances of oldChar with newChar.
//
diff --git a/src/utilcode/downlevel.cpp b/src/utilcode/downlevel.cpp
index ec8d3f5a15..6ff7b82815 100644
--- a/src/utilcode/downlevel.cpp
+++ b/src/utilcode/downlevel.cpp
@@ -1924,11 +1924,11 @@ namespace DownLevel
if (dwFindNLSStringFlags & (FIND_ENDSWITH | FIND_FROMEND))
{
- retValue = NewApis::LastIndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_ENDSWITH);
+ retValue = NewApis::LastIndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_ENDSWITH, pcchFound);
}
else
{
- retValue = NewApis::IndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_STARTSWITH);
+ retValue = NewApis::IndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_STARTSWITH, pcchFound);
}
return retValue;
}
diff --git a/src/utilcode/newapis.cpp b/src/utilcode/newapis.cpp
index c05d024b7e..599197c944 100644
--- a/src/utilcode/newapis.cpp
+++ b/src/utilcode/newapis.cpp
@@ -754,12 +754,14 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
int IndexOfString( __in LPCWSTR lpLocaleName,
__in_ecount(cchCount1) LPCWSTR pString1, // String to search in
__in int cchCount1, // length of pString1
- __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
+ __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
__in int cchCount2, // length of pString2
__in DWORD dwFlags, // search flags
- __in BOOL startWith) // true if we need to check for prefix case
+ __in BOOL startWith, // true if we need to check for prefix case
+ __out_opt LPINT pcchFound) // length of the string we found in source
{
int iRetVal = -1;
+ int foundLengthInSource = 0;
//
// Check the ranges.
@@ -788,6 +790,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
if (dwFlags == COMPARE_OPTIONS_ORDINAL)
{
iRetVal = FastIndexOfString(pString1, cchCount1, pString2, cchCount2);
+ foundLengthInSource = cchCount2;
goto lExit;
}
//For dwFlags, 0 is the default, 1 is ignore case, we can handle both.
@@ -801,6 +804,11 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
iRetVal = FastIndexOfString(pString1, cchCount1, pString2, cchCount2);
else
iRetVal = FastIndexOfStringInsensitive(pString1, cchCount1, pString2, cchCount2);
+
+ // both are ascii strings,
+ // the length should be the same as the length of the string we are searching for.
+ foundLengthInSource = cchCount2;
+
goto lExit;
}
}
@@ -832,6 +840,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
if (result == CSTR_EQUAL)
{
iRetVal = iOffset;
+ foundLengthInSource = iLength;
break;
}
else if (result == 0)
@@ -848,6 +857,9 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
{
iRetVal = -1;
}
+
+ if(iRetVal != -1 && pcchFound != NULL)
+ *pcchFound = foundLengthInSource;
return iRetVal;
}
@@ -859,13 +871,16 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
int LastIndexOfString( __in LPCWSTR lpLocaleName,
__in_ecount(cchCount1) LPCWSTR pString1, // String to search in
__in int cchCount1, // length of pString1
- __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
+ __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
__in int cchCount2, // length of pString2
__in DWORD dwFlags,
- __in BOOL endWith) // check suffix case
+ __in BOOL endWith, // check suffix case
+ __out_opt LPINT pcchFound) // length of the string we found in source
{
INT32 iRetVal = -1;
BOOL comparedOrdinal = FALSE;
+
+ int foundLengthInSource = 0;
// Check for empty strings
if (cchCount1 == 0)
@@ -896,6 +911,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
{
iRetVal = FastLastIndexOfString(pString1, cchCount1, pString2, cchCount2);
comparedOrdinal = TRUE;
+ foundLengthInSource = cchCount2;
goto lExit;
}
@@ -910,6 +926,8 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
else
iRetVal = FastLastIndexOfStringInsensitive(pString1, cchCount1, pString2, cchCount2);
comparedOrdinal = TRUE;
+
+ foundLengthInSource = cchCount2;
goto lExit;
}
}
@@ -923,6 +941,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
if (NewApis::CompareStringEx(lpLocaleName, dwFlags, pString2, cchCount2, &pString1[cchCount1 + iOffset - iLength], iLength, NULL, NULL, 0) == CSTR_EQUAL)
{
iRetVal= cchCount1 + iOffset - iLength;
+ foundLengthInSource = iLength;
break;
}
}
@@ -940,6 +959,9 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
iRetVal = -1;
}
}
+
+ if(iRetVal != -1 && pcchFound != NULL)
+ *pcchFound = foundLengthInSource;
return iRetVal;
}