Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Alberto Cortez <calberto.cortez@gmail.com>2010-01-04 06:46:31 +0300
committerCarlos Alberto Cortez <calberto.cortez@gmail.com>2010-01-04 06:46:31 +0300
commit992a4b5afca86f440395aa95d1c7469937f47aa8 (patch)
treec9a4dbd57ef73ee69d326f525e511d28c37483d0 /mcs/class/corlib/System.IO/MemoryStream.cs
parent611f32df81108d843229dd6e3f92da299e4faf88 (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.cs36
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;
}