protected internal override ReadOnlySequence <byte> _GetSequence(int index, int count)
        {
            if (0u >= (uint)count)
            {
                return(ReadOnlySequence <byte> .Empty);
            }

            var c = FindComponent(index);

            if (c == FindComponent(index + count - 1))
            {
                return(c.GetSequence(index - c.Offset, count));
            }
            var array = ThreadLocalList <ReadOnlyMemory <byte> > .NewInstance(_nioBufferCount);

            try
            {
                int i          = c.Index;
                int adjustment = c.Offset;
                var s          = c.Buf;
                for (; ;)
                {
                    int localLength = Math.Min(count, s.ReadableBytes - (index - adjustment));
                    switch (s.IoBufferCount)
                    {
                    case 0:
                        ThrowHelper.ThrowNotSupportedException();
                        break;

                    case 1:
                        array.Add(s.GetReadableMemory(index - adjustment, localLength));
                        break;

                    default:
                        var sequence = s.GetSequence(index - adjustment, localLength);
                        foreach (var memory in sequence)
                        {
                            array.Add(memory);
                        }
                        break;
                    }

                    index      += localLength;
                    count      -= localLength;
                    adjustment += s.ReadableBytes;
                    if ((uint)(count - 1) > SharedConstants.TooBigOrNegative) // count <= 0
                    {
                        break;
                    }
                    s = Buffer(++i);
                }

                return(ReadOnlyBufferSegment.Create(array));
            }
            finally
            {
                array.Return();
            }
        }
        protected internal override ReadOnlySequence <byte> _GetSequence(int index, int count)
        {
            if (0u >= (uint)count)
            {
                return(ReadOnlySequence <byte> .Empty);
            }

            var buffers = ThreadLocalList <ReadOnlyMemory <byte> > .NewInstance(_componentCount);

            try
            {
                int i = ToComponentIndex0(index);
                while (count > 0)
                {
                    ComponentEntry c           = _components[i];
                    IByteBuffer    s           = c.Buffer;
                    int            localLength = Math.Min(count, c.EndOffset - index);
                    switch (s.IoBufferCount)
                    {
                    case 0:
                        ThrowHelper.ThrowNotSupportedException();
                        break;

                    case 1:
                        if (s.IsSingleIoBuffer)
                        {
                            buffers.Add(s.GetReadableMemory(c.Idx(index), localLength));
                        }
                        else
                        {
                            var sequence0 = s.GetSequence(c.Idx(index), localLength);
                            foreach (var memory in sequence0)
                            {
                                buffers.Add(memory);
                            }
                        }
                        break;

                    default:
                        var sequence = s.GetSequence(c.Idx(index), localLength);
                        foreach (var memory in sequence)
                        {
                            buffers.Add(memory);
                        }
                        break;
                    }

                    index += localLength;
                    count -= localLength;
                    i++;
                }

                return(ReadOnlyBufferSegment.Create(buffers));
            }
            finally
            {
                buffers.Return();
            }
        }
예제 #3
0
        public static Task WriteAndFlushManyAsync(this IChannelHandlerContext context, ICollection <object> messages)
        {
            if (messages is null || 0u >= (uint)messages.Count)
            {
                return(TaskUtil.Completed);
            }

            var taskList = ThreadLocalList <Task> .NewInstance();

            foreach (object m in messages)
            {
                taskList.Add(context.WriteAsync(m));
            }
            context.Flush();

            var writeCloseCompletion = Task.WhenAll(taskList);

            writeCloseCompletion.ContinueWith(s_returnAfterWriteAction, taskList, TaskContinuationOptions.ExecuteSynchronously);
            return(writeCloseCompletion);
        }