Skip to content

Commit 2fb0e5b

Browse files
committed
Ported over improvements from Sys.IO.FileStream
(improvements from @Ellerbach)
1 parent 866528c commit 2fb0e5b

File tree

1 file changed

+83
-88
lines changed

1 file changed

+83
-88
lines changed

System.IO.Streams/MemoryStream.cs

Lines changed: 83 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ namespace System.IO
1111
/// </summary>
1212
public class MemoryStream : Stream
1313
{
14+
private const int CapacityDefaultSize = 256;
15+
1416
// Either allocated internally or externally.
1517
private byte[] _buffer;
1618
// For user-provided arrays, start at this origin
@@ -41,8 +43,8 @@ public class MemoryStream : Stream
4143
/// </remarks>
4244
public MemoryStream()
4345
{
44-
_buffer = new byte[256];
45-
_capacity = 256;
46+
_buffer = new byte[CapacityDefaultSize];
47+
_capacity = CapacityDefaultSize;
4648
_expandable = true;
4749

4850
// Must be 0 for byte[]'s created by MemoryStream
@@ -124,52 +126,6 @@ protected override void Dispose(bool disposing)
124126
}
125127
}
126128

127-
// returns a bool saying whether we allocated a new array.
128-
private bool EnsureCapacity(int value)
129-
{
130-
if (value > _capacity)
131-
{
132-
int newCapacity = value;
133-
134-
if (newCapacity < 256)
135-
{
136-
newCapacity = 256;
137-
}
138-
139-
if (newCapacity < _capacity * 2)
140-
{
141-
newCapacity = _capacity * 2;
142-
}
143-
144-
if (!_expandable && newCapacity > _capacity)
145-
{
146-
throw new NotSupportedException();
147-
}
148-
149-
if (newCapacity > 0)
150-
{
151-
byte[] newBuffer = new byte[newCapacity];
152-
153-
if (_length > 0)
154-
{
155-
Array.Copy(_buffer, 0, newBuffer, 0, _length);
156-
}
157-
158-
_buffer = newBuffer;
159-
}
160-
else
161-
{
162-
_buffer = null;
163-
}
164-
165-
_capacity = newCapacity;
166-
167-
return true;
168-
}
169-
170-
return false;
171-
}
172-
173129
/// <inheritdoc/>
174130
public override void Flush()
175131
{
@@ -197,34 +153,27 @@ public override long Length
197153
{
198154
get
199155
{
200-
if (!_isOpen)
201-
{
202-
throw new ObjectDisposedException();
203-
}
156+
EnsureOpen();
204157

205158
return _length - _origin;
206159
}
207160
}
208161

209162
/// <inheritdoc/>
163+
///<exception cref="IOException">Can't adjust position out of the buffer size for fixed size buffer</exception>
164+
///<exception cref="ArgumentOutOfRangeException">Position can't be negative or higher than the stream allocated size.</exception>
210165
public override long Position
211166
{
212167
get
213168
{
214-
if (!_isOpen)
215-
{
216-
throw new ObjectDisposedException();
217-
}
169+
EnsureOpen();
218170

219171
return _position - _origin;
220172
}
221173

222174
set
223175
{
224-
if (!_isOpen)
225-
{
226-
throw new ObjectDisposedException();
227-
}
176+
EnsureOpen();
228177

229178
if (value < 0 || value > MemStreamMaxLength)
230179
{
@@ -246,10 +195,7 @@ public override int Read(
246195
int offset,
247196
int count)
248197
{
249-
if (!_isOpen)
250-
{
251-
throw new ObjectDisposedException();
252-
}
198+
EnsureOpen();
253199

254200
if (buffer == null)
255201
{
@@ -288,10 +234,7 @@ public override int Read(
288234
/// <exception cref="ObjectDisposedException">The current stream instance is closed.</exception>
289235
public override int ReadByte()
290236
{
291-
if (!_isOpen)
292-
{
293-
throw new ObjectDisposedException();
294-
}
237+
EnsureOpen();
295238

296239
if (_position >= _length)
297240
{
@@ -314,10 +257,7 @@ public override long Seek(
314257
long offset,
315258
SeekOrigin origin)
316259
{
317-
if (!_isOpen)
318-
{
319-
throw new ObjectDisposedException();
320-
}
260+
EnsureOpen();
321261

322262
if (offset > MemStreamMaxLength)
323263
{
@@ -363,10 +303,7 @@ public override long Seek(
363303
/// <inheritdoc/>
364304
public override void SetLength(long value)
365305
{
366-
if (!_isOpen)
367-
{
368-
throw new ObjectDisposedException();
369-
}
306+
EnsureOpen();
370307

371308
if (value > MemStreamMaxLength || value < 0)
372309
{
@@ -402,10 +339,7 @@ public virtual byte[] ToArray()
402339
/// <inheritdoc/>
403340
public override void Write(byte[] buffer, int offset, int count)
404341
{
405-
if (!_isOpen)
406-
{
407-
throw new ObjectDisposedException();
408-
}
342+
EnsureOpen();
409343

410344
if (buffer == null)
411345
{
@@ -442,10 +376,7 @@ public override void Write(byte[] buffer, int offset, int count)
442376
/// <inheritdoc/>
443377
public override void WriteByte(byte value)
444378
{
445-
if (!_isOpen)
446-
{
447-
throw new ObjectDisposedException();
448-
}
379+
EnsureOpen();
449380

450381
if (_position >= _capacity)
451382
{
@@ -460,20 +391,84 @@ public override void WriteByte(byte value)
460391
}
461392
}
462393

463-
/// <inheritdoc/>
394+
/// <summary>
395+
/// Writes this MemoryStream to another stream.
396+
/// </summary>
397+
/// <param name="stream">Stream to write into.</param>
398+
/// <exception cref="ArgumentNullException">If <paramref name="stream"/> is <see langword="null"/>.</exception>
464399
public virtual void WriteTo(Stream stream)
400+
{
401+
EnsureOpen();
402+
403+
if (stream == null)
404+
{
405+
throw new ArgumentNullException();
406+
}
407+
408+
stream.Write(_buffer, _origin, _length - _origin);
409+
}
410+
411+
/// <summary>
412+
/// Check that stream is open.
413+
/// </summary>
414+
/// <exception cref="ObjectDisposedException"></exception>
415+
private void EnsureOpen()
465416
{
466417
if (!_isOpen)
467418
{
468419
throw new ObjectDisposedException();
469420
}
421+
}
470422

471-
if (stream == null)
423+
/// <summary>
424+
/// Verifies that there is enough capacity in the stream.
425+
/// </summary>
426+
/// <param name="value">Value for the new capacity.</param>
427+
/// <returns><see langword="true"/> if allocation for a new array was successful. <see langword="false"/> otherwise.</returns>
428+
/// <exception cref="NotSupportedException"></exception>
429+
private bool EnsureCapacity(int value)
430+
{
431+
if (value > _capacity)
472432
{
473-
throw new ArgumentNullException();
433+
int newCapacity = value;
434+
435+
if (newCapacity < CapacityDefaultSize)
436+
{
437+
newCapacity = CapacityDefaultSize;
438+
}
439+
440+
if (newCapacity < _capacity * 2)
441+
{
442+
newCapacity = _capacity * 2;
443+
}
444+
445+
if (!_expandable && newCapacity > _capacity)
446+
{
447+
throw new NotSupportedException();
448+
}
449+
450+
if (newCapacity > 0)
451+
{
452+
byte[] newBuffer = new byte[newCapacity];
453+
454+
if (_length > 0)
455+
{
456+
Array.Copy(_buffer, 0, newBuffer, 0, _length);
457+
}
458+
459+
_buffer = newBuffer;
460+
}
461+
else
462+
{
463+
_buffer = null;
464+
}
465+
466+
_capacity = newCapacity;
467+
468+
return true;
474469
}
475470

476-
stream.Write(_buffer, _origin, _length - _origin);
471+
return false;
477472
}
478473
}
479474
}

0 commit comments

Comments
 (0)