diff options
author | Carlos Alberto Cortez <calberto.cortez@gmail.com> | 2010-01-04 06:46:31 +0300 |
---|---|---|
committer | Carlos Alberto Cortez <calberto.cortez@gmail.com> | 2010-01-04 06:46:31 +0300 |
commit | 992a4b5afca86f440395aa95d1c7469937f47aa8 (patch) | |
tree | c9a4dbd57ef73ee69d326f525e511d28c37483d0 /mcs/class/corlib/System.IO/MemoryStream.cs | |
parent | 611f32df81108d843229dd6e3f92da299e4faf88 (diff) |
2010-01-03 Carlos Alberto Cortez <calberto.cortez@gmail.com>
* MemoryStream.cs: Don't clear the bytes beyond Length when shrinking
it. Instead just save the related information for it and do it when
Length grows and touchs that dirty region. Refactor the code where
needed to avoid duplication as well.
Fixes #327053.
svn path=/trunk/mcs/; revision=148995
Diffstat (limited to 'mcs/class/corlib/System.IO/MemoryStream.cs')
-rw-r--r-- | mcs/class/corlib/System.IO/MemoryStream.cs | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/mcs/class/corlib/System.IO/MemoryStream.cs b/mcs/class/corlib/System.IO/MemoryStream.cs index 808225a440b..3d88cd08ff0 100644 --- a/mcs/class/corlib/System.IO/MemoryStream.cs +++ b/mcs/class/corlib/System.IO/MemoryStream.cs @@ -52,6 +52,7 @@ namespace System.IO bool expandable; bool streamClosed; int position; + int dirty_bytes; public MemoryStream () : this (0) { @@ -168,6 +169,7 @@ namespace System.IO Buffer.BlockCopy (internalBuffer, 0, newBuffer, 0, length); } + dirty_bytes = 0; // discard any dirty area beyond previous length internalBuffer = newBuffer; // It's null when capacity is set to 0 capacity = value; } @@ -311,6 +313,18 @@ namespace System.IO return minimum; } + void Expand (int newSize) + { + // We don't need to take into account the dirty bytes when incrementing the + // Capacity, as changing it will only preserve the valid clear region. + if (newSize > capacity) + Capacity = CalculateNewCapacity (newSize); + else if (dirty_bytes > 0) { + Array.Clear (internalBuffer, length, dirty_bytes); + dirty_bytes = 0; + } + } + public override void SetLength (long value) { if (!expandable && value > capacity) @@ -331,12 +345,11 @@ namespace System.IO throw new ArgumentOutOfRangeException (); int newSize = (int) value + initialIndex; - if (newSize > capacity) - Capacity = CalculateNewCapacity (newSize); - else if (newSize < length) - // zeroize present data (so we don't get it - // back if we expand the stream using Seek) - Array.Clear (internalBuffer, newSize, length - newSize); + + if (newSize > length) + Expand (newSize); + else if (newSize < length) // Postpone the call to Array.Clear till expand time + dirty_bytes += length - newSize; length = newSize; if (position > length) @@ -371,8 +384,8 @@ namespace System.IO "The size of the buffer is less than offset + count."); // reordered to avoid possible integer overflow - if (position > capacity - count) - Capacity = CalculateNewCapacity (position + count); + if (position > length - count) + Expand (position + count); Buffer.BlockCopy (buffer, offset, internalBuffer, position, count); position += count; @@ -386,11 +399,10 @@ namespace System.IO if (!canWrite) throw new NotSupportedException ("Cannot write to this stream."); - if (position >= capacity) - Capacity = CalculateNewCapacity (position + 1); - - if (position >= length) + if (position >= length) { + Expand (position + 1); length = position + 1; + } internalBuffer [position++] = value; } |