/// <exception cref="NSch.SftpException"></exception>
public virtual void _put(InputStream src, string dst, SftpProgressMonitor monitor
, int mode)
{
try
{
((Channel.MyPipedInputStream)io_in).UpdateReadSide();
byte[] dstb = Util.Str2byte(dst, fEncoding);
long skip = 0;
if (mode == RESUME || mode == APPEND)
{
try
{
SftpATTRS attr = _stat(dstb);
skip = attr.GetSize();
}
catch (Exception)
{
}
}
//System.err.println(eee);
if (mode == RESUME && skip > 0)
{
long skipped = src.Skip(skip);
if (skipped < skip)
{
throw new SftpException(SSH_FX_FAILURE, "failed to resume for " + dst);
}
}
if (mode == OVERWRITE)
{
SendOPENW(dstb);
}
else
{
SendOPENA(dstb);
}
ChannelHeader header = new ChannelHeader(this);
header = Header(buf, header);
int length = header.length;
int type = header.type;
Fill(buf, length);
if (type != SSH_FXP_STATUS && type != SSH_FXP_HANDLE)
{
throw new SftpException(SSH_FX_FAILURE, "invalid type=" + type);
}
if (type == SSH_FXP_STATUS)
{
int i = buf.GetInt();
ThrowStatusError(buf, i);
}
byte[] handle = buf.GetString();
// handle
byte[] data = null;
bool dontcopy = true;
if (!dontcopy)
{
// This case will not work anymore.
data = new byte[obuf.buffer.Length - (5 + 13 + 21 + handle.Length + Session.buffer_margin
)];
}
long offset = 0;
if (mode == RESUME || mode == APPEND)
{
offset += skip;
}
int startid = seq;
int ackcount = 0;
int _s = 0;
int _datalen = 0;
if (!dontcopy)
{
// This case will not work anymore.
_datalen = data.Length;
}
else
{
data = obuf.buffer;
_s = 5 + 13 + 21 + handle.Length;
_datalen = obuf.buffer.Length - _s - Session.buffer_margin;
}
int bulk_requests = rq.Size();
while (true)
{
int nread = 0;
int count = 0;
int s = _s;
int datalen = _datalen;
do
{
nread = src.Read(data, s, datalen);
if (nread > 0)
{
s += nread;
datalen -= nread;
count += nread;
}
}
while (datalen > 0 && nread > 0);
if (count <= 0)
{
break;
}
int foo = count;
while (foo > 0)
{
if ((seq - 1) == startid || ((seq - startid) - ackcount) >= bulk_requests)
{
while (((seq - startid) - ackcount) >= bulk_requests)
{
if (this.rwsize >= foo)
{
break;
}
if (CheckStatus(ackid, header))
{
int _ackid = ackid[0];
if (startid > _ackid || _ackid > seq - 1)
{
if (_ackid == seq)
{
System.Console.Error.WriteLine("ack error: startid=" + startid + " seq=" + seq +
" _ackid=" + _ackid);
}
else
{
throw new SftpException(SSH_FX_FAILURE, "ack error: startid=" + startid + " seq="
+ seq + " _ackid=" + _ackid);
}
}
ackcount++;
}
else
{
break;
}
}
}
foo -= SendWRITE(handle, offset, data, 0, foo);
}
offset += count;
if (monitor != null && !monitor.Count(count))
{
break;
}
}
int _ackcount = seq - startid;
while (_ackcount > ackcount)
{
if (!CheckStatus(null, header))
{
break;
}
ackcount++;
}
if (monitor != null)
{
monitor.End();
}
_sendCLOSE(handle, header);
}
catch (Exception e)
{
if (e is SftpException)
{
throw (SftpException)e;
}
if (e is Exception)
{
throw new SftpException(SSH_FX_FAILURE, e.ToString(), (Exception)e);
}
throw new SftpException(SSH_FX_FAILURE, e.ToString());
}
}