/// <summary> /// Performs the actual data-transfer implied by the specified /// SI session. /// </summary> /// <param name="session">The SI session whose data to transfer.</param> /// <exception cref="ArgumentNullException">The session parameter is /// null.</exception> /// <exception cref="NotSupportedException">The XMPP extension /// implementing this method is not supported by the intended recipient's /// XMPP client.</exception> /// <exception cref="XmppErrorException">The server or the XMPP entity /// with the specified JID returned an XMPP error code. Use the Error /// property of the XmppErrorException to obtain the specific error /// condition.</exception> /// <exception cref="XmppException">The server returned invalid data or /// another unspecified XMPP error occurred.</exception> public void Transfer(SISession session) { session.ThrowIfNull("session"); // Open the negotiated IBB. OpenStream(session.To, session.Sid); byte[] buf = new byte[blockSize]; // 'seq' is defined as 16-bit unsigned short value that wraps around. ushort seq = 0; long left = session.Size; try { while (left > 0) { int read = session.Stream.Read(buf, 0, blockSize); left = left - read; if (read <= 0) { break; } string b64 = Convert.ToBase64String(buf, 0, read); var data = Xml.Element("data", "http://jabber.org/protocol/ibb") .Attr("sid", session.Sid) .Attr("seq", seq.ToString()) .Text(b64); seq++; Iq response = im.IqRequest(IqType.Set, session.To, im.Jid, data); if (response.Type == IqType.Error) { throw Util.ExceptionFromError(response); } session.Count = session.Count + read; // Raise the 'BytesTransferred' event. BytesTransferred.Raise(this, new BytesTransferredEventArgs(session)); } } catch (ObjectDisposedException) { // This means the IO-stream has been disposed because we cancelled // the transfer. Just fall through. } catch { // The IQ response is of type 'error', the other site has cancelled // the transfer. TransferAborted.Raise(this, new TransferAbortedEventArgs(session)); // Rethrow. throw; } finally { // Gracefully close the IBB. CloseStream(session.To, session.Sid); } }
/// <summary> /// Initializes a new instance of the BytesTransferredEventArgs class. /// </summary> /// <param name="session">The session for which the event is raised.</param> /// <exception cref="ArgumentNullException">The session parameter /// is null.</exception> public BytesTransferredEventArgs(SISession session) { session.ThrowIfNull("session"); Session = session; }
/// <summary> /// Initializes a new instance of the BytesTransferredEventArgs class. /// </summary> /// <param name="session">The session for which the event is raised.</param> /// <exception cref="ArgumentNullException">The session parameter /// is null.</exception> public TransferAbortedEventArgs(SISession session) { session.ThrowIfNull("session"); Session = session; }
/// <summary> /// Cancels the data-transfer implied by the specified SI session. /// </summary> /// <param name="session">The SI session whose data-transfer to /// cancel.</param> /// <exception cref="ArgumentNullException">The session parameter is /// null.</exception> public void CancelTransfer(SISession session) { session.ThrowIfNull("session"); siFileTransfer.InvalidateSession(session.Sid); }
/// <summary> /// Cancels the data-transfer implied by the specified SI session. /// </summary> /// <param name="session">The SI session whose data-transfer to /// cancel.</param> /// <exception cref="ArgumentNullException">The session parameter is /// null.</exception> public void CancelTransfer(SISession session) { session.ThrowIfNull("session"); siFileTransfer.InvalidateSession(session.Sid); TransferAborted.Raise(this, new TransferAbortedEventArgs(session)); }