X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.IO%2FUnmanagedMemoryStream.cs;h=4342766f6c120bcbe1a175d96648d61e9b0863c3;hb=7c970f8ee1f635da8575bcf58d89c16bb5c2ace1;hp=2bec7e0739e82f5d39ebb3112d5324fb4710bcdb;hpb=5b795199007384eb5ae2356cf9877a8f3e13905c;p=mono.git diff --git a/mcs/class/corlib/System.IO/UnmanagedMemoryStream.cs b/mcs/class/corlib/System.IO/UnmanagedMemoryStream.cs index 2bec7e0739e..4342766f6c1 100644 --- a/mcs/class/corlib/System.IO/UnmanagedMemoryStream.cs +++ b/mcs/class/corlib/System.IO/UnmanagedMemoryStream.cs @@ -1,14 +1,11 @@ -//------------------------------------------------------------------------------ // // System.IO.UnmanagedMemoryStream.cs // // Copyright (C) 2006 Sridhar Kulkarni, All Rights Reserved // -// Author: Sridhar Kulkarni (sridharkulkarni@gmail.com) -// Created: Monday, July 10, 2006 -// -//------------------------------------------------------------------------------ - +// Authors: +// Sridhar Kulkarni (sridharkulkarni@gmail.com) +// Gert Driesen (drieseng@users.sourceforge.net) // // Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com) // @@ -38,7 +35,6 @@ using System; using System.IO; using System.Runtime.InteropServices; - namespace System.IO { [CLSCompliantAttribute(false)] @@ -54,6 +50,8 @@ namespace System.IO long initial_position; long current_position; + internal event EventHandler Closed; + #region Constructor protected UnmanagedMemoryStream() { @@ -64,15 +62,15 @@ namespace System.IO current_position = initial_position; } - public unsafe UnmanagedMemoryStream (byte *pointer, long len) + public unsafe UnmanagedMemoryStream (byte *pointer, long length) { 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"); + throw new ArgumentNullException("pointer"); + if (length < 0) + throw new ArgumentOutOfRangeException("length", "Non-negative number required."); fileaccess = FileAccess.Read; - length = len; - capacity = len; + this.length = length; + capacity = length; initial_position = 0; current_position = initial_position; canseek = true; @@ -80,19 +78,21 @@ namespace System.IO initial_pointer = new IntPtr((void*)pointer); } - public unsafe UnmanagedMemoryStream (byte *pointer, long len, long cap, FileAccess access) + public unsafe UnmanagedMemoryStream (byte *pointer, long length, long capacity, 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"); + throw new ArgumentNullException("pointer"); + if (length < 0) + throw new ArgumentOutOfRangeException("length", "Non-negative number required."); 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"); + throw new ArgumentOutOfRangeException("capacity", "Non-negative number required."); + if (length > capacity) + throw new ArgumentOutOfRangeException("length", "The length cannot be greater than the capacity."); + if (!Enum.IsDefined (typeof (FileAccess), access)) + throw new ArgumentOutOfRangeException ("access", "Enum value was out of legal range."); fileaccess = access; - length = len; - capacity = cap; + this.length = length; + this.capacity = capacity; initial_position = 0; current_position = initial_position; canseek = true; @@ -107,14 +107,13 @@ namespace System.IO get { if (closed) return false; - else - return ((fileaccess == FileAccess.Read || fileaccess == FileAccess.ReadWrite)? true:false); + return (fileaccess == FileAccess.Read || fileaccess == FileAccess.ReadWrite); } } public override bool CanSeek { get { - return ((closed) ? false : true); + return !closed; } } @@ -122,8 +121,7 @@ namespace System.IO get { if (closed) return (false); - else - return ((fileaccess == FileAccess.Write || fileaccess == FileAccess.ReadWrite)? true:false); + return (fileaccess == FileAccess.Write || fileaccess == FileAccess.ReadWrite); } } public long Capacity { @@ -146,16 +144,16 @@ namespace System.IO get { if (closed) throw new ObjectDisposedException("The stream is closed"); - else - return (current_position); + 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; + if (value < 0) + throw new ArgumentOutOfRangeException("value", "Non-negative number required."); + if (value > (long)Int32.MaxValue) + throw new ArgumentOutOfRangeException("value", "The position is larger than Int32.MaxValue."); + current_position = value; } } @@ -175,56 +173,44 @@ namespace System.IO 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"); + throw new ArgumentNullException("buffer"); + if (offset < 0) + throw new ArgumentOutOfRangeException("offset", "Non-negative number required."); + if (count < 0) + throw new ArgumentOutOfRangeException("count", "Non-negative number required."); 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"); + throw new NotSupportedException("Stream does not support reading"); else { - if (current_position == capacity) + if (current_position >= length) return (0); else { - unsafe { - Marshal.Copy(initial_pointer, buffer, offset, - (int)length); - current_position += length; - } - return (buffer.GetLength(0)); + int progress = current_position + count < length ? count : (int) (length - current_position); + for (int i = 0; i < progress; i++) + buffer [offset + i] = Marshal.ReadByte (initial_pointer, (int) current_position++); + return progress; } } } 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"); + throw new NotSupportedException("Stream does not support reading"); else { - if (current_position == length) + if (current_position >= length) return (-1); - else { - unsafe { - byteread = (int)Marshal.ReadByte(initial_pointer, (int)current_position); - current_position++; - } - return(byteread); - } + return (int) Marshal.ReadByte(initial_pointer, (int) current_position++); } } 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: @@ -241,7 +227,7 @@ namespace System.IO default: throw new ArgumentException("Invalid SeekOrigin option"); } - refpoint =+ (int)offset; + 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; @@ -252,14 +238,15 @@ namespace System.IO { if (closed) throw new ObjectDisposedException("The stream is closed"); - if (value < 0 || value > capacity) - throw new ArgumentOutOfRangeException("The specified value is negative or exceeds the capacity of the stream"); - if (fileaccess == FileAccess.Read) - throw new NotSupportedException("write property is set to false"); + if (value < 0) + throw new ArgumentOutOfRangeException("length", "Non-negative number required."); + if (value > capacity) + throw new IOException ("Unable to expand length of this stream beyond its capacity."); if (fileaccess == FileAccess.Read) - throw new NotSupportedException("Length change not supported; see object construction"); - else - length = value; + throw new NotSupportedException ("Stream does not support writing."); + length = value; + if (length < current_position) + current_position = length; } public override void Flush () @@ -272,8 +259,11 @@ namespace System.IO protected override void Dispose (bool disposing) { - + if (closed) + return; closed = true; + if (Closed != null) + Closed (this, null); } public override void Write (byte[] buffer, int offset, int count) @@ -282,19 +272,25 @@ namespace System.IO 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 ((current_position + count) > capacity) + throw new NotSupportedException ("Unable to expand length of this stream beyond its capacity."); + if (offset < 0) + throw new ArgumentOutOfRangeException("offset", "Non-negative number required."); + if (count < 0) + throw new ArgumentOutOfRangeException("count", "Non-negative number required."); 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"); + throw new NotSupportedException ("Stream does not support writing."); else { unsafe { - //COPY data from managed buffer to unmanaged mem pointer - Marshal.Copy(buffer, offset, initial_pointer, (int)length); - current_position += length; + // use Marshal.WriteByte since that allow us to start writing + // from the current position + for (int i = 0; i < count; i++) + Marshal.WriteByte (initial_pointer, (int) current_position++, buffer [offset + i]); + + if (current_position > length) + length = current_position; } } } @@ -307,11 +303,13 @@ namespace System.IO 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"); + throw new NotSupportedException("Stream does not support writing."); else { unsafe { Marshal.WriteByte(initial_pointer, (int)current_position, value); current_position++; + if (current_position > length) + length = current_position; } } }