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