Exemple #1
0
        /// <summary>
        /// Attempts to locate the target <paramref name="value"/> within this <see cref="Utf8Span"/> instance.
        /// If <paramref name="value"/> is found, returns <see langword="true"/> and sets <paramref name="range"/> to
        /// the location where <paramref name="value"/> occurs within this <see cref="Utf8Span"/> instance.
        /// If <paramref name="value"/> is not found, returns <see langword="false"/> and sets <paramref name="range"/>
        /// to <see langword="default"/>.
        /// </summary>
        /// <remarks>
        /// An ordinal search is performed.
        /// </remarks>
        public bool TryFind(Rune value, out Range range)
        {
            if (value.IsAscii)
            {
                // Special-case ASCII since it's a simple single byte search.

                int idx = Bytes.IndexOf((byte)value.Value);
                if (idx < 0)
                {
                    range = default;
                    return(false);
                }
                else
                {
                    range = idx..(idx + 1);
                    return(true);
                }
            }
            else
            {
                // Slower path: need to search a multi-byte sequence.
                // TODO_UTF8STRING: As an optimization, we could use unsafe APIs below since we
                // know Rune instances are well-formed and slicing is safe.

                Span <byte> runeBytes            = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
                int         utf8ByteLengthOfRune = value.EncodeToUtf8(runeBytes);

                return(TryFind(UnsafeCreateWithoutValidation(runeBytes.Slice(0, utf8ByteLengthOfRune)), out range));
            }
        }
        /// <summary>
        /// Returns a value stating whether the current <see cref="Utf8Span"/> instance contains
        /// the specified <see cref="Rune"/>. An ordinal comparison is used.
        /// </summary>
        public bool Contains(Rune value)
        {
            // TODO_UTF8STRING: This should be split into two methods:
            // One which operates on a single-byte (ASCII) search value,
            // the other which operates on a multi-byte (non-ASCII) search value.

            Span <byte> runeBytes        = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
            int         runeBytesWritten = value.EncodeToUtf8(runeBytes);

            return(this.Bytes.IndexOf(runeBytes.Slice(0, runeBytesWritten)) >= 0);
        }
Exemple #3
0
        /// <summary>
        /// Attempts to locate the target <paramref name="value"/> within this <see cref="Utf8Span"/> instance.
        /// If <paramref name="value"/> is found, returns <see langword="true"/> and sets <paramref name="range"/> to
        /// the location where <paramref name="value"/> occurs within this <see cref="Utf8Span"/> instance.
        /// If <paramref name="value"/> is not found, returns <see langword="false"/> and sets <paramref name="range"/>
        /// to <see langword="default"/>.
        /// </summary>
        /// <remarks>
        /// The search is performed using the specified <paramref name="comparisonType"/>.
        /// </remarks>
        public bool TryFind(Rune value, StringComparison comparisonType, out Range range)
        {
            if (comparisonType == StringComparison.Ordinal)
            {
                return(TryFind(value, out range));
            }
            else
            {
                // Slower path: not an ordinal comparison.
                // TODO_UTF8STRING: As an optimization, we could use unsafe APIs below since we
                // know Rune instances are well-formed and slicing is safe.

                Span <byte> runeBytes            = stackalloc byte[Utf8Utility.MaxBytesPerScalar];
                int         utf8ByteLengthOfRune = value.EncodeToUtf8(runeBytes);

                return(TryFind(UnsafeCreateWithoutValidation(runeBytes.Slice(0, utf8ByteLengthOfRune)), comparisonType, out range));
            }
        }