コード例 #1
0
 private static bool TryReadStringImpl(ReadOnlySequence <byte> sequence, out string value, ref int readSize, Decoder decoder)
 {
     value     = ReadStringImpl(sequence, decoder);
     readSize += sequence.GetIntLength();
     return(true);
 }
コード例 #2
0
        private static string ReadStringImpl(ReadOnlySequence <byte> sequence, Decoder decoder)
        {
            if (sequence.IsSingleSegment)
            {
                return(ReadStringImpl(sequence.First.Span, decoder));
            }

            var safeDecoder = decoder.GetThreadStatic();

            using (var rentedBuffer = MemoryPool <char> .Shared.Rent(sequence.GetIntLength()))
            {
                var chars    = rentedBuffer.Memory.Span;
                var length   = 0;
                var leftOver = ReadOnlySpan <byte> .Empty;

                foreach (var memory in sequence)
                {
                    if (memory.IsEmpty)
                    {
                        continue;
                    }

                    var bytes = memory.Span;
                    using (var rentedBytes = GetMemoryOwner(leftOver, bytes))
                    {
                        safeDecoder.Convert(
                            rentedBytes != null ? rentedBytes.Memory.Span : bytes,
                            chars,
                            false,
                            out var bytesUsed,
                            out var charsUsed,
                            out var completed);

                        chars   = chars.Slice(charsUsed);
                        length += charsUsed;

                        leftOver = completed ? ReadOnlySpan <byte> .Empty : bytes.Slice(bytesUsed - leftOver.Length);
                    }
                }

                if (!leftOver.IsEmpty)
                {
                    throw GetInvalidStringException();
                }

                return(rentedBuffer.Memory.Span.Slice(0, length).ToString());
            }

            IMemoryOwner <byte> GetMemoryOwner(ReadOnlySpan <byte> leftOver, ReadOnlySpan <byte> bytes)
            {
                if (leftOver.IsEmpty)
                {
                    return(null);
                }

                var owner = FixedLengthMemoryPool <byte> .Shared.Rent(leftOver.Length + bytes.Length);

                var span = owner.Memory.Span;

                leftOver.CopyTo(span);
                bytes.CopyTo(span.Slice(leftOver.Length));
                return(owner);
            }
        }