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;
20 class FtpDataStream : Stream, IDisposable
22 FtpWebRequest request;
23 NetworkStream networkStream;
29 ManualResetEvent closewh;
31 internal FtpDataStream (FtpWebRequest request, Socket socket, bool isRead)
34 throw new ArgumentNullException ("request");
36 throw new ArgumentNullException ("socket");
37 if (!socket.Connected)
38 throw new ArgumentException ("socket");
40 this.request = request;
41 this.contentLength = socket.Available;
42 this.networkStream = new NetworkStream (socket, true);
45 closewh = new ManualResetEvent (false);
48 public override bool CanRead {
54 public override bool CanWrite {
60 public override bool CanSeek {
66 public override long Length {
68 throw new NotSupportedException ();
72 public override long Position {
74 throw new NotSupportedException ();
77 throw new NotSupportedException ();
81 internal NetworkStream NetworkStream {
88 public override void Close ()
90 ((IDisposable) this).Dispose ();
93 public override void Flush ()
98 public override long Seek (long offset, SeekOrigin origin)
100 throw new NotSupportedException ();
103 public override void SetLength (long value)
105 throw new NotSupportedException ();
108 int ReadInternal (byte [] buffer, int offset, int size)
112 // Probably it would be better to have the socket here
113 nbytes = networkStream.Read (buffer, offset, size);
114 } catch (IOException exc) {
115 throw new ProtocolViolationException ("Server commited a protocol violation");
120 contentLength = totalRead;
121 if (totalRead >= contentLength)
122 request.SetTransferCompleted ();
127 public override IAsyncResult BeginRead (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
132 throw new NotSupportedException ();
134 throw new ArgumentNullException ("buffer");
135 if (offset < 0 || offset > buffer.Length)
136 throw new ArgumentOutOfRangeException ("offset");
137 if (size < 0 || size > buffer.Length - offset)
138 throw new ArgumentOutOfRangeException ("offset+size");
140 ReadDelegate del = ReadInternal;
141 return del.BeginInvoke (buffer, offset, size, cb, state);
144 public override int EndRead (IAsyncResult asyncResult)
146 if (asyncResult == null)
147 throw new ArgumentNullException ("asyncResult");
149 AsyncResult ar = asyncResult as AsyncResult;
151 throw new ArgumentException ("Invalid asyncResult", "asyncResult");
153 ReadDelegate del = ar.AsyncDelegate as ReadDelegate;
155 throw new ArgumentException ("Invalid asyncResult", "asyncResult");
157 return del.EndInvoke (asyncResult);
160 public override int Read (byte [] buffer, int offset, int size)
162 IAsyncResult ar = BeginRead (buffer, offset, size, null, null);
163 if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
164 throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
170 delegate void WriteDelegate (byte [] buffer, int offset, int size);
172 void WriteInternal (byte [] buffer, int offset, int size)
175 networkStream.Write (buffer, offset, size);
176 } catch (IOException exc) {
177 throw new ProtocolViolationException ();
181 public override IAsyncResult BeginWrite (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
185 throw new NotSupportedException ();
187 throw new ArgumentNullException ("buffer");
188 if (offset < 0 || offset > buffer.Length)
189 throw new ArgumentOutOfRangeException ("offset");
190 if (size < 0 || size > buffer.Length - offset)
191 throw new ArgumentOutOfRangeException ("offset+size");
193 WriteDelegate del = WriteInternal;
194 return del.BeginInvoke (buffer, offset, size, cb, state);
197 public override void EndWrite (IAsyncResult asyncResult)
199 if (asyncResult == null)
200 throw new ArgumentNullException ("asyncResult");
202 AsyncResult ar = asyncResult as AsyncResult;
204 throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
206 WriteDelegate del = ar.AsyncDelegate as WriteDelegate;
208 throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
210 del.EndInvoke (asyncResult);
213 public override void Write (byte [] buffer, int offset, int size)
215 IAsyncResult ar = BeginWrite (buffer, offset, size, null, null);
216 if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
217 throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
227 void IDisposable.Dispose ()
230 GC.SuppressFinalize (this);
233 protected override void Dispose (bool disposing)
240 networkStream.Close ();
241 networkStream = null;
246 void CheckDisposed ()
249 throw new ObjectDisposedException (GetType ().FullName);
252 delegate int ReadDelegate (byte [] buffer, int offset, int size);
254 // We need to know whether the stream has been closed
255 internal ManualResetEvent CloseWaitHandle {