5 // Dietmar Maurer (dietmar@ximian.com)
6 // Miguel de Icaza (miguel@ximian.com)
7 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
9 // (C) 2001, 2002 Ximian, Inc. http://www.ximian.com
10 // (c) 2004 Novell, Inc. (http://www.novell.com)
14 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Threading;
37 using System.Runtime.Remoting.Messaging;
38 using System.Runtime.InteropServices;
45 public abstract class Stream : IDisposable
47 public abstract class Stream : MarshalByRefObject, IDisposable
50 public static readonly Stream Null = new NullStream ();
56 public abstract bool CanRead
61 public abstract bool CanSeek
66 public abstract bool CanWrite
72 public virtual bool CanTimeout {
78 public abstract long Length
83 public abstract long Position
90 // 2.0 version of Dispose.
91 public void Dispose ()
96 // 2.0 version of Dispose.
97 protected virtual void Dispose (bool disposing)
103 // 2.0 version of Close (): calls Dispose (true)
105 public virtual void Close ()
108 GC.SuppressFinalize (this);
112 public virtual int ReadTimeout {
114 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
117 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
122 public virtual int WriteTimeout {
124 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
127 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
131 public static Stream Synchronized (Stream stream)
133 return new SynchronizedStream (stream);
136 [Obsolete ("CreateWaitHandle is due for removal. Use \"new ManualResetEvent(false)\" instead.")]
137 protected virtual WaitHandle CreateWaitHandle()
139 return new ManualResetEvent (false);
142 public abstract void Flush ();
144 public abstract int Read ([In,Out] byte[] buffer, int offset, int count);
146 public virtual int ReadByte ()
148 byte[] buffer = new byte [1];
150 if (Read (buffer, 0, 1) == 1)
156 public abstract long Seek (long offset, SeekOrigin origin);
158 public abstract void SetLength (long value);
160 public abstract void Write (byte[] buffer, int offset, int count);
162 public virtual void WriteByte (byte value)
164 byte[] buffer = new byte [1];
168 Write (buffer, 0, 1);
171 public virtual IAsyncResult
172 BeginRead (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
175 throw new NotSupportedException ("This stream does not support reading");
177 // Creating a class derived from Stream that doesn't override BeginRead
178 // shows that it actually calls Read and does everything synchronously.
179 // Just put this in the Read override:
180 // Console.WriteLine ("Read");
181 // Console.WriteLine (Environment.StackTrace);
182 // Thread.Sleep (10000);
185 StreamAsyncResult result = new StreamAsyncResult (state);
187 int nbytes = Read (buffer, offset, count);
188 result.SetComplete (null, nbytes);
189 } catch (Exception e) {
190 result.SetComplete (e, 0);
193 if (callback != null)
199 // delegate void WriteDelegate (byte [] buffer, int offset, int count);
201 public virtual IAsyncResult
202 BeginWrite (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
205 throw new NotSupportedException ("This stream does not support writing");
207 // Creating a class derived from Stream that doesn't override BeginWrite
208 // shows that it actually calls Write and does everything synchronously except
209 // when invoking the callback, which is done from the ThreadPool.
210 // Just put this in the Write override:
211 // Console.WriteLine ("Write");
212 // Console.WriteLine (Environment.StackTrace);
213 // Thread.Sleep (10000);
215 StreamAsyncResult result = new StreamAsyncResult (state);
217 Write (buffer, offset, count);
218 result.SetComplete (null);
219 } catch (Exception e) {
220 result.SetComplete (e);
223 if (callback != null)
224 callback.BeginInvoke (result, null, null);
229 public virtual int EndRead (IAsyncResult asyncResult)
231 if (asyncResult == null)
232 throw new ArgumentNullException ("asyncResult");
234 StreamAsyncResult result = asyncResult as StreamAsyncResult;
235 if (result == null || result.NBytes == -1)
236 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
239 throw new InvalidOperationException ("EndRead already called.");
242 if (result.Exception != null)
243 throw result.Exception;
245 return result.NBytes;
248 public virtual void EndWrite (IAsyncResult asyncResult)
250 if (asyncResult == null)
251 throw new ArgumentNullException ("asyncResult");
253 StreamAsyncResult result = asyncResult as StreamAsyncResult;
254 if (result == null || result.NBytes != -1)
255 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
258 throw new InvalidOperationException ("EndWrite already called.");
261 if (result.Exception != null)
262 throw result.Exception;
265 #if MOONLIGHT || NET_4_0 || MOBILE
266 public void CopyTo (Stream destination)
268 CopyTo (destination, 16*1024);
271 public void CopyTo (Stream destination, int bufferSize)
273 if (destination == null)
274 throw new ArgumentNullException ("destination");
276 throw new NotSupportedException ("This stream does not support reading");
277 if (!destination.CanWrite)
278 throw new NotSupportedException ("This destination stream does not support writing");
280 throw new ArgumentOutOfRangeException ("bufferSize");
282 var buffer = new byte [bufferSize];
284 while ((nread = Read (buffer, 0, bufferSize)) != 0)
285 destination.Write (buffer, 0, nread);
288 protected virtual void ObjectInvariant ()
294 class NullStream : Stream
296 public override bool CanRead
303 public override bool CanSeek
310 public override bool CanWrite
317 public override long Length
324 public override long Position
333 public override void Flush ()
337 public override int Read (byte[] buffer, int offset, int count)
342 public override int ReadByte ()
347 public override long Seek (long offset, SeekOrigin origin)
352 public override void SetLength (long value)
356 public override void Write (byte[] buffer, int offset, int count)
360 public override void WriteByte (byte value)
365 class SynchronizedStream : Stream {
369 internal SynchronizedStream (Stream source)
371 this.source = source;
372 slock = new object ();
375 public override bool CanRead
379 return source.CanRead;
383 public override bool CanSeek
387 return source.CanSeek;
391 public override bool CanWrite
395 return source.CanWrite;
399 public override long Length
403 return source.Length;
407 public override long Position
411 return source.Position;
415 source.Position = value;
419 public override void Flush ()
425 public override int Read (byte[] buffer, int offset, int count)
428 return source.Read (buffer, offset, count);
431 public override int ReadByte ()
434 return source.ReadByte ();
437 public override long Seek (long offset, SeekOrigin origin)
440 return source.Seek (offset, origin);
443 public override void SetLength (long value)
446 source.SetLength (value);
449 public override void Write (byte[] buffer, int offset, int count)
452 source.Write (buffer, offset, count);
455 public override void WriteByte (byte value)
458 source.WriteByte (value);