FtpDataStream.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. //
  2. // System.Net.FtpDataStream.cs
  3. //
  4. // Authors:
  5. // Carlos Alberto Cortez ([email protected])
  6. //
  7. // (c) Copyright 2006 Novell, Inc. (http://www.novell.com)
  8. //
  9. using System;
  10. using System.IO;
  11. using System.Net.Sockets;
  12. using System.Runtime.Remoting.Messaging;
  13. using System.Threading;
  14. #if NET_2_0
  15. namespace System.Net
  16. {
  17. class FtpDataStream : Stream, IDisposable
  18. {
  19. FtpWebRequest request;
  20. NetworkStream networkStream;
  21. bool disposed;
  22. bool isRead;
  23. int totalRead;
  24. int contentLength;
  25. ManualResetEvent closewh;
  26. internal FtpDataStream (FtpWebRequest request, Socket socket, bool isRead)
  27. {
  28. if (request == null)
  29. throw new ArgumentNullException ("request");
  30. if (socket == null)
  31. throw new ArgumentNullException ("socket");
  32. if (!socket.Connected)
  33. throw new ArgumentException ("socket");
  34. this.request = request;
  35. this.contentLength = socket.Available;
  36. this.networkStream = new NetworkStream (socket, true);
  37. this.isRead = isRead;
  38. closewh = new ManualResetEvent (false);
  39. }
  40. public override bool CanRead {
  41. get {
  42. return isRead;
  43. }
  44. }
  45. public override bool CanWrite {
  46. get {
  47. return !isRead;
  48. }
  49. }
  50. public override bool CanSeek {
  51. get {
  52. return false;
  53. }
  54. }
  55. public override long Length {
  56. get {
  57. throw new NotSupportedException ();
  58. }
  59. }
  60. public override long Position {
  61. get {
  62. throw new NotSupportedException ();
  63. }
  64. set {
  65. throw new NotSupportedException ();
  66. }
  67. }
  68. internal NetworkStream NetworkStream {
  69. get {
  70. CheckDisposed ();
  71. return networkStream;
  72. }
  73. }
  74. public override void Close ()
  75. {
  76. ((IDisposable) this).Dispose ();
  77. }
  78. public override void Flush ()
  79. {
  80. // Do nothing.
  81. }
  82. public override long Seek (long offset, SeekOrigin origin)
  83. {
  84. throw new NotSupportedException ();
  85. }
  86. public override void SetLength (long value)
  87. {
  88. throw new NotSupportedException ();
  89. }
  90. int ReadInternal (byte [] buffer, int offset, int size)
  91. {
  92. int nbytes;
  93. try {
  94. // Probably it would be better to have the socket here
  95. nbytes = networkStream.Read (buffer, offset, size);
  96. } catch (IOException exc) {
  97. throw new ProtocolViolationException ("Server commited a protocol violation");
  98. }
  99. totalRead += nbytes;
  100. if (nbytes == 0)
  101. contentLength = totalRead;
  102. if (totalRead >= contentLength)
  103. request.SetTransferCompleted ();
  104. return nbytes;
  105. }
  106. public override IAsyncResult BeginRead (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
  107. {
  108. CheckDisposed ();
  109. if (!isRead)
  110. throw new NotSupportedException ();
  111. if (buffer == null)
  112. throw new ArgumentNullException ("buffer");
  113. if (offset < 0 || offset > buffer.Length)
  114. throw new ArgumentOutOfRangeException ("offset");
  115. if (size < 0 || size > buffer.Length - offset)
  116. throw new ArgumentOutOfRangeException ("offset+size");
  117. ReadDelegate del = ReadInternal;
  118. return del.BeginInvoke (buffer, offset, size, cb, state);
  119. }
  120. public override int EndRead (IAsyncResult asyncResult)
  121. {
  122. if (asyncResult == null)
  123. throw new ArgumentNullException ("asyncResult");
  124. AsyncResult ar = asyncResult as AsyncResult;
  125. if (ar == null)
  126. throw new ArgumentException ("Invalid asyncResult", "asyncResult");
  127. ReadDelegate del = ar.AsyncDelegate as ReadDelegate;
  128. if (del == null)
  129. throw new ArgumentException ("Invalid asyncResult", "asyncResult");
  130. return del.EndInvoke (asyncResult);
  131. }
  132. public override int Read (byte [] buffer, int offset, int size)
  133. {
  134. IAsyncResult ar = BeginRead (buffer, offset, size, null, null);
  135. if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
  136. throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
  137. return EndRead (ar);
  138. }
  139. delegate void WriteDelegate (byte [] buffer, int offset, int size);
  140. void WriteInternal (byte [] buffer, int offset, int size)
  141. {
  142. try {
  143. networkStream.Write (buffer, offset, size);
  144. } catch (IOException exc) {
  145. throw new ProtocolViolationException ();
  146. }
  147. }
  148. public override IAsyncResult BeginWrite (byte [] buffer, int offset, int size, AsyncCallback cb, object state)
  149. {
  150. CheckDisposed ();
  151. if (isRead)
  152. throw new NotSupportedException ();
  153. if (buffer == null)
  154. throw new ArgumentNullException ("buffer");
  155. if (offset < 0 || offset > buffer.Length)
  156. throw new ArgumentOutOfRangeException ("offset");
  157. if (size < 0 || size > buffer.Length - offset)
  158. throw new ArgumentOutOfRangeException ("offset+size");
  159. WriteDelegate del = WriteInternal;
  160. return del.BeginInvoke (buffer, offset, size, cb, state);
  161. }
  162. public override void EndWrite (IAsyncResult asyncResult)
  163. {
  164. if (asyncResult == null)
  165. throw new ArgumentNullException ("asyncResult");
  166. AsyncResult ar = asyncResult as AsyncResult;
  167. if (ar == null)
  168. throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
  169. WriteDelegate del = ar.AsyncDelegate as WriteDelegate;
  170. if (del == null)
  171. throw new ArgumentException ("Invalid asyncResult.", "asyncResult");
  172. del.EndInvoke (asyncResult);
  173. }
  174. public override void Write (byte [] buffer, int offset, int size)
  175. {
  176. IAsyncResult ar = BeginWrite (buffer, offset, size, null, null);
  177. if (!ar.IsCompleted && !ar.AsyncWaitHandle.WaitOne (request.ReadWriteTimeout, false))
  178. throw new WebException ("Read timed out.", WebExceptionStatus.Timeout);
  179. EndWrite (ar);
  180. }
  181. ~FtpDataStream ()
  182. {
  183. Dispose (false);
  184. }
  185. void IDisposable.Dispose ()
  186. {
  187. Dispose (true);
  188. GC.SuppressFinalize (this);
  189. }
  190. protected override void Dispose (bool disposing)
  191. {
  192. if (disposed)
  193. return;
  194. disposed = true;
  195. networkStream.Close ();
  196. networkStream = null;
  197. closewh.Set ();
  198. }
  199. void CheckDisposed ()
  200. {
  201. if (disposed)
  202. throw new ObjectDisposedException (GetType ().FullName);
  203. }
  204. delegate int ReadDelegate (byte [] buffer, int offset, int size);
  205. // We need to know whether the stream has been closed
  206. internal ManualResetEvent CloseWaitHandle {
  207. get {
  208. return closewh;
  209. }
  210. }
  211. }
  212. }
  213. #endif