00001 using System;
00002 using System.IO;
00003
00004 namespace Tamir.SharpSsh.jsch
00005 {
00006 internal class OutputStreamPut : java.io.OutputStream
00007 {
00008 ChannelSftp sftp;
00009 byte[] handle;
00010 long[] _offset;
00011 SftpProgressMonitor monitor;
00012 private bool init=true;
00013 private int[] ackid=new int[1];
00014 private int startid=0;
00015 private int _ackid=0;
00016 private int ackcount=0;
00017 private ChannelSftp.Header header=new ChannelSftp.Header();
00018
00019 internal OutputStreamPut
00020 (ChannelSftp sftp,
00021 byte[] handle,
00022 long[] _offset,
00023 SftpProgressMonitor monitor):base()
00024 {
00025 this.sftp=sftp;
00026 this.handle=handle;
00027 this._offset=_offset;
00028 this.monitor=monitor;
00029 }
00030
00031 public override void Write(byte[] d, int s, int len)
00032 {
00033 if(init)
00034 {
00035 startid=sftp.seq;
00036 _ackid=sftp.seq;
00037 init=false;
00038 }
00039
00040 try
00041 {
00042 int _len=len;
00043 while(_len>0)
00044 {
00045 int sent=sftp.sendWRITE(handle, _offset[0], d, s, _len);
00046 _offset[0]+=sent;
00047 s+=sent;
00048 _len-=sent;
00049 if((sftp.seq-1)==startid ||
00050 sftp.io.ins.available()>=1024)
00051 {
00052 while(sftp.io.ins.available()>0)
00053 {
00054 if(sftp.checkStatus(ackid, header))
00055 {
00056 _ackid=ackid[0];
00057 if(startid>_ackid || _ackid>sftp.seq-1)
00058 {
00059 throw new SftpException(ChannelSftp.SSH_FX_FAILURE, "");
00060 }
00061 ackcount++;
00062 }
00063 else
00064 {
00065 break;
00066 }
00067 }
00068 }
00069 }
00070 if(monitor!=null && !monitor.count(len))
00071 {
00072 close();
00073 throw new IOException("canceled");
00074 }
00075 }
00076 catch(IOException e){ throw e; }
00077 catch(Exception e){ throw new IOException(e.ToString()); }
00078 }
00079 byte[] _data=new byte[1];
00080 public void write(int foo)
00081 {
00082 _data[0]=(byte)foo;
00083 Write(_data, 0, 1);
00084 }
00085 public override void Close()
00086 {
00087 if(!init)
00088 {
00089 try
00090 {
00091 int _ackcount=sftp.seq-startid;
00092 while(_ackcount>ackcount)
00093 {
00094 if(!sftp.checkStatus(null, header))
00095 {
00096 break;
00097 }
00098 ackcount++;
00099 }
00100 }
00101 catch(SftpException e)
00102 {
00103 throw new IOException(e.toString());
00104 }
00105 }
00106
00107 if(monitor!=null)monitor.end();
00108 try{ sftp._sendCLOSE(handle, header); }
00109 catch(IOException e){ throw e; }
00110 catch(Exception e)
00111 {
00112 throw new IOException(e.ToString());
00113 }
00114 }
00115 }
00116 }