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;
24 NetworkStream networkStream;
30 ManualResetEvent closewh;
32 internal FtpDataStream (FtpWebRequest request, Socket socket, bool isRead)
35 throw new ArgumentNullException ("request");
37 throw new ArgumentNullException ("socket");
38 if (!socket.Connected)
39 throw new ArgumentException ("socket");
41 this.request = request;
42 this.contentLength = socket.Available;
43 this.networkStream = new NetworkStream (socket, true);
46 if (request.EnableSsl) {
47 FtpWebRequest.ChangeToSSLSocket (ref networkStream);
50 closewh = new ManualResetEvent (false);
53 public override bool CanRead {
59 public override bool CanWrite {
65 public override bool CanSeek {
71 public override long Length {
73 throw new NotSupportedException ();
77 public override long Position {
79 throw new NotSupportedException ();
82 throw new NotSupportedException ();
86 internal NetworkStream NetworkStream {
93 public override void Close ()
96 networkStream.Close ();
97 request.SetTransferCompleted ();
98 ((IDisposable) this).Dispose ();
102 public override void Flush ()
107 public override long Seek (long offset, SeekOrigin origin)
109 throw new NotSupportedException ();
112 public override void SetLength (long value)
114 throw new NotSupportedException ();
117 int ReadInternal (byte [] buffer, int offset, int size)
121 request.CheckIfAborted ();
124 // Probably it would be better to have the socket here
125 nbytes = networkStream.Read (buffer, offset, size);
126 } catch (IOException) {
127 throw new ProtocolViolationException ("Server commited a protocol violation");
132 contentLength = totalRead;
133 request.SetTransferCompleted ();
134 networkStream.Close ();
140 public override IAsyncResult BeginRead (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
145 throw new NotSupportedException ();
147 throw new ArgumentNullException ("buffer");
148 if (offset < 0 || offset > buffer.Length)
149 throw new ArgumentOutOfRangeException ("offset");
150 if (size < 0 || size > buffer.Length - offset)
151 throw new ArgumentOutOfRangeException ("offset+size");
153 ReadDelegate del = ReadInternal;
154 return del.BeginInvoke (buffer, offset, size, cb, state);
157 public override int EndRead (IAsyncResult asyncResult)
159 if (asyncResult == null)
160 throw new ArgumentNullException ("asyncResult");
162 AsyncResult ar = asyncResult as AsyncResult;
164 throw new ArgumentException ("Invalid asyncResult", "asyncResult");
166 ReadDelegate del = ar.AsyncDelegate as ReadDelegate;
168 throw new ArgumentException ("Invalid asyncResult", "asyncResult");
170 return del.EndInvoke (asyncResult);
173 public override int Read (byte [] buffer, int offset, int size)
175 request.CheckIfAborted ();
176 IAsyncResult ar = BeginRead (buffer, offset, size, null, null);
177 if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
178 throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
184 delegate void WriteDelegate (byte [] buffer, int offset, int size);
186 void WriteInternal (byte [] buffer, int offset, int size)
188 request.CheckIfAborted ();
191 networkStream.Write (buffer, offset, size);
192 } catch (IOException) {
193 throw new ProtocolViolationException ();
197 public override IAsyncResult BeginWrite (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
201 throw new NotSupportedException ();
203 throw new ArgumentNullException ("buffer");
204 if (offset < 0 || offset > buffer.Length)
205 throw new ArgumentOutOfRangeException ("offset");
206 if (size < 0 || size > buffer.Length - offset)
207 throw new ArgumentOutOfRangeException ("offset+size");
209 WriteDelegate del = WriteInternal;
210 return del.BeginInvoke (buffer, offset, size, cb, state);
213 public override void EndWrite (IAsyncResult asyncResult)
215 if (asyncResult == null)
216 throw new ArgumentNullException ("asyncResult");
218 AsyncResult ar = asyncResult as AsyncResult;
220 throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
222 WriteDelegate del = ar.AsyncDelegate as WriteDelegate;
224 throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
226 del.EndInvoke (asyncResult);
229 public override void Write (byte [] buffer, int offset, int size)
231 request.CheckIfAborted ();
232 IAsyncResult ar = BeginWrite (buffer, offset, size, null, null);
233 if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
234 throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
244 void IDisposable.Dispose ()
247 GC.SuppressFinalize (this);
250 protected override void Dispose (bool disposing)
257 networkStream.Close ();
258 networkStream = null;
263 void CheckDisposed ()
266 throw new ObjectDisposedException (GetType ().FullName);
269 delegate int ReadDelegate (byte [] buffer, int offset, int size);
271 // We need to know whether the stream has been closed
272 internal ManualResetEvent CloseWaitHandle {