using System; using System.Globalization; using System.IO; using System.Text; namespace Renci.SshNet.Common { public class SshDataStream : MemoryStream { public SshDataStream(int capacity) : base(capacity) { } public SshDataStream(byte[] buffer) : base(buffer) { } /// /// Gets a value indicating whether all data from the SSH data stream has been read. /// /// /// true if this instance is end of data; otherwise, false. /// public bool IsEndOfData { get { return Position >= Length; } } /// /// Writes data to the SSH data stream. /// /// data to write. public void Write(uint value) { var bytes = value.GetBytes(); Write(bytes, 0, bytes.Length); } /// /// Writes data to the SSH data stream. /// /// data to write. public void Write(ulong value) { var bytes = value.GetBytes(); Write(bytes, 0, bytes.Length); } /// /// Writes string data to the SSH data stream using the specified encoding. /// /// The string data to write. /// The character encoding to use. /// is null. /// is null. public void Write(string value, Encoding encoding) { if (value == null) throw new ArgumentNullException("value"); if (encoding == null) throw new ArgumentNullException("encoding"); var bytes = encoding.GetBytes(value); var bytesLength = bytes.Length; Write((uint) bytesLength); Write(bytes, 0, bytesLength); } /// /// Reads the next data type from the SSH data stream. /// /// /// The read from the SSH data stream. /// public uint ReadUInt32() { var data = ReadBytes(4); return (uint)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]); } /// /// Reads the next data type from the SSH data stream. /// /// /// The read from the SSH data stream. /// public ulong ReadUInt64() { var data = ReadBytes(8); return ((ulong) data[0] << 56 | (ulong) data[1] << 48 | (ulong) data[2] << 40 | (ulong) data[3] << 32 | (ulong) data[4] << 24 | (ulong) data[5] << 16 | (ulong) data[6] << 8 | data[7]); } /// /// Reads the next data type from the SSH data stream. /// /// /// The read from the SSH data stream. /// public string ReadString(Encoding encoding) { var length = ReadUInt32(); if (length > int.MaxValue) { throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Strings longer than {0} is not supported.", int.MaxValue)); } return encoding.GetString(ReadBytes((int) length), 0, (int) length); } /// /// Reads next specified number of bytes data type from internal buffer. /// /// Number of bytes to read. /// An array of bytes that was read from the internal buffer. /// is greater than the internal buffer size. private byte[] ReadBytes(int length) { var data = new byte[length]; var bytesRead = base.Read(data, 0, length); if (bytesRead < length) throw new ArgumentOutOfRangeException("length"); return data; } public override byte[] ToArray() { if (Capacity == Length) { return GetBuffer(); } return base.ToArray(); } } }