Author: miguel
Date: 2007-01-13 02:08:52 -0500 (Sat, 13 Jan 2007)
New Revision: 70953

Added:
   trunk/mcs/class/corlib/System.IO/UnmanagedMemoryStream.cs
Log:
Patch from Sridhar Kulkarni (full impl)

Added: trunk/mcs/class/corlib/System.IO/UnmanagedMemoryStream.cs
===================================================================
--- trunk/mcs/class/corlib/System.IO/UnmanagedMemoryStream.cs   2007-01-13 
07:05:49 UTC (rev 70952)
+++ trunk/mcs/class/corlib/System.IO/UnmanagedMemoryStream.cs   2007-01-13 
07:08:52 UTC (rev 70953)
@@ -0,0 +1,328 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.UnmanagedMemoryStream.cs
+//
+// Copyright (C) 2006 Sridhar Kulkarni, All Rights Reserved
+//
+// Author:         Sridhar Kulkarni ([EMAIL PROTECTED])
+// Created:        Monday, July 10, 2006
+//
+//------------------------------------------------------------------------------
+
+//
+// Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+
+namespace System.IO
+{
+       [CLSCompliantAttribute(false)]
+       public class UnmanagedMemoryStream : Stream
+       {
+               long length;
+               bool closed;
+               bool canseek = false;
+               long capacity;
+               FileAccess fileaccess;
+               IntPtr initial_pointer;
+               IntPtr pointer_position;
+               long initial_position;
+               long current_position;
+               
+#region Constructor
+               protected UnmanagedMemoryStream()
+               {
+                       fileaccess = FileAccess.Read;
+                       initial_position = 0;
+                       canseek = true;
+                       closed = false;
+                       current_position = initial_position;
+               }
+               
+               public unsafe UnmanagedMemoryStream (byte *pointer, long len)
+               {
+                       if (pointer == null)
+                               throw new ArgumentNullException("The pointer 
value is a null reference ");
+                       if (len < 0)
+                               throw new ArgumentOutOfRangeException("The 
length value is less than zero");
+                       fileaccess = FileAccess.Read;
+                       length = len;
+                       capacity = len;
+                       initial_position = 0;
+                       current_position = initial_position;
+                       canseek = true;
+                       closed = false;
+                       initial_pointer = new IntPtr((void*)pointer);
+               }
+               
+               public unsafe UnmanagedMemoryStream (byte *pointer, long len, 
long cap, FileAccess access)
+               {
+                       if (pointer == null)
+                               throw new ArgumentNullException("The pointer 
value is a null reference");
+                       if (len < 0)
+                               throw new ArgumentOutOfRangeException("The 
length value is less than zero");
+                       if (capacity < 0)
+                               throw new ArgumentOutOfRangeException("The 
capacity value is less than zero");
+                       if (len > capacity)
+                               throw new ArgumentOutOfRangeException("The 
length value is greater than the capacity value");
+                       fileaccess = access;
+                       length = len;
+                       capacity = cap;
+                       initial_position = 0;
+                       current_position = initial_position;
+                       canseek = true;
+                       initial_pointer = new IntPtr ((void*)pointer);
+                       closed = false;
+                       fileaccess = access;
+               }
+#endregion
+       
+#region Properties
+               public override bool CanRead {
+                       get {
+                               if (closed)
+                                       return false;
+                               else
+                                       return ((fileaccess == FileAccess.Read 
|| fileaccess == FileAccess.ReadWrite)? true:false);
+                       }
+               }
+
+               public override bool CanSeek {
+                       get {
+                               return ((closed) ? false : true);
+                       }
+               }
+               
+               public override bool CanWrite {
+                       get {
+                               if (closed)
+                                       return (false);
+                               else
+                                       return ((fileaccess == FileAccess.Write 
|| fileaccess == FileAccess.ReadWrite)? true:false);
+                       }
+               }
+               public long Capacity {
+                       get {
+                               if (closed)
+                                       throw new ObjectDisposedException("The 
stream is closed");
+                               else
+                                       return (capacity);
+                       }
+               }
+               public override long Length {
+                       get {
+                               if (closed)
+                                       throw new ObjectDisposedException("The 
stream is closed");
+                               else
+                                       return (length);
+                       }
+               }
+               public override long Position {
+                       get {
+                               if (closed)
+                                       throw new ObjectDisposedException("The 
stream is closed");
+                               else
+                                       return (current_position);
+                       }
+                       set {
+                               if (closed)
+                                       throw new ObjectDisposedException("The 
stream is closed");
+                               if (value < 0 || value > (long)Int32.MaxValue 
|| value > capacity)
+                                       throw new 
ArgumentOutOfRangeException("value that is less than zero, or the position is 
larger than Int32.MaxValue or capacity of the stream");
+                               else
+                                       current_position = value;
+                       }
+               }
+
+               public unsafe byte* PositionPointer {
+                       get {
+                               throw new NotImplementedException("Error");
+                       }
+                       set {
+                               throw new NotImplementedException("Error");
+                       }
+               }
+#endregion
+               
+#region Methods
+               public override int Read ([InAttribute] [OutAttribute] byte[] 
buffer, int offset, int count)
+                        {
+                               if (closed)
+                                       throw new ObjectDisposedException("The 
stream is closed");
+
+
+                               if (buffer == null)
+                                       throw new ArgumentNullException("The 
buffer parameter is set to a null reference");
+                               if (offset < 0 || count < 0)
+                                       throw new 
ArgumentOutOfRangeException("The offset or count parameter is less than zero");
+                               if ((buffer.Length - offset) < count)
+                                       throw new ArgumentException("The length 
of the buffer array minus the offset parameter is less than the count 
parameter");
+
+                               if (fileaccess == FileAccess.Write)
+                                       throw new NotSupportedException("Read 
property is false");
+                               else {
+                                       if (current_position == capacity)
+                                               return (0);
+                                       else {
+                                               unsafe {
+                                                       
Marshal.Copy(initial_pointer, buffer, offset, 
+                                                                    
(int)length);
+                                                       current_position += 
length;
+                                               }
+                                               return (buffer.GetLength(0));
+                                       }
+                               }
+                       }
+               public override int ReadByte () {
+                       if (closed)
+                               throw new ObjectDisposedException("The stream 
is closed");
+                       if (current_position == capacity)
+                               throw new NotSupportedException("The current 
position is at the end of the stream");
+
+                       int byteread;
+
+                       if (fileaccess== FileAccess.Write)
+                               throw new NotSupportedException("The underlying 
memory does not support reading");
+                       else {
+                               if (current_position == length)
+                                       return (-1);
+                               else {
+                                       unsafe {
+                                               byteread = 
(int)Marshal.ReadByte(initial_pointer, (int)current_position);
+                                               current_position++;
+                                       }
+                                       return(byteread);
+                               }
+                       }
+               }
+               public override long Seek (long offset, SeekOrigin loc) {
+                       if (closed)
+                               throw new ObjectDisposedException("The stream 
is closed");
+                       if (offset > capacity)
+                               throw new ArgumentOutOfRangeException("The 
offset value is larger than the maximum size of the stream");
+                       long refpoint;
+                       switch(loc) {
+                       case SeekOrigin.Begin:
+                               if (offset < 0)
+                                       throw new IOException("An attempt was 
made to seek before the beginning of the stream");
+                               refpoint = initial_position;
+                               break;
+                       case SeekOrigin.Current:
+                               refpoint = current_position;
+                               break;
+                       case SeekOrigin.End:
+                               refpoint = length;
+                               break;
+                       default:
+                               throw new ArgumentException("Invalid SeekOrigin 
option");
+                               break;
+                       }
+                       refpoint =+ (int)offset;
+                       if (refpoint < initial_position)
+                               throw new IOException("An attempt was made to 
seek before the beginning of the stream");
+                       current_position = refpoint;
+                       return(current_position);
+               }
+                
+               public override void SetLength (long value)
+               {
+                       if (closed)
+                               throw new ObjectDisposedException("The stream 
is closed");
+                       if (value < 0 || value > capacity)
+                               throw new ArgumentOutOfRangeException("The 
specified value is negetive exceeds the capacity of the stream");
+                       if (fileaccess == FileAccess.Read)
+                               throw new NotSupportedException("write property 
is set to false");
+                       if (fileaccess == FileAccess.Read)
+                               throw new NotSupportedException("Length change 
not supported see object construction");
+                       else
+                               length = value;
+               }
+
+               public override void Flush ()
+               {
+                       if (closed)
+                               throw new ObjectDisposedException("The stream 
is closed");
+                       //This method performs no action for this class
+                       //but is included as part of the Stream base class
+               }
+                
+               public void Dispose ()
+               {
+                       Dispose(true);
+               }
+                
+               protected override void Dispose (bool disposing)
+               {
+
+                       closed = true;
+               }
+                
+               public override void Write (byte[] buffer, int offset, int 
count)
+               {
+                       if (closed)
+                               throw new ObjectDisposedException("The stream 
is closed");
+                       if (buffer == null)
+                               throw new ArgumentNullException("The buffer 
parameter is a null reference");
+                       if (count > capacity)
+                               throw new ArgumentOutOfRangeException("The 
count value is greater than the capacity of the stream");
+                       if (offset < 0 || count < 0)
+                               throw new ArgumentOutOfRangeException("One of 
the specified parameters is less than zero");
+                       if ((buffer.Length - offset) < count)
+                               throw new ArgumentException("The length of the 
buffer array minus the offset parameter is less than the count parameter");
+                       if (fileaccess == FileAccess.Read)
+                               throw new NotSupportedException("write property 
is set to false");
+                       else {
+                               unsafe {
+                                       //COPY data from managed buffer to 
unmanaged mem pointer
+                                       Marshal.Copy(buffer, offset, 
initial_pointer, (int)length);
+                                       current_position += length;
+                               }
+                       }
+               }
+               
+               public override void WriteByte (byte value)
+                {
+                       if (closed)
+                               throw new ObjectDisposedException("The stream 
is closed");
+                       
+                       if (current_position == capacity)
+                               throw new NotSupportedException("The current 
position is at the end of the capacity of the stream");
+                       if (fileaccess == FileAccess.Read)
+                               throw new NotSupportedException("write property 
is set to false");
+                       else {
+                               unsafe {
+                                       Marshal.WriteByte(initial_pointer, 
(int)current_position, value);
+                                       current_position++;
+                               }
+                       }
+               }
+#endregion
+       }
+}
+#endif
+


Property changes on: trunk/mcs/class/corlib/System.IO/UnmanagedMemoryStream.cs
___________________________________________________________________
Name: svn:eol-style
   + native

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to