2 // System.Net.FtpDataStream.cs
5 // Carlos Alberto Cortez (calberto.cortez@gmail.com)
7 // (c) Copyright 2006 Novell, Inc. (http://www.novell.com)
12 using System.Net.Sockets;
13 using System.Runtime.Remoting.Messaging;
14 using System.Threading;
21 class FtpDataStream : Stream, IDisposable
23 FtpWebRequest request;
29 internal FtpDataStream (FtpWebRequest request, Stream stream, bool isRead)
32 throw new ArgumentNullException ("request");
34 this.request = request;
35 this.networkStream = stream;
39 public override bool CanRead {
45 public override bool CanWrite {
51 public override bool CanSeek {
57 public override long Length {
59 throw new NotSupportedException ();
63 public override long Position {
65 throw new NotSupportedException ();
68 throw new NotSupportedException ();
72 internal Stream NetworkStream {
79 public override void Close ()
84 public override void Flush ()
89 public override long Seek (long offset, SeekOrigin origin)
91 throw new NotSupportedException ();
94 public override void SetLength (long value)
96 throw new NotSupportedException ();
99 int ReadInternal (byte [] buffer, int offset, int size)
102 request.CheckIfAborted ();
105 // Probably it would be better to have the socket here
106 nbytes = networkStream.Read (buffer, offset, size);
107 } catch (IOException) {
108 throw new ProtocolViolationException ("Server commited a protocol violation");
113 networkStream = null;
114 request.CloseDataConnection ();
115 request.SetTransferCompleted ();
121 public override IAsyncResult BeginRead (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
126 throw new NotSupportedException ();
128 throw new ArgumentNullException ("buffer");
129 if (offset < 0 || offset > buffer.Length)
130 throw new ArgumentOutOfRangeException ("offset");
131 if (size < 0 || size > buffer.Length - offset)
132 throw new ArgumentOutOfRangeException ("offset+size");
134 ReadDelegate del = ReadInternal;
135 return del.BeginInvoke (buffer, offset, size, cb, state);
138 public override int EndRead (IAsyncResult asyncResult)
140 if (asyncResult == null)
141 throw new ArgumentNullException ("asyncResult");
143 AsyncResult ar = asyncResult as AsyncResult;
145 throw new ArgumentException ("Invalid asyncResult", "asyncResult");
147 ReadDelegate del = ar.AsyncDelegate as ReadDelegate;
149 throw new ArgumentException ("Invalid asyncResult", "asyncResult");
151 return del.EndInvoke (asyncResult);
154 public override int Read (byte [] buffer, int offset, int size)
156 request.CheckIfAborted ();
157 IAsyncResult ar = BeginRead (buffer, offset, size, null, null);
158 if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
159 throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
164 delegate void WriteDelegate (byte [] buffer, int offset, int size);
166 void WriteInternal (byte [] buffer, int offset, int size)
168 request.CheckIfAborted ();
171 networkStream.Write (buffer, offset, size);
172 } catch (IOException) {
173 throw new ProtocolViolationException ();
177 public override IAsyncResult BeginWrite (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
181 throw new NotSupportedException ();
183 throw new ArgumentNullException ("buffer");
184 if (offset < 0 || offset > buffer.Length)
185 throw new ArgumentOutOfRangeException ("offset");
186 if (size < 0 || size > buffer.Length - offset)
187 throw new ArgumentOutOfRangeException ("offset+size");
189 WriteDelegate del = WriteInternal;
190 return del.BeginInvoke (buffer, offset, size, cb, state);
193 public override void EndWrite (IAsyncResult asyncResult)
195 if (asyncResult == null)
196 throw new ArgumentNullException ("asyncResult");
198 AsyncResult ar = asyncResult as AsyncResult;
200 throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
202 WriteDelegate del = ar.AsyncDelegate as WriteDelegate;
204 throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
206 del.EndInvoke (asyncResult);
209 public override void Write (byte [] buffer, int offset, int size)
211 request.CheckIfAborted ();
212 IAsyncResult ar = BeginWrite (buffer, offset, size, null, null);
213 if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
214 throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
224 void IDisposable.Dispose ()
227 GC.SuppressFinalize (this);
230 protected override void Dispose (bool disposing)
236 if (networkStream != null) {
237 request.CloseDataConnection ();
238 request.SetTransferCompleted ();
240 networkStream = null;
244 void CheckDisposed ()
247 throw new ObjectDisposedException (GetType ().FullName);
250 delegate int ReadDelegate (byte [] buffer, int offset, int size);