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 internal FtpDataStream (FtpWebRequest request, Socket socket, bool isRead)
33 throw new ArgumentNullException ("request");
35 throw new ArgumentNullException ("socket");
36 if (!socket.Connected)
37 throw new ArgumentException ("socket");
39 this.request = request;
41 this.networkStream = new NetworkStream (socket, true);
44 if (request.EnableSsl) {
45 FtpWebRequest.ChangeToSSLSocket (ref networkStream);
49 public override bool CanRead {
55 public override bool CanWrite {
61 public override bool CanSeek {
67 public override long Length {
69 throw new NotSupportedException ();
73 public override long Position {
75 throw new NotSupportedException ();
78 throw new NotSupportedException ();
82 internal NetworkStream NetworkStream {
89 public override void Close ()
94 public override void Flush ()
99 public override long Seek (long offset, SeekOrigin origin)
101 throw new NotSupportedException ();
104 public override void SetLength (long value)
106 throw new NotSupportedException ();
109 int ReadInternal (byte [] buffer, int offset, int size)
113 request.CheckIfAborted ();
116 // Probably it would be better to have the socket here
117 nbytes = networkStream.Read (buffer, offset, size);
118 } catch (IOException) {
119 throw new ProtocolViolationException ("Server commited a protocol violation");
124 networkStream.Close ();
125 request.SetTransferCompleted ();
131 public override IAsyncResult BeginRead (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
136 throw new NotSupportedException ();
138 throw new ArgumentNullException ("buffer");
139 if (offset < 0 || offset > buffer.Length)
140 throw new ArgumentOutOfRangeException ("offset");
141 if (size < 0 || size > buffer.Length - offset)
142 throw new ArgumentOutOfRangeException ("offset+size");
144 ReadDelegate del = ReadInternal;
145 return del.BeginInvoke (buffer, offset, size, cb, state);
148 public override int EndRead (IAsyncResult asyncResult)
150 if (asyncResult == null)
151 throw new ArgumentNullException ("asyncResult");
153 AsyncResult ar = asyncResult as AsyncResult;
155 throw new ArgumentException ("Invalid asyncResult", "asyncResult");
157 ReadDelegate del = ar.AsyncDelegate as ReadDelegate;
159 throw new ArgumentException ("Invalid asyncResult", "asyncResult");
161 return del.EndInvoke (asyncResult);
164 public override int Read (byte [] buffer, int offset, int size)
166 request.CheckIfAborted ();
167 IAsyncResult ar = BeginRead (buffer, offset, size, null, null);
168 if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
169 throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
175 delegate void WriteDelegate (byte [] buffer, int offset, int size);
177 void WriteInternal (byte [] buffer, int offset, int size)
179 request.CheckIfAborted ();
182 networkStream.Write (buffer, offset, size);
183 } catch (IOException) {
184 throw new ProtocolViolationException ();
188 public override IAsyncResult BeginWrite (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
192 throw new NotSupportedException ();
194 throw new ArgumentNullException ("buffer");
195 if (offset < 0 || offset > buffer.Length)
196 throw new ArgumentOutOfRangeException ("offset");
197 if (size < 0 || size > buffer.Length - offset)
198 throw new ArgumentOutOfRangeException ("offset+size");
200 WriteDelegate del = WriteInternal;
201 return del.BeginInvoke (buffer, offset, size, cb, state);
204 public override void EndWrite (IAsyncResult asyncResult)
206 if (asyncResult == null)
207 throw new ArgumentNullException ("asyncResult");
209 AsyncResult ar = asyncResult as AsyncResult;
211 throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
213 WriteDelegate del = ar.AsyncDelegate as WriteDelegate;
215 throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
217 del.EndInvoke (asyncResult);
220 public override void Write (byte [] buffer, int offset, int size)
222 request.CheckIfAborted ();
223 IAsyncResult ar = BeginWrite (buffer, offset, size, null, null);
224 if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
225 throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
235 void IDisposable.Dispose ()
238 GC.SuppressFinalize (this);
241 protected override void Dispose (bool disposing)
247 if (socket != null) {
249 if (socket.Poll (0, SelectMode.SelectRead)) {
250 byte [] bytes = new byte [2048];
253 nbytes = socket.Receive (bytes);
254 } while (nbytes > 0 && socket.Poll (0, SelectMode.SelectRead));
261 networkStream.Close ();
264 networkStream = null;
266 request.SetTransferCompleted ();
271 void CheckDisposed ()
274 throw new ObjectDisposedException (GetType ().FullName);
277 delegate int ReadDelegate (byte [] buffer, int offset, int size);