Beispiel #1
0
        public BucketBytes AsBytes(BucketBytes appendBytes)
        {
            if (IsEmpty)
            {
                return(appendBytes);
            }
            else if (appendBytes.IsEmpty)
            {
                return(IsEmpty ? BucketBytes.Empty : AsBytes());
            }

            if (_expected > 0)
            {
                _expected = 0;

                if (Length > 0)
                {
                    byte[] bb = (byte[])_bytes !;

                    _bytes = _bytes !.Take(Length);
                    if (Length + appendBytes.Length <= bb.Length)
                    {
                        appendBytes.CopyTo(bb.AsSpan(Length));
                        return(new BucketBytes(bb, 0, Length + appendBytes.Length));
                    }
                }
            }

            return(_bytes !.Concat(appendBytes.ToArray()).ToArray());
        }
Beispiel #2
0
        async Task <BucketBytes> DoRead(int requested)
        {
            if (_unread.Length > 0)
            {
                var bb = _unread.Slice(0, Math.Min(requested, _unread.Length));
                _unread = _unread.Slice(bb.Length);
                return(bb);
            }
            else if (_readEof)
            {
                return(BucketBytes.Eof);
            }

            int len = await Socket.ReceiveAsync(new ArraySegment <byte>(_inputBuffer), SocketFlags.None).ConfigureAwait(false);

            if (len > 0)
            {
                _bytesRead += len;
                if (len > requested)
                {
                    _unread = new BucketBytes(_inputBuffer, requested, len - requested);
                    return(new BucketBytes(_inputBuffer, 0, requested));
                }
                else
                {
                    return(new BucketBytes(_inputBuffer, 0, len));
                }
            }
            else
            {
                _readEof = true;
                return(BucketBytes.Eof);
            }
        }
Beispiel #3
0
        public static bool IsEmpty(this BucketBytes bytes, BucketEol eol)
        {
            if (bytes.IsEmpty || bytes.Length == eol.CharCount())
            {
                return(true);
            }

            return(false);
        }
        internal static Task <int> SendAsync(this Socket socket, ReadOnlyMemory <byte> buffer, SocketFlags socketFlags)
        {
            if (socket is null)
            {
                throw new ArgumentNullException(nameof(socket));
            }

            return(Task <int> .Factory.FromAsync(
                       (AsyncCallback cb, object?state) =>
            {
                var(arr, offset) = BucketBytes.ExpandToArray(buffer);

                return socket.BeginSend(arr !, offset, buffer.Length, socketFlags, cb, state);
            },
                       socket.EndSend, null));
        }
Beispiel #5
0
        public void Append(BucketBytes bytes)
        {
            if (bytes.Length == 0)
            {
                return;
            }

            if (_expected > 0)
            {
                byte[]? bb = _bytes as byte[];

                if (bytes.Length + (bb?.Length ?? 0) <= _expected)
                {
                    _bytes = bb ??= new byte[_expected];

                    bytes.CopyTo(bb.AsSpan(Length));
                    Length += bytes.Length;
                    return;
                }
                else if (Length == 0)
                {
                    _bytes    = bytes !.ToArray();
                    Length    = bytes.Length;
                    _expected = 0;
                    return;
                }
                else
                {
                    _bytes    = _bytes !.Take(Length);
                    _expected = 0;
                    // And fall through
                }
            }

            if (_bytes is null)
            {
                _bytes = bytes.ToArray();
            }
            else
            {
                _bytes = _bytes.Concat(bytes.ToArray());
            }

            Length += bytes.Length;
        }
        public static ValueTask WriteAsync(this Stream stream, BucketBytes bucketBytes, CancellationToken cancellationToken = default)
        {
            if (stream is null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

#if !NETFRAMEWORK
            return(stream.WriteAsync(bucketBytes.Memory, cancellationToken));
#else
            var(q, r) = bucketBytes;

            if (q is not null)
            {
                return(new ValueTask(stream.WriteAsync(q, r, bucketBytes.Length, cancellationToken)));
            }
            else
            {
                q = bucketBytes.ToArray();
                return(new ValueTask(stream.WriteAsync(q, 0, bucketBytes.Length, cancellationToken)));
            }
#endif
        }
Beispiel #7
0
 internal static string AsDebuggerDisplay(this BucketBytes bb) => bb.Memory.AsDebuggerDisplay();
Beispiel #8
0
        public async ValueTask <BucketBytes> ReadAsync(int readBytes)
        {
            try
            {
                if (AlreadyRead == 0)
                {
                    return(await Bucket.ReadAsync(readBytes).ConfigureAwait(false));
                }
                else if (readBytes <= AlreadyRead)
                {
                    if (readBytes < AlreadyRead)
                    {
                        throw new InvalidOperationException();
                    }

                    AlreadyRead = 0;
                    var r = Data.Slice(0, readBytes);
                    Data = Data.Slice(readBytes);
                    return(r);
                }
                else if (readBytes > Data.Length)
                {
                    byte[] returnData;

                    if (readBytes < Data.Length)
                    {
                        returnData = Data.Slice(0, readBytes).ToArray();
                    }
                    else
                    {
                        returnData = Data.ToArray();
                    }

                    int consume = readBytes - AlreadyRead;
                    int copy    = AlreadyRead;
                    AlreadyRead = 0; // No errors in Dispose please

                    var bb = await Bucket.ReadAsync(consume).ConfigureAwait(false);

                    if (bb.IsEof)
                    {
                        return(new BucketBytes(returnData, 0, copy));
                    }

                    if (copy + bb.Length <= returnData.Length)
                    {
                        return(new BucketBytes(returnData, 0, copy + bb.Length)); // Data already available from peek buffer
                    }
                    // We got new and old data, but how can we return that?
                    var(arr, offset) = bb;

                    // Unlikely, but cheap: The return buffer is what we need
                    if (arr is not null &&
                        offset >= copy &&
                        new ReadOnlySpan <byte>(arr, offset - copy, copy).SequenceEqual(returnData))
                    {
                        return(new BucketBytes(arr, offset - copy, bb.Length + copy));
                    }

                    byte[] ret = new byte[bb.Length + copy];

                    Array.Copy(returnData, ret, copy);
                    bb.Span.CopyTo(new Span <byte>(ret, copy, bb.Length));

                    return(ret);
                }
                else
                {
                    int consume = readBytes - AlreadyRead;

                    BucketBytes slicedDataCopy = Data.Slice(0, Math.Min(readBytes, Data.Length)).ToArray();

                    var bb = await Bucket.ReadAsync(consume).ConfigureAwait(false);

                    AlreadyRead = Math.Max(0, AlreadyRead - bb.Length);

                    if (bb.Length == consume)
                    {
                        return(slicedDataCopy);
                    }
                    else if (bb.Length < consume)
                    {
                        return(slicedDataCopy.Slice(0, slicedDataCopy.Length - (consume - bb.Length)));
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                }
            }
            finally
            {
                Data = BucketBytes.Empty;
            }
        }
Beispiel #9
0
 public BucketPollBytes(Bucket bucket, BucketBytes data, int alreadyRead)
 {
     Bucket      = bucket ?? throw new ArgumentNullException(nameof(bucket));
     Data        = data;
     AlreadyRead = alreadyRead;
 }
Beispiel #10
0
 public DebuggerProxy(BucketBytes bytes)
 {
     Bytes = bytes;
 }