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;
}
}
}