SparkleShare/SharpSSH/jsch/ChannelSftpStreamPut.cs
2010-07-15 20:41:37 +01:00

117 lines
2.3 KiB
C#

using System;
using System.IO;
namespace Tamir.SharpSsh.jsch
{
internal class OutputStreamPut : java.io.OutputStream
{
ChannelSftp sftp;
byte[] handle;
long[] _offset;
SftpProgressMonitor monitor;
private bool init=true;
private int[] ackid=new int[1];
private int startid=0;
private int _ackid=0;
private int ackcount=0;
private ChannelSftp.Header header=new ChannelSftp.Header();
internal OutputStreamPut
(ChannelSftp sftp,
byte[] handle,
long[] _offset,
SftpProgressMonitor monitor):base()
{
this.sftp=sftp;
this.handle=handle;
this._offset=_offset;
this.monitor=monitor;
}
public override void Write(byte[] d, int s, int len)
{
if(init)
{
startid=sftp.seq;
_ackid=sftp.seq;
init=false;
}
try
{
int _len=len;
while(_len>0)
{
int sent=sftp.sendWRITE(handle, _offset[0], d, s, _len);
_offset[0]+=sent;
s+=sent;
_len-=sent;
if((sftp.seq-1)==startid ||
sftp.io.ins.available()>=1024)
{
while(sftp.io.ins.available()>0)
{
if(sftp.checkStatus(ackid, header))
{
_ackid=ackid[0];
if(startid>_ackid || _ackid>sftp.seq-1)
{
throw new SftpException(ChannelSftp.SSH_FX_FAILURE, "");
}
ackcount++;
}
else
{
break;
}
}
}
}
if(monitor!=null && !monitor.count(len))
{
close();
throw new IOException("canceled");
}
}
catch(IOException e){ throw e; }
catch(Exception e){ throw new IOException(e.ToString()); }
}
byte[] _data=new byte[1];
public void write(int foo)
{
_data[0]=(byte)foo;
Write(_data, 0, 1);
}
public override void Close()
{
if(!init)
{
try
{
int _ackcount=sftp.seq-startid;
while(_ackcount>ackcount)
{
if(!sftp.checkStatus(null, header))
{
break;
}
ackcount++;
}
}
catch(SftpException e)
{
throw new IOException(e.toString());
}
}
if(monitor!=null)monitor.end();
try{ sftp._sendCLOSE(handle, header); }
catch(IOException e){ throw e; }
catch(Exception e)
{
throw new IOException(e.ToString());
}
}
}
}