You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
4.2 KiB
C#

using System;
using System.IO;
using Renci.SshNet.Common;
using System.Globalization;
using Renci.SshNet.Sftp.Responses;
using System.Text;
namespace Renci.SshNet.Sftp
{
internal abstract class SftpMessage : SshData
{
public static SftpMessage Load(uint protocolVersion, byte[] data, int offset, int count, Encoding encoding)
{
var messageType = (SftpMessageTypes) data[offset];
return Load(protocolVersion, messageType, data, offset + 1, count - 1, encoding);
}
/// <summary>
/// Gets the size of the message in bytes.
/// </summary>
/// <value>
/// The size of the messages in bytes.
/// </value>
protected override int BufferCapacity
{
get
{
// 4 bytes for the length of the SFTP data
// 1 byte for the SFTP message type
return 5;
}
}
public abstract SftpMessageTypes SftpMessageType { get; }
protected override void LoadData()
{
}
protected override void SaveData()
{
Write((byte) SftpMessageType);
}
/// <summary>
/// Writes the current message to the specified <see cref="SshDataStream"/>.
/// </summary>
/// <param name="stream">The <see cref="SshDataStream"/> to write the message to.</param>
protected override void WriteBytes(SshDataStream stream)
{
const int sizeOfDataLengthBytes = 4;
var startPosition = stream.Position;
// skip 4 bytes for the length of the SFTP message data
stream.Seek(sizeOfDataLengthBytes, SeekOrigin.Current);
// write the SFTP message data to the stream
base.WriteBytes(stream);
// save where we were positioned when we finished writing the SSH message data
var endPosition = stream.Position;
// determine the length of the SSH message data
var dataLength = endPosition - startPosition - sizeOfDataLengthBytes;
// write the length of the SFTP message where we were positioned before we started
// writing the SFTP message data
stream.Position = startPosition;
stream.Write((uint) dataLength);
// move back to we were positioned when we finished writing the SFTP message data
stream.Position = endPosition;
}
protected SftpFileAttributes ReadAttributes()
{
return SftpFileAttributes.FromBytes(DataStream);
}
private static SftpMessage Load(uint protocolVersion, SftpMessageTypes messageType, byte[] data, int offset, int count, Encoding encoding)
{
SftpMessage message;
switch (messageType)
{
case SftpMessageTypes.Version:
message = new SftpVersionResponse();
break;
case SftpMessageTypes.Status:
message = new SftpStatusResponse(protocolVersion);
break;
case SftpMessageTypes.Data:
message = new SftpDataResponse(protocolVersion);
break;
case SftpMessageTypes.Handle:
message = new SftpHandleResponse(protocolVersion);
break;
case SftpMessageTypes.Name:
message = new SftpNameResponse(protocolVersion, encoding);
break;
case SftpMessageTypes.Attrs:
message = new SftpAttrsResponse(protocolVersion);
break;
case SftpMessageTypes.ExtendedReply:
message = new SftpExtendedReplyResponse(protocolVersion);
break;
default:
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Message type '{0}' is not supported.", messageType));
}
message.Load(data, offset, count);
return message;
}
public override string ToString()
{
return string.Format(CultureInfo.CurrentCulture, "SFTP Message : {0}", SftpMessageType);
}
}
}