internal static IntPtr GetCachedSortHandle(string sortName) { lock (s_sortNameToSortHandleCache) { if (!s_sortNameToSortHandleCache.TryGetValue(sortName, out IntPtr result)) { Interop.Globalization.ResultCode resultCode = Interop.Globalization.GetSortHandle(sortName, out result); if (resultCode == Interop.Globalization.ResultCode.OutOfMemory) { throw new OutOfMemoryException(); } else if (resultCode != Interop.Globalization.ResultCode.Success) { throw new ExternalException(SR.Arg_ExternalException); } try { s_sortNameToSortHandleCache.Add(sortName, result); } catch { Interop.Globalization.CloseSortHandle(result); throw; } } return(result); } }
private void InitSort(CultureInfo culture) { _sortName = culture.SortName; if (_invariantMode) { _isAsciiEqualityOrdinal = true; } else { Interop.Globalization.ResultCode resultCode = Interop.Globalization.GetSortHandle(GetNullTerminatedUtf8String(_sortName), out _sortHandle); if (resultCode != Interop.Globalization.ResultCode.Success) { _sortHandle.Dispose(); if (resultCode == Interop.Globalization.ResultCode.OutOfMemory) { throw new OutOfMemoryException(); } throw new ExternalException(SR.Arg_ExternalException); } _isAsciiEqualityOrdinal = (_sortName == "en-US" || _sortName == ""); } }
/// <summary> /// Helper for making interop calls that return a string, but we don't know /// the correct size of buffer to make. So invoke the interop call with an /// increasing buffer until the size is big enough. /// </summary> internal static bool CallStringMethod <TArg1, TArg2, TArg3>( Func <TArg1, TArg2, TArg3, StringBuilder, Interop.Globalization.ResultCode> interopCall, TArg1 arg1, TArg2 arg2, TArg3 arg3, out string result) { const int initialStringSize = 80; const int maxDoubleAttempts = 5; StringBuilder stringBuilder = StringBuilderCache.Acquire(initialStringSize); for (int i = 0; i < maxDoubleAttempts; i++) { Interop.Globalization.ResultCode resultCode = interopCall(arg1, arg2, arg3, stringBuilder); if (resultCode == Interop.Globalization.ResultCode.Success) { result = StringBuilderCache.GetStringAndRelease(stringBuilder); return(true); } else if (resultCode == Interop.Globalization.ResultCode.InsufficentBuffer) { // increase the string size and loop stringBuilder.EnsureCapacity(stringBuilder.Capacity * 2); } else { // if there is an unknown error, don't proceed break; } } StringBuilderCache.Release(stringBuilder); result = null; return(false); }