Refactor loading of a response to an extended request (SSH_FXP_EXTENDED):

Continue reading from SshDataStream instead of creating new instance for type specific part.
This commit is contained in:
Gert Driesen
2017-08-06 18:22:44 +02:00
parent 3e1dd2d345
commit 9ecfa0d38c
6 changed files with 34 additions and 129 deletions
@@ -86,66 +86,6 @@ namespace Renci.SshNet.Tests.Classes.Common
Assert.AreEqual(two, request.ValueTwo);
}
[TestMethod]
public void OfType()
{
const uint one = 123456u;
const uint two = 456789u;
var sshDataStream = new SshDataStream(8);
sshDataStream.Write(one);
sshDataStream.Write(two);
var sshData = sshDataStream.ToArray();
var request = new RequestSshData();
request.Load(sshData);
var reply = request.OfType<ReplySshData>();
Assert.IsNotNull(reply);
Assert.AreEqual(one, reply.ValueOne);
}
[TestMethod]
public void OfType_LoadWithOffset()
{
const uint one = 123456u;
const uint two = 456789u;
var sshDataStream = new SshDataStream(11);
sshDataStream.WriteByte(0x05);
sshDataStream.WriteByte(0x07);
sshDataStream.WriteByte(0x0f);
sshDataStream.Write(one);
sshDataStream.Write(two);
var sshData = sshDataStream.ToArray();
var request = new RequestSshData();
request.Load(sshData, 3, sshData.Length - 3);
var reply = request.OfType<ReplySshData>();
Assert.IsNotNull(reply);
Assert.AreEqual(one, reply.ValueOne);
}
[TestMethod]
public void OfType_ShouldThrowArgumentNullExceptionWhenNoDataIsLoaded()
{
var request = new RequestSshData();
try
{
request.OfType<ReplySshData>();
Assert.Fail();
}
catch (ArgumentNullException ex)
{
Assert.IsNull(ex.InnerException);
Assert.AreEqual("data", ex.ParamName);
}
}
private class BoolSshData : SshData
{
private readonly bool _value;
@@ -50,8 +50,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp.Responses
[TestMethod]
public void Load()
{
var target = new StatVfsReplyInfo();
var sshDataStream = new SshDataStream(4 + 1 + 4 + 88);
sshDataStream.Write(_responseId);
sshDataStream.Write(_bsize);
@@ -66,7 +64,12 @@ namespace Renci.SshNet.Tests.Classes.Sftp.Responses
sshDataStream.Write((ulong) 0x1);
sshDataStream.Write(_namemax);
target.Load(sshDataStream.ToArray());
var extendedReplyResponse = new SftpExtendedReplyResponse(SftpSession.MaximumSupportedVersion);
extendedReplyResponse.Load(sshDataStream.ToArray());
Assert.AreEqual(_responseId, extendedReplyResponse.ResponseId);
var target = extendedReplyResponse.GetReply<StatVfsReplyInfo>();
Assert.IsNotNull(target.Information);
+5 -29
View File
@@ -45,10 +45,6 @@ namespace Renci.SshNet.Common
}
}
private byte[] _loadedData;
private int _offset;
private int _count;
/// <summary>
/// Gets the size of the message in bytes.
/// </summary>
@@ -61,9 +57,11 @@ namespace Renci.SshNet.Common
}
/// <summary>
/// Gets data bytes array
/// Gets data bytes array.
/// </summary>
/// <returns>Byte array representation of data structure.</returns>
/// <returns>
/// A <see cref="Byte"/> array representation of data structure.
/// </returns>
public byte[] GetBytes()
{
var messageLength = BufferCapacity;
@@ -83,13 +81,6 @@ namespace Renci.SshNet.Common
SaveData();
}
internal T OfType<T>() where T : SshData, new()
{
var result = new T();
result.Load(_loadedData, _offset, _count);
return result;
}
/// <summary>
/// Loads data from specified bytes.
/// </summary>
@@ -120,7 +111,7 @@ namespace Renci.SshNet.Common
private void LoadInternal(byte[] value, int offset, int count)
{
LoadBytes(value, offset, count);
_stream = new SshDataStream(value, offset, count);
LoadData();
}
@@ -134,21 +125,6 @@ namespace Renci.SshNet.Common
/// </summary>
protected abstract void SaveData();
/// <summary>
/// Loads data bytes into internal buffer.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="offset">The zero-based offset in <paramref name="bytes"/> at which to begin reading SSH data.</param>
/// <param name="count">The number of bytes to load.</param>
private void LoadBytes(byte[] bytes, int offset, int count)
{
_loadedData = bytes;
_offset = offset;
_count = count;
_stream = new SshDataStream(bytes, _offset, count);
}
/// <summary>
/// Reads all data left in internal buffer at current position.
/// </summary>
@@ -1,19 +1,9 @@
using Renci.SshNet.Common;
using System;
namespace Renci.SshNet.Sftp.Responses
{
internal abstract class ExtendedReplyInfo : SshData
internal abstract class ExtendedReplyInfo
{
protected override void LoadData()
{
// skip response id
ReadUInt32();
}
protected override void SaveData()
{
throw new NotImplementedException();
}
public abstract void LoadData(SshDataStream stream);
}
}
@@ -1,29 +1,25 @@
namespace Renci.SshNet.Sftp.Responses
using Renci.SshNet.Common;
namespace Renci.SshNet.Sftp.Responses
{
internal class StatVfsReplyInfo : ExtendedReplyInfo
{
public SftpFileSytemInformation Information { get; private set; }
protected override void LoadData()
public override void LoadData(SshDataStream stream)
{
base.LoadData();
Information = new SftpFileSytemInformation(ReadUInt64(),
ReadUInt64(),
ReadUInt64(),
ReadUInt64(),
ReadUInt64(),
ReadUInt64(),
ReadUInt64(),
ReadUInt64(),
ReadUInt64(),
ReadUInt64(),
ReadUInt64());
}
protected override void SaveData()
{
throw new System.NotImplementedException();
Information = new SftpFileSytemInformation(stream.ReadUInt64(), // FileSystemBlockSize
stream.ReadUInt64(), // BlockSize
stream.ReadUInt64(), // TotalBlocks
stream.ReadUInt64(), // FreeBlocks
stream.ReadUInt64(), // AvailableBlocks
stream.ReadUInt64(), // TotalNodes
stream.ReadUInt64(), // FreeNodes
stream.ReadUInt64(), // AvailableNodes
stream.ReadUInt64(), // Sid
stream.ReadUInt64(), // Flags
stream.ReadUInt64() // MaxNameLenght
);
}
}
}
@@ -1,6 +1,4 @@
using Renci.SshNet.Common;
namespace Renci.SshNet.Sftp.Responses
namespace Renci.SshNet.Sftp.Responses
{
internal class SftpExtendedReplyResponse : SftpResponse
{
@@ -14,9 +12,11 @@ namespace Renci.SshNet.Sftp.Responses
{
}
public T GetReply<T>() where T : SshData, new()
public T GetReply<T>() where T : ExtendedReplyInfo, new()
{
return OfType<T>();
var result = new T();
result.LoadData(DataStream);
return result;
}
}
}