class · System.IO
MemoryStream
public class MemoryStream : Stream
Bytes kept in an array that grows as it is written (or in a fixed array given to it).
- Tipo
- class
- Espacio de nombres
- System.IO
- Ensamblado
- System.Core
- Acceso
- public
- Archivo fuente
Stream.ant
Herencia
Constructores
Propiedades
How many bytes fit before it grows.
Métodos
override Seek(i64 offset, SeekOrigin origin) : i64
#
override Close()
#
A copy of its bytes.
The array it keeps its bytes in (Length of them are the stream's).
Writes all its bytes into destination.
Miembros privados e internos (13)
Miembros heredados (12)
Código fuente
MemoryStream en Antril, descompilado a partir de su Larva HIR.
// System.IO.MemoryStream — System.Core (decompiled from Larva HIR)
import System;
into namespace System.IO
{
/// Bytes kept in an array that grows as it is written (or in a fixed array given to it).
public class MemoryStream : Stream
{
u8[] data;
i32 length;
i32 position;
bool writable;
bool growable;
bool open;
/// Where a write can go without the slow path: data.Length when open and writable, else 0.
i32 room;
/// The throw is kept out of the methods that check (so they stay small enough to inline).
[NoInline]
static Closed()
{
throw new IOError("the stream is closed");
}
[NoInline]
static ReadOnly()
{
throw new IOError("the memory stream is read-only");
}
Check()
{
if (!open)
Closed();
}
/// Room for at least `needed` bytes.
Reserve(i32 needed)
{
if (needed > data.Length)
Grow(needed);
}
[NoInline]
Grow(i32 needed)
{
if (!growable)
throw new IOError("the memory stream cannot grow");
i32 capacity = data.Length < 256 ? 256 : data.Length * 2;
if (capacity < needed)
capacity = needed;
u8[] grown = new u8[capacity];
Array.Copy(data, 0, grown, 0, length);
data = grown;
room = capacity;
}
[NoInline]
WriteByteSlow(u8 value)
{
Check();
if (!writable)
ReadOnly();
Reserve(position + 1);
loop (i32 i = length..position)
data[i] = 0;
data[position] = value;
position++;
if (position > length)
length = position;
}
public:
new() : (0)
{
}
new(i32 capacity)
{
data = new u8[capacity];
writable = true;
growable = true;
open = true;
room = capacity;
}
/// Over `buffer` (its bytes are the stream's, it does not grow).
new(u8[] buffer) : (buffer, true)
{
}
new(u8[] buffer, bool writable)
{
data = buffer;
length = buffer.Length;
this.writable = writable;
open = true;
room = writable ? buffer.Length : 0;
}
override Read(u8[] buffer, i32 offset, i32 count) : i32
{
Check();
i32 n = length - position;
if (n > count)
n = count;
if (n <= 0)
return 0;
if (n <= 16 && offset >= 0 && offset + n <= buffer.Length)
{
loop (i32 i = 0..n)
buffer[offset + i] = data[position + i];
}
else
{
Array.Copy(data, position, buffer, offset, n);
}
position += n;
return n;
}
override ReadByte() : i32
{
i32 at = position;
if (at < length && open)
{
position = at + 1;
return (i32)data[at];
}
Check();
return -1;
}
override Write(u8[] buffer, i32 offset, i32 count)
{
Check();
if (!writable)
ReadOnly();
i32 end = position + count;
Reserve(end);
loop (i32 i = length..position)
data[i] = 0;
if (count <= 16 && offset >= 0 && offset + count <= buffer.Length)
{
loop (i32 i = 0..count)
data[position + i] = buffer[offset + i];
}
else
{
Array.Copy(buffer, offset, data, position, count);
}
position = end;
if (end > length)
length = end;
}
override WriteByte(u8 value)
{
i32 at = position;
if (at < room && at <= length)
{
data[at] = value;
position = at + 1;
if (at == length)
length = at + 1;
return;
}
WriteByteSlow(value);
}
override Seek(i64 offset, SeekOrigin origin) : i64
{
Check();
i64 at = origin == SeekOrigin.Begin ? offset : origin == SeekOrigin.Current ? (i64)position + offset : (i64)length + offset;
if (at < 0 || at > 2147483647)
throw new IOError("MemoryStream.Seek: before the start");
position = (i32)at;
return at;
}
override SetLength(i64 newLength)
{
Check();
if (!writable)
throw new IOError("the memory stream is read-only");
if (newLength < 0 || newLength > 2147483647)
throw new ArgumentError("MemoryStream.SetLength: out of range");
i32 n = (i32)newLength;
Reserve(n);
loop (i32 i = length..n)
data[i] = 0;
length = n;
if (position > length)
position = length;
}
override Close()
{
open = false;
room = 0;
}
/// A copy of its bytes.
ToArray() : u8[]
{
u8[] copy = new u8[length];
Array.Copy(data, 0, copy, 0, length);
return copy;
}
/// The array it keeps its bytes in (Length of them are the stream's).
GetBuffer() : u8[] => data;
/// Writes all its bytes into `destination`.
WriteTo(Stream destination)
{
destination.Write(data, 0, length);
}
override bool CanRead
{
get => open;
}
override bool CanWrite
{
get => open && writable;
}
override bool CanSeek
{
get => open;
}
override i64 Length
{
get => length;
}
override i64 Position
{
get => position;
set
{
if (value < 0 || value > 2147483647)
throw new ArgumentError("MemoryStream.Position: out of range");
position = (i32)value;
}
}
/// How many bytes fit before it grows.
i32 Capacity
{
get => data.Length;
}
}
}