/// <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()); } }
/// <exception cref="NSch.SftpException"></exception> public virtual void _put(InputStream src, string dst, SftpProgressMonitor monitor , int mode) { try { 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) { data = new byte[buf.buffer.Length - (5 + 13 + 21 + handle.Length + 32 + 20)]; } // padding and mac long offset = 0; if (mode == RESUME || mode == APPEND) { offset += skip; } int startid = seq; int _ackid = seq; int ackcount = 0; while (true) { int nread = 0; int s = 0; int datalen = 0; int count = 0; if (!dontcopy) { datalen = data.Length - s; } else { data = buf.buffer; s = 5 + 13 + 21 + handle.Length; datalen = buf.buffer.Length - s - 32 - 20; } do { // padding and mac 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 _i = count; while (_i > 0) { _i -= SendWRITE(handle, offset, data, 0, _i); if ((seq - 1) == startid || io_in.Available() >= 1024) { while (io_in.Available() > 0) { if (CheckStatus(ackid, header)) { _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:"); throw new SftpException(SSH_FX_FAILURE, "ack error: startid=" + startid + " seq=" + seq + " _ackid=" + _ackid); } } ackcount++; } else { break; } } } } 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()); } }
/// <summary>Skip an entire region of an input stream.</summary> /// <remarks> /// Skip an entire region of an input stream. /// <p> /// The input stream's position is moved forward by the number of requested /// bytes, discarding them from the input. This method does not return until /// the exact number of bytes requested has been skipped. /// </remarks> /// <param name="fd">the stream to skip bytes from.</param> /// <param name="toSkip">total number of bytes to be discarded. Must be >= 0.</param> /// <exception cref="Sharpen.EOFException"> /// the stream ended before the requested number of bytes were /// skipped. /// </exception> /// <exception cref="System.IO.IOException">there was an error reading from the stream. /// </exception> public static void SkipFully(InputStream fd, long toSkip) { while (toSkip > 0) { long r = fd.Skip(toSkip); if (r <= 0) { throw new EOFException(JGitText.Get().shortSkipOfBlock); } toSkip -= r; } }