|
|
@@ -1,8 +1,5 @@
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
-#if !TUNING
|
|
|
-using System.Linq;
|
|
|
-#endif
|
|
|
using System.Text;
|
|
|
|
|
|
namespace Renci.SshNet.Common
|
|
|
@@ -17,44 +14,29 @@ namespace Renci.SshNet.Common
|
|
|
internal static readonly Encoding Ascii = new ASCIIEncoding();
|
|
|
internal static readonly Encoding Utf8 = Encoding.UTF8;
|
|
|
|
|
|
-#if TUNING
|
|
|
private SshDataStream _stream;
|
|
|
|
|
|
protected SshDataStream DataStream
|
|
|
{
|
|
|
get { return _stream; }
|
|
|
}
|
|
|
-#else
|
|
|
- /// <summary>
|
|
|
- /// Data byte array that hold message unencrypted data
|
|
|
- /// </summary>
|
|
|
- private List<byte> _data;
|
|
|
-
|
|
|
- private int _readerIndex;
|
|
|
-#endif
|
|
|
|
|
|
/// <summary>
|
|
|
/// Gets a value indicating whether all data from the buffer has been read.
|
|
|
/// </summary>
|
|
|
/// <value>
|
|
|
- /// <c>true</c> if this instance is end of data; otherwise, <c>false</c>.
|
|
|
+ /// <c>true</c> if this instance is end of data; otherwise, <c>false</c>.
|
|
|
/// </value>
|
|
|
protected bool IsEndOfData
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
-#if TUNING
|
|
|
return _stream.Position >= _stream.Length;
|
|
|
-#else
|
|
|
- return _readerIndex >= _data.Count();
|
|
|
-#endif
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private byte[] _loadedData;
|
|
|
-#if TUNING
|
|
|
private int _offset;
|
|
|
-#endif
|
|
|
|
|
|
/// <summary>
|
|
|
/// Gets the index that represents zero in current data type.
|
|
|
@@ -70,7 +52,6 @@ namespace Renci.SshNet.Common
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#if TUNING
|
|
|
/// <summary>
|
|
|
/// Gets the size of the message in bytes.
|
|
|
/// </summary>
|
|
|
@@ -81,34 +62,20 @@ namespace Renci.SshNet.Common
|
|
|
{
|
|
|
get { return 0; }
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
/// <summary>
|
|
|
/// Gets data bytes array
|
|
|
/// </summary>
|
|
|
/// <returns>Byte array representation of data structure.</returns>
|
|
|
- public
|
|
|
-#if !TUNING
|
|
|
- virtual
|
|
|
-#endif
|
|
|
- byte[] GetBytes()
|
|
|
+ public byte[] GetBytes()
|
|
|
{
|
|
|
-#if TUNING
|
|
|
var messageLength = BufferCapacity;
|
|
|
var capacity = messageLength != -1 ? messageLength : DefaultCapacity;
|
|
|
var dataStream = new SshDataStream(capacity);
|
|
|
WriteBytes(dataStream);
|
|
|
return dataStream.ToArray();
|
|
|
-#else
|
|
|
- _data = new List<byte>();
|
|
|
-
|
|
|
- SaveData();
|
|
|
-
|
|
|
- return _data.ToArray();
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
-#if TUNING
|
|
|
/// <summary>
|
|
|
/// Writes the current message to the specified <see cref="SshDataStream"/>.
|
|
|
/// </summary>
|
|
|
@@ -118,16 +85,11 @@ namespace Renci.SshNet.Common
|
|
|
_stream = stream;
|
|
|
SaveData();
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
internal T OfType<T>() where T : SshData, new()
|
|
|
{
|
|
|
var result = new T();
|
|
|
-#if TUNING
|
|
|
result.LoadBytes(_loadedData, _offset);
|
|
|
-#else
|
|
|
- result.LoadBytes(_loadedData);
|
|
|
-#endif
|
|
|
result.LoadData();
|
|
|
return result;
|
|
|
}
|
|
|
@@ -139,18 +101,9 @@ namespace Renci.SshNet.Common
|
|
|
/// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
|
|
|
public void Load(byte[] value)
|
|
|
{
|
|
|
-#if TUNING
|
|
|
Load(value, 0);
|
|
|
-#else
|
|
|
- if (value == null)
|
|
|
- throw new ArgumentNullException("value");
|
|
|
-
|
|
|
- LoadBytes(value);
|
|
|
- LoadData();
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
-#if TUNING
|
|
|
/// <summary>
|
|
|
/// Loads data from the specified buffer.
|
|
|
/// </summary>
|
|
|
@@ -162,7 +115,6 @@ namespace Renci.SshNet.Common
|
|
|
LoadBytes(value, offset);
|
|
|
LoadData();
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
/// <summary>
|
|
|
/// Called when type specific data need to be loaded.
|
|
|
@@ -181,21 +133,9 @@ namespace Renci.SshNet.Common
|
|
|
/// <exception cref="ArgumentNullException"><paramref name="bytes"/> is null.</exception>
|
|
|
protected void LoadBytes(byte[] bytes)
|
|
|
{
|
|
|
-#if TUNING
|
|
|
LoadBytes(bytes, 0);
|
|
|
-#else
|
|
|
- // Note about why I check for null here, and in Load(byte[]) in this class.
|
|
|
- // This method is called by several other classes, such as SshNet.Messages.Message, SshNet.Sftp.SftpMessage.
|
|
|
- if (bytes == null)
|
|
|
- throw new ArgumentNullException("bytes");
|
|
|
-
|
|
|
- ResetReader();
|
|
|
- _loadedData = bytes;
|
|
|
- _data = new List<byte>(bytes);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
-#if TUNING
|
|
|
/// <summary>
|
|
|
/// Loads data bytes into internal buffer.
|
|
|
/// </summary>
|
|
|
@@ -213,49 +153,25 @@ namespace Renci.SshNet.Common
|
|
|
_stream = new SshDataStream(bytes);
|
|
|
ResetReader();
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
/// <summary>
|
|
|
/// Resets internal data reader index.
|
|
|
/// </summary>
|
|
|
protected void ResetReader()
|
|
|
{
|
|
|
-#if TUNING
|
|
|
_stream.Position = ZeroReaderIndex + _offset;
|
|
|
-#else
|
|
|
- _readerIndex = ZeroReaderIndex; // Set to 1 to skip first byte which specifies message type
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
-#if !TUNING
|
|
|
- /// <summary>
|
|
|
- /// Reads next mpint data type from internal buffer.
|
|
|
- /// </summary>
|
|
|
- /// <returns>mpint read.</returns>
|
|
|
- protected BigInteger ReadBigInt()
|
|
|
- {
|
|
|
- var length = this.ReadUInt32();
|
|
|
- var data = this.ReadBytes((int)length);
|
|
|
- return new BigInteger(data.Reverse().ToArray());
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// Reads all data left in internal buffer at current position.
|
|
|
/// </summary>
|
|
|
/// <returns>An array of bytes containing the remaining data in the internal buffer.</returns>
|
|
|
protected byte[] ReadBytes()
|
|
|
{
|
|
|
-#if TUNING
|
|
|
var bytesLength = (int) (_stream.Length - _stream.Position);
|
|
|
var data = new byte[bytesLength];
|
|
|
_stream.Read(data, 0, bytesLength);
|
|
|
return data;
|
|
|
-#else
|
|
|
- var data = new byte[_data.Count - _readerIndex];
|
|
|
- _data.CopyTo(_readerIndex, data, 0, data.Length);
|
|
|
- return data;
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -270,7 +186,6 @@ namespace Renci.SshNet.Common
|
|
|
// For the nerds, the condition translates to: if (length > data.Count && length < int.MaxValue)
|
|
|
// Which probably would cause all sorts of exception, most notably OutOfMemoryException.
|
|
|
|
|
|
-#if TUNING
|
|
|
var data = new byte[length];
|
|
|
var bytesRead = _stream.Read(data, 0, length);
|
|
|
|
|
|
@@ -278,15 +193,6 @@ namespace Renci.SshNet.Common
|
|
|
throw new ArgumentOutOfRangeException("length");
|
|
|
|
|
|
return data;
|
|
|
-#else
|
|
|
- if (length > _data.Count)
|
|
|
- throw new ArgumentOutOfRangeException("length");
|
|
|
-
|
|
|
- var result = new byte[length];
|
|
|
- _data.CopyTo(_readerIndex, result, 0, length);
|
|
|
- _readerIndex += length;
|
|
|
- return result;
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -295,14 +201,10 @@ namespace Renci.SshNet.Common
|
|
|
/// <returns>Byte read.</returns>
|
|
|
protected byte ReadByte()
|
|
|
{
|
|
|
-#if TUNING
|
|
|
var byteRead = _stream.ReadByte();
|
|
|
if (byteRead == -1)
|
|
|
throw new InvalidOperationException("Attempt to read past the end of the SSH data stream.");
|
|
|
return (byte) byteRead;
|
|
|
-#else
|
|
|
- return ReadBytes(1).FirstOrDefault();
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -344,23 +246,6 @@ namespace Renci.SshNet.Common
|
|
|
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]);
|
|
|
}
|
|
|
|
|
|
-#if !TUNING
|
|
|
- /// <summary>
|
|
|
- /// Reads next string data type from internal buffer.
|
|
|
- /// </summary>
|
|
|
- /// <returns>string read</returns>
|
|
|
- protected string ReadAsciiString()
|
|
|
- {
|
|
|
- var length = ReadUInt32();
|
|
|
-
|
|
|
- if (length > int.MaxValue)
|
|
|
- {
|
|
|
- throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Strings longer than {0} is not supported.", int.MaxValue));
|
|
|
- }
|
|
|
- return Ascii.GetString(ReadBytes((int)length), 0, (int)length);
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// Reads next string data type from internal buffer using the specific encoding.
|
|
|
/// </summary>
|
|
|
@@ -369,20 +254,9 @@ namespace Renci.SshNet.Common
|
|
|
/// </returns>
|
|
|
protected string ReadString(Encoding encoding)
|
|
|
{
|
|
|
-#if TUNING
|
|
|
return _stream.ReadString(encoding);
|
|
|
-#else
|
|
|
- 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);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
-#if TUNING
|
|
|
/// <summary>
|
|
|
/// Reads next data type as byte array from internal buffer.
|
|
|
/// </summary>
|
|
|
@@ -393,28 +267,13 @@ namespace Renci.SshNet.Common
|
|
|
{
|
|
|
return _stream.ReadBinary();
|
|
|
}
|
|
|
-#else
|
|
|
- /// <summary>
|
|
|
- /// Reads next string data type from internal buffer.
|
|
|
- /// </summary>
|
|
|
- /// <returns>string read</returns>
|
|
|
- protected byte[] ReadBinaryString()
|
|
|
- {
|
|
|
- var length = ReadUInt32();
|
|
|
-
|
|
|
- if (length > int.MaxValue)
|
|
|
- {
|
|
|
- throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Strings longer than {0} is not supported.", int.MaxValue));
|
|
|
- }
|
|
|
-
|
|
|
- return ReadBytes((int)length);
|
|
|
- }
|
|
|
-#endif
|
|
|
|
|
|
/// <summary>
|
|
|
/// Reads next name-list data type from internal buffer.
|
|
|
/// </summary>
|
|
|
- /// <returns>String array or read data..</returns>
|
|
|
+ /// <returns>
|
|
|
+ /// String array or read data.
|
|
|
+ /// </returns>
|
|
|
protected string[] ReadNamesList()
|
|
|
{
|
|
|
var namesList = ReadString(Ascii);
|
|
|
@@ -437,7 +296,6 @@ namespace Renci.SshNet.Common
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-#if TUNING
|
|
|
/// <summary>
|
|
|
/// Writes bytes array data into internal buffer.
|
|
|
/// </summary>
|
|
|
@@ -447,19 +305,7 @@ namespace Renci.SshNet.Common
|
|
|
{
|
|
|
_stream.Write(data);
|
|
|
}
|
|
|
-#else
|
|
|
- /// <summary>
|
|
|
- /// Writes bytes array data into internal buffer.
|
|
|
- /// </summary>
|
|
|
- /// <param name="data">Byte array data to write.</param>
|
|
|
- /// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
|
|
|
- protected void Write(IEnumerable<byte> data)
|
|
|
- {
|
|
|
- _data.AddRange(data);
|
|
|
- }
|
|
|
-#endif
|
|
|
|
|
|
-#if TUNING
|
|
|
/// <summary>
|
|
|
/// Writes a sequence of bytes to the current SSH data stream and advances the current position
|
|
|
/// within this stream by the number of bytes written.
|
|
|
@@ -474,71 +320,47 @@ namespace Renci.SshNet.Common
|
|
|
{
|
|
|
_stream.Write(buffer, offset, count);
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Writes byte data into internal buffer.
|
|
|
+ /// Writes <see cref="byte"/> data into internal buffer.
|
|
|
/// </summary>
|
|
|
- /// <param name="data">Byte data to write.</param>
|
|
|
+ /// <param name="data"><see cref="byte"/> data to write.</param>
|
|
|
protected void Write(byte data)
|
|
|
{
|
|
|
-#if TUNING
|
|
|
_stream.WriteByte(data);
|
|
|
-#else
|
|
|
- _data.Add(data);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Writes boolean data into internal buffer.
|
|
|
+ /// Writes <see cref="bool"/> into internal buffer.
|
|
|
/// </summary>
|
|
|
- /// <param name="data">Boolean data to write.</param>
|
|
|
+ /// <param name="data"><see cref="bool" /> data to write.</param>
|
|
|
protected void Write(bool data)
|
|
|
{
|
|
|
Write(data ? (byte) 1 : (byte) 0);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Writes uint32 data into internal buffer.
|
|
|
+ /// Writes <see cref="uint"/> data into internal buffer.
|
|
|
/// </summary>
|
|
|
- /// <param name="data">uint32 data to write.</param>
|
|
|
+ /// <param name="data"><see cref="uint"/> data to write.</param>
|
|
|
protected void Write(uint data)
|
|
|
{
|
|
|
-#if TUNING
|
|
|
_stream.Write(data);
|
|
|
-#else
|
|
|
- Write(data.GetBytes());
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Writes uint64 data into internal buffer.
|
|
|
+ /// Writes <see cref="ulong" /> data into internal buffer.
|
|
|
/// </summary>
|
|
|
- /// <param name="data">uint64 data to write.</param>
|
|
|
+ /// <param name="data"><see cref="ulong"/> data to write.</param>
|
|
|
protected void Write(ulong data)
|
|
|
{
|
|
|
-#if TUNING
|
|
|
_stream.Write(data);
|
|
|
-#else
|
|
|
- Write(data.GetBytes());
|
|
|
-#endif
|
|
|
- }
|
|
|
-
|
|
|
-#if !TUNING
|
|
|
- /// <summary>
|
|
|
- /// Writes string data into internal buffer as ASCII.
|
|
|
- /// </summary>
|
|
|
- /// <param name="data">string data to write.</param>
|
|
|
- protected void WriteAscii(string data)
|
|
|
- {
|
|
|
- Write(data, Ascii);
|
|
|
}
|
|
|
-#endif // !TUNING
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Writes string data into internal buffer using default encoding.
|
|
|
+ /// Writes <see cref="string"/> data into internal buffer using default encoding.
|
|
|
/// </summary>
|
|
|
- /// <param name="data">string data to write.</param>
|
|
|
+ /// <param name="data"><see cref="string"/> data to write.</param>
|
|
|
/// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
|
|
|
protected void Write(string data)
|
|
|
{
|
|
|
@@ -546,30 +368,17 @@ namespace Renci.SshNet.Common
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Writes string data into internal buffer using the specified encoding.
|
|
|
+ /// Writes <see cref="string"/> data into internal buffer using the specified encoding.
|
|
|
/// </summary>
|
|
|
- /// <param name="data">string data to write.</param>
|
|
|
+ /// <param name="data"><see cref="string"/> data to write.</param>
|
|
|
/// <param name="encoding">The character encoding to use.</param>
|
|
|
/// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
|
|
|
/// <exception cref="ArgumentNullException"><paramref name="encoding"/> is null.</exception>
|
|
|
protected void Write(string data, Encoding encoding)
|
|
|
{
|
|
|
-#if TUNING
|
|
|
_stream.Write(data, encoding);
|
|
|
-#else
|
|
|
- if (data == null)
|
|
|
- throw new ArgumentNullException("data");
|
|
|
- if (encoding == null)
|
|
|
- throw new ArgumentNullException("encoding");
|
|
|
-
|
|
|
- var bytes = encoding.GetBytes(data);
|
|
|
-
|
|
|
- Write((uint)bytes.Length);
|
|
|
- Write(bytes);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
-#if TUNING
|
|
|
/// <summary>
|
|
|
/// Writes data into internal buffer.
|
|
|
/// </summary>
|
|
|
@@ -593,21 +402,6 @@ namespace Renci.SshNet.Common
|
|
|
{
|
|
|
_stream.WriteBinary(buffer, offset, count);
|
|
|
}
|
|
|
-#else
|
|
|
- /// <summary>
|
|
|
- /// Writes string data into internal buffer.
|
|
|
- /// </summary>
|
|
|
- /// <param name="data">string data to write.</param>
|
|
|
- /// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
|
|
|
- protected void WriteBinaryString(byte[] data)
|
|
|
- {
|
|
|
- if (data == null)
|
|
|
- throw new ArgumentNullException("data");
|
|
|
-
|
|
|
- Write((uint)data.Length);
|
|
|
- _data.AddRange(data);
|
|
|
- }
|
|
|
-#endif
|
|
|
|
|
|
/// <summary>
|
|
|
/// Writes mpint data into internal buffer.
|
|
|
@@ -615,13 +409,7 @@ namespace Renci.SshNet.Common
|
|
|
/// <param name="data">mpint data to write.</param>
|
|
|
protected void Write(BigInteger data)
|
|
|
{
|
|
|
-#if TUNING
|
|
|
_stream.Write(data);
|
|
|
-#else
|
|
|
- var bytes = data.ToByteArray().Reverse().ToList();
|
|
|
- Write((uint)bytes.Count);
|
|
|
- Write(bytes);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
/// <summary>
|