2 // System.IO.IntPtrStream: A stream that is backed up by unmanaged memory
5 // Miguel de Icaza (miguel@ximian.com)
7 // Based on the code for MemoryStream.cs:
9 // Authors: Marcin Szczepanski (marcins@zipworld.com.au)
10 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
12 // (c) 2001,2002 Marcin Szczepanski
13 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
17 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
19 // Permission is hereby granted, free of charge, to any person obtaining
20 // a copy of this software and associated documentation files (the
21 // "Software"), to deal in the Software without restriction, including
22 // without limitation the rights to use, copy, modify, merge, publish,
23 // distribute, sublicense, and/or sell copies of the Software, and to
24 // permit persons to whom the Software is furnished to do so, subject to
25 // the following conditions:
27 // The above copyright notice and this permission notice shall be
28 // included in all copies or substantial portions of the Software.
30 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 using System.Runtime.InteropServices;
42 namespace System.Web {
44 internal class IntPtrStream : Stream {
45 unsafe byte *base_address;
50 public IntPtrStream (IntPtr base_address, int size)
53 this.base_address = (byte*)((void *)base_address);
59 public IntPtrStream (Stream stream)
61 IntPtrStream st = (IntPtrStream) stream;
64 this.base_address = st.base_address;
68 protected IntPtr BaseAddress {
70 unsafe { return (IntPtr) base_address; }
78 public override bool CanRead {
84 public override bool CanSeek {
90 public override bool CanWrite {
96 public override long Position {
103 throw new ArgumentOutOfRangeException ("Position", "Can not be negative");
105 throw new ArgumentOutOfRangeException ("Position", "Pointer falls out of range");
107 position = (int) value;
111 public override long Length {
117 public override int Read (byte [] buffer, int offset, int count)
120 throw new ArgumentNullException ("buffer");
122 if (offset < 0 || count < 0)
123 throw new ArgumentOutOfRangeException ("offset or count less than zero.");
125 if (buffer.Length - offset < count )
126 throw new ArgumentException ("offset+count",
127 "The size of the buffer is less than offset + count.");
130 if (base_address == null)
131 throw new ObjectDisposedException ("Stream has been closed");
134 if (position >= size || count == 0)
137 if (position > size - count)
138 count = size - position;
141 Marshal.Copy ((IntPtr) (base_address + position), buffer, offset, count);
147 public override int ReadByte ()
149 if (position >= size)
153 if (base_address == null)
154 throw new ObjectDisposedException ("Stream has been closed");
158 return base_address [position++];
162 public override long Seek (long offset, SeekOrigin loc)
164 // It's funny that they don't throw this exception for < Int32.MinValue
165 if (offset > (long) Int32.MaxValue)
166 throw new ArgumentOutOfRangeException ("Offset out of range. " + offset);
169 if (base_address == null)
170 throw new ObjectDisposedException ("Stream has been closed");
175 case SeekOrigin.Begin:
177 throw new IOException ("Attempted to seek before start of MemoryStream.");
180 case SeekOrigin.Current:
181 ref_point = position;
187 throw new ArgumentException ("loc", "Invalid SeekOrigin");
192 ref_point += (int) offset;
194 throw new ArgumentOutOfRangeException ("Too large seek destination");
198 throw new IOException ("Attempted to seek before start of MemoryStream.");
201 position = ref_point;
205 public override void SetLength (long value)
207 throw new NotSupportedException ("This stream can not change its size");
210 public override void Write (byte [] buffer, int offset, int count)
212 throw new NotSupportedException ("This stream can not change its size");
215 public override void WriteByte (byte value)
217 throw new NotSupportedException ("This stream can not change its size");
220 public override void Flush ()
224 public override void Close ()
228 IntPtr ptr = (IntPtr) base_address;
229 if (ptr != IntPtr.Zero)
230 Marshal.FreeHGlobal (ptr);
240 IntPtr ptr = (IntPtr) base_address;
241 if (ptr != IntPtr.Zero)
242 Marshal.FreeHGlobal (ptr);