2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / corlib / System.IO / Stream.cs
blob17c8cc457eb82bc3b2733a00659fb5546c423e09
1 //
2 // System.IO.Stream.cs
3 //
4 // Authors:
5 // Dietmar Maurer (dietmar@ximian.com)
6 // Miguel de Icaza (miguel@ximian.com)
7 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 //
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:
23 //
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 //
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;
40 namespace System.IO
42 [Serializable]
43 [ComVisible (true)]
44 #if NET_2_1
45 public abstract class Stream : IDisposable
46 #else
47 public abstract class Stream : MarshalByRefObject, IDisposable
48 #endif
50 public static readonly Stream Null = new NullStream ();
52 protected Stream ()
56 public abstract bool CanRead
58 get;
61 public abstract bool CanSeek
63 get;
66 public abstract bool CanWrite
68 get;
71 [ComVisible (false)]
72 public virtual bool CanTimeout {
73 get {
74 return false;
78 public abstract long Length
80 get;
83 public abstract long Position
85 get;
86 set;
90 // 2.0 version of Dispose.
91 public void Dispose ()
93 Close ();
96 // 2.0 version of Dispose.
97 protected virtual void Dispose (bool disposing)
99 // nothing.
103 // 2.0 version of Close (): calls Dispose (true)
105 public virtual void Close ()
107 Dispose (true);
110 [ComVisible (false)]
111 public virtual int ReadTimeout {
112 get {
113 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
115 set {
116 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
120 [ComVisible (false)]
121 public virtual int WriteTimeout {
122 get {
123 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
125 set {
126 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
130 public static Stream Synchronized (Stream stream)
132 return new SynchronizedStream (stream);
135 [Obsolete ("CreateWaitHandle is due for removal. Use \"new ManualResetEvent(false)\" instead.")]
136 protected virtual WaitHandle CreateWaitHandle()
138 return new ManualResetEvent (false);
141 public abstract void Flush ();
143 public abstract int Read ([In,Out] byte[] buffer, int offset, int count);
145 public virtual int ReadByte ()
147 byte[] buffer = new byte [1];
149 if (Read (buffer, 0, 1) == 1)
150 return buffer [0];
152 return -1;
155 public abstract long Seek (long offset, SeekOrigin origin);
157 public abstract void SetLength (long value);
159 public abstract void Write (byte[] buffer, int offset, int count);
161 public virtual void WriteByte (byte value)
163 byte[] buffer = new byte [1];
165 buffer [0] = value;
167 Write (buffer, 0, 1);
170 public virtual IAsyncResult
171 BeginRead (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
173 if (!CanRead)
174 throw new NotSupportedException ("This stream does not support reading");
176 // Creating a class derived from Stream that doesn't override BeginRead
177 // shows that it actually calls Read and does everything synchronously.
178 // Just put this in the Read override:
179 // Console.WriteLine ("Read");
180 // Console.WriteLine (Environment.StackTrace);
181 // Thread.Sleep (10000);
182 // return 10;
184 StreamAsyncResult result = new StreamAsyncResult (state);
185 try {
186 int nbytes = Read (buffer, offset, count);
187 result.SetComplete (null, nbytes);
188 } catch (Exception e) {
189 result.SetComplete (e, 0);
192 if (callback != null)
193 callback (result);
195 return result;
198 // delegate void WriteDelegate (byte [] buffer, int offset, int count);
200 public virtual IAsyncResult
201 BeginWrite (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
203 if (!CanWrite)
204 throw new NotSupportedException ("This stream does not support writing");
206 // Creating a class derived from Stream that doesn't override BeginWrite
207 // shows that it actually calls Write and does everything synchronously except
208 // when invoking the callback, which is done from the ThreadPool.
209 // Just put this in the Write override:
210 // Console.WriteLine ("Write");
211 // Console.WriteLine (Environment.StackTrace);
212 // Thread.Sleep (10000);
214 StreamAsyncResult result = new StreamAsyncResult (state);
215 try {
216 Write (buffer, offset, count);
217 result.SetComplete (null);
218 } catch (Exception e) {
219 result.SetComplete (e);
222 if (callback != null)
223 callback.BeginInvoke (result, null, null);
225 return result;
228 public virtual int EndRead (IAsyncResult asyncResult)
230 if (asyncResult == null)
231 throw new ArgumentNullException ("asyncResult");
233 StreamAsyncResult result = asyncResult as StreamAsyncResult;
234 if (result == null || result.NBytes == -1)
235 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
237 if (result.Done)
238 throw new InvalidOperationException ("EndRead already called.");
240 result.Done = true;
241 if (result.Exception != null)
242 throw result.Exception;
244 return result.NBytes;
247 public virtual void EndWrite (IAsyncResult asyncResult)
249 if (asyncResult == null)
250 throw new ArgumentNullException ("asyncResult");
252 StreamAsyncResult result = asyncResult as StreamAsyncResult;
253 if (result == null || result.NBytes != -1)
254 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
256 if (result.Done)
257 throw new InvalidOperationException ("EndWrite already called.");
259 result.Done = true;
260 if (result.Exception != null)
261 throw result.Exception;
264 #if MOONLIGHT || NET_4_0
265 public void CopyTo (Stream destination)
267 CopyTo (destination, 16*1024);
270 public void CopyTo (Stream destination, int bufferSize)
272 if (destination == null)
273 throw new ArgumentNullException ("destination");
274 if (!CanRead)
275 throw new NotSupportedException ("This stream does not support reading");
276 if (!destination.CanWrite)
277 throw new NotSupportedException ("This destination stream does not support writing");
278 if (bufferSize <= 0)
279 throw new ArgumentOutOfRangeException ("bufferSize");
281 var buffer = new byte [bufferSize];
282 int nread;
283 while ((nread = Read (buffer, 0, bufferSize)) != 0)
284 destination.Write (buffer, 0, nread);
287 protected virtual void ObjectInvariant ()
290 #endif
293 class NullStream : Stream
295 public override bool CanRead
297 get {
298 return true;
302 public override bool CanSeek
304 get {
305 return true;
309 public override bool CanWrite
311 get {
312 return true;
316 public override long Length
318 get {
319 return 0;
323 public override long Position
325 get {
326 return 0;
328 set {
332 public override void Flush ()
336 public override int Read (byte[] buffer, int offset, int count)
338 return 0;
341 public override int ReadByte ()
343 return -1;
346 public override long Seek (long offset, SeekOrigin origin)
348 return 0;
351 public override void SetLength (long value)
355 public override void Write (byte[] buffer, int offset, int count)
359 public override void WriteByte (byte value)
364 class SynchronizedStream : Stream {
365 Stream source;
366 object slock;
368 internal SynchronizedStream (Stream source)
370 this.source = source;
371 slock = new object ();
374 public override bool CanRead
376 get {
377 lock (slock)
378 return source.CanRead;
382 public override bool CanSeek
384 get {
385 lock (slock)
386 return source.CanSeek;
390 public override bool CanWrite
392 get {
393 lock (slock)
394 return source.CanWrite;
398 public override long Length
400 get {
401 lock (slock)
402 return source.Length;
406 public override long Position
408 get {
409 lock (slock)
410 return source.Position;
412 set {
413 lock (slock)
414 source.Position = value;
418 public override void Flush ()
420 lock (slock)
421 source.Flush ();
424 public override int Read (byte[] buffer, int offset, int count)
426 lock (slock)
427 return source.Read (buffer, offset, count);
430 public override int ReadByte ()
432 lock (slock)
433 return source.ReadByte ();
436 public override long Seek (long offset, SeekOrigin origin)
438 lock (slock)
439 return source.Seek (offset, origin);
442 public override void SetLength (long value)
444 lock (slock)
445 source.SetLength (value);
448 public override void Write (byte[] buffer, int offset, int count)
450 lock (slock)
451 source.Write (buffer, offset, count);
454 public override void WriteByte (byte value)
456 lock (slock)
457 source.WriteByte (value);