Пример #1
0
 public virtual unsafe int GetByteCount(ReadOnlySpan <char> chars, bool flush)
 {
     fixed(char *charsPtr = &MemoryMarshal.GetNonNullPinnableReference(chars))
     {
         return(GetByteCount(charsPtr, chars.Length, flush));
     }
 }
Пример #2
0
 public virtual unsafe int GetCharCount(ReadOnlySpan <byte> bytes, bool flush)
 {
     fixed(byte *bytesPtr = &MemoryMarshal.GetNonNullPinnableReference(bytes))
     {
         return(GetCharCount(bytesPtr, bytes.Length, flush));
     }
 }
Пример #3
0
 public override unsafe int GetCharCount(ReadOnlySpan <byte> bytes)
 {
     fixed(byte *bytesPtr = &MemoryMarshal.GetNonNullPinnableReference(bytes))
     {
         return(GetCharCount(bytesPtr, bytes.Length, decoder: null));
     }
 }
Пример #4
0
 public override unsafe int GetByteCount(ReadOnlySpan <char> chars)
 {
     fixed(char *charsPtr = &MemoryMarshal.GetNonNullPinnableReference(chars))
     {
         return(GetByteCount(charsPtr, chars.Length, encoder: null));
     }
 }
Пример #5
0
 public virtual unsafe void Convert(ReadOnlySpan <byte> bytes, Span <char> chars, bool flush, out int bytesUsed, out int charsUsed, out bool completed)
 {
     fixed(byte *bytesPtr = &MemoryMarshal.GetNonNullPinnableReference(bytes))
     fixed(char *charsPtr = &MemoryMarshal.GetNonNullPinnableReference(chars))
     {
         Convert(bytesPtr, bytes.Length, charsPtr, chars.Length, flush, out bytesUsed, out charsUsed, out completed);
     }
 }
Пример #6
0
 public unsafe virtual int GetChars(ReadOnlySpan<byte> bytes, Span<char> chars, bool flush)
 {
     fixed (byte* bytesPtr = &MemoryMarshal.GetNonNullPinnableReference(bytes))
     fixed (char* charsPtr = &MemoryMarshal.GetNonNullPinnableReference(chars))
     {
         return GetChars(bytesPtr, bytes.Length, charsPtr, chars.Length, flush);
     }
 }
Пример #7
0
        private unsafe int IcuGetHashCodeOfString(ReadOnlySpan <char> source, CompareOptions options)
        {
            Debug.Assert(!GlobalizationMode.Invariant);
            Debug.Assert(!GlobalizationMode.UseNls);
            Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);

            // according to ICU User Guide the performance of ucol_getSortKey is worse when it is called with null output buffer
            // the solution is to try to fill the sort key in a temporary buffer of size equal 4 x string length
            // (The ArrayPool used to have a limit on the length of buffers it would cache; this code was avoiding
            // exceeding that limit to avoid a per-operation allocation, and the performance implications here
            // were not re-evaluated when the limit was lifted.)
            int sortKeyLength = (source.Length > 1024 * 1024 / 4) ? 0 : 4 * source.Length;

            byte[]? borrowedArray = null;
            Span <byte> sortKey = sortKeyLength <= 1024
                ? stackalloc byte[1024]
                : (borrowedArray = ArrayPool <byte> .Shared.Rent(sortKeyLength));

            fixed(char *pSource = &MemoryMarshal.GetNonNullPinnableReference(source))
            {
                fixed(byte *pSortKey = &MemoryMarshal.GetReference(sortKey))
                {
                    sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKey.Length, options);
                }

                if (sortKeyLength > sortKey.Length) // slow path for big strings
                {
                    if (borrowedArray != null)
                    {
                        ArrayPool <byte> .Shared.Return(borrowedArray);
                    }

                    sortKey = (borrowedArray = ArrayPool <byte> .Shared.Rent(sortKeyLength));

                    fixed(byte *pSortKey = &MemoryMarshal.GetReference(sortKey))
                    {
                        sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKey.Length, options);
                    }
                }
            }

            if (sortKeyLength == 0 || sortKeyLength > sortKey.Length) // internal error (0) or a bug (2nd call failed) in ucol_getSortKey
            {
                throw new ArgumentException(SR.Arg_ExternalException);
            }

            int hash = Marvin.ComputeHash32(sortKey.Slice(0, sortKeyLength), Marvin.DefaultSeed);

            if (borrowedArray != null)
            {
                ArrayPool <byte> .Shared.Return(borrowedArray);
            }

            return(hash);
        }
Пример #8
0
        // -----------------------------
        // ---- PAL layer ends here ----
        // -----------------------------

        internal unsafe int GetHashCodeOfStringCore(ReadOnlySpan <char> source, CompareOptions options)
        {
            Debug.Assert(!GlobalizationMode.Invariant);
            Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);

            // according to ICU User Guide the performance of ucol_getSortKey is worse when it is called with null output buffer
            // the solution is to try to fill the sort key in a temporary buffer of size equal 4 x string length
            // 1MB is the biggest array that can be rented from ArrayPool.Shared without memory allocation
            int sortKeyLength = (source.Length > 1024 * 1024 / 4) ? 0 : 4 * source.Length;

            byte[]? borrowedArray = null;
            Span <byte> sortKey = sortKeyLength <= 1024
                ? stackalloc byte[1024]
                : (borrowedArray = ArrayPool <byte> .Shared.Rent(sortKeyLength));

            fixed(char *pSource = &MemoryMarshal.GetNonNullPinnableReference(source))
            {
                fixed(byte *pSortKey = &MemoryMarshal.GetReference(sortKey))
                {
                    sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKey.Length, options);
                }

                if (sortKeyLength > sortKey.Length) // slow path for big strings
                {
                    if (borrowedArray != null)
                    {
                        ArrayPool <byte> .Shared.Return(borrowedArray);
                    }

                    sortKey = (borrowedArray = ArrayPool <byte> .Shared.Rent(sortKeyLength));

                    fixed(byte *pSortKey = &MemoryMarshal.GetReference(sortKey))
                    {
                        sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKey.Length, options);
                    }
                }
            }

            if (sortKeyLength == 0 || sortKeyLength > sortKey.Length) // internal error (0) or a bug (2nd call failed) in ucol_getSortKey
            {
                throw new ArgumentException(SR.Arg_ExternalException);
            }

            int hash = Marvin.ComputeHash32(sortKey.Slice(0, sortKeyLength), Marvin.DefaultSeed);

            if (borrowedArray != null)
            {
                ArrayPool <byte> .Shared.Return(borrowedArray);
            }

            return(hash);
        }