SshDataStream
Specialized  MemoryStream for reading and writing data SSH data.
            
                using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Globalization;
using System.IO;
using System.Numerics;
using System.Text;
namespace Renci.SshNet.Common
{
    public class SshDataStream : MemoryStream
    {
        public bool IsEndOfData => Position >= Length;
        public SshDataStream(int capacity)
            : base(capacity)
        {
        }
        public SshDataStream(byte[] buffer)
        {
            if (buffer == null)
                throw new ArgumentNullException("buffer");
            base..ctor(buffer, 0, buffer.Length, true, true);
        }
        public SshDataStream(byte[] buffer, int offset, int count)
            : base(buffer, offset, count, true, true)
        {
        }
        private new void Write(ReadOnlySpan<byte> buffer)
        {
            byte[] array = ArrayPool<byte>.Shared.Rent(buffer.Length);
            buffer.CopyTo(array);
            Write(array, 0, buffer.Length);
            ArrayPool<byte>.Shared.Return(array, false);
        }
        public unsafe void Write(uint value)
        {
            Span<byte> span = new Span<byte>(stackalloc byte[4], 4);
            BinaryPrimitives.WriteUInt32BigEndian(span, value);
            Write(span);
        }
        public unsafe void Write(ulong value)
        {
            Span<byte> span = new Span<byte>(stackalloc byte[8], 8);
            BinaryPrimitives.WriteUInt64BigEndian(span, value);
            Write(span);
        }
        public void Write(BigInteger data)
        {
            byte[] array = Extensions.ToByteArray(data, false, true);
            WriteBinary(array, 0, array.Length);
        }
        public void Write(byte[] data)
        {
            ThrowHelper.ThrowIfNull(data, "data");
            Write(data, 0, data.Length);
        }
        public void Write(string s, Encoding encoding)
        {
            ThrowHelper.ThrowIfNull(s, "s");
            ThrowHelper.ThrowIfNull(encoding, "encoding");
            byte[] bytes = encoding.GetBytes(s);
            WriteBinary(bytes, 0, bytes.Length);
        }
        public byte[] ReadBinary()
        {
            return Extensions.ToArray(ReadBinarySegment());
        }
        internal ArraySegment<byte> ReadBinarySegment()
        {
            uint num = ReadUInt32();
            if (num > 2147483647)
                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Data longer than {0} is not supported.", 2147483647));
            ArraySegment<byte> result = Extensions.Slice(GetRemainingBuffer(), 0, (int)num);
            Position += num;
            return result;
        }
        private ArraySegment<byte> GetRemainingBuffer()
        {
            TryGetBuffer(out ArraySegment<byte> buffer);
            return Extensions.Slice(buffer, (int)Position);
        }
        public void WriteBinary(byte[] buffer)
        {
            ThrowHelper.ThrowIfNull(buffer, "buffer");
            WriteBinary(buffer, 0, buffer.Length);
        }
        public void WriteBinary(byte[] buffer, int offset, int count)
        {
            Write((uint)count);
            Write(buffer, offset, count);
        }
        public BigInteger ReadBigInt()
        {
            byte[] array = ReadBinary();
            Array.Reverse((Array)array);
            return new BigInteger(array);
        }
        public ushort ReadUInt16()
        {
            ushort result = BinaryPrimitives.ReadUInt16BigEndian(GetRemainingBuffer());
            Position += 2;
            return result;
        }
        public uint ReadUInt32()
        {
            uint result = BinaryPrimitives.ReadUInt32BigEndian(GetRemainingBuffer());
            Position += 4;
            return result;
        }
        public ulong ReadUInt64()
        {
            ulong result = BinaryPrimitives.ReadUInt64BigEndian(GetRemainingBuffer());
            Position += 8;
            return result;
        }
        public string ReadString(Encoding encoding = null)
        {
            if (encoding == null)
                encoding = Encoding.UTF8;
            ArraySegment<byte> arraySegment = ReadBinarySegment();
            return encoding.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
        }
        public override byte[] ToArray()
        {
            TryGetBuffer(out ArraySegment<byte> buffer);
            if (buffer.Offset == 0 && buffer.Count == buffer.Array.Length && buffer.Count == Length)
                return buffer.Array;
            return base.ToArray();
        }
        internal byte[] ReadBytes(int length)
        {
            byte[] array = new byte[length];
            int num = Read(array, 0, length);
            if (num < length)
                throw new ArgumentOutOfRangeException("length", string.Format(CultureInfo.InvariantCulture, "The requested length ({0}) is greater than the actual number of bytes read ({1}).", length, num));
            return array;
        }
    }
}