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

Clases base
Any Stream MemoryStream

Constructores

new()
#
new(i32 capacity)
#
new(u8[] buffer)
#

Over buffer (its bytes are the stream's, it does not grow).

new(u8[] buffer, bool writable)
#

Propiedades

override bool CanRead { get; }
#

read-only

override bool CanWrite { get; }
#

read-only

override bool CanSeek { get; }
#

read-only

override i64 Length { get; }
#

read-only

override i64 Position { get; set; }
#
i32 Capacity { get; }
#

read-only

How many bytes fit before it grows.

Métodos

override Read(u8[] buffer, i32 offset, i32 count) : i32
#

override

override ReadByte() : i32
#

override

override Write(u8[] buffer, i32 offset, i32 count)
#

override

override WriteByte(u8 value)
#

override

override Seek(i64 offset, SeekOrigin origin) : i64
#

override

override SetLength(i64 newLength)
#

override

override Close()
#

override

ToArray() : u8[]
#

A copy of its bytes.

GetBuffer() : u8[]
#

The array it keeps its bytes in (Length of them are the stream's).

WriteTo(Stream destination)
#

Writes all its bytes into destination.

Miembros privados e internos (13)

u8[] data
#

private

i32 length
#

private

i32 position
#

private

bool writable
#

private

bool growable
#

private

bool open
#

private

i32 room
#

private

Where a write can go without the slow path: data.Length when open and writable, else 0.

static Closed()
#

private static

The throw is kept out of the methods that check (so they stay small enough to inline).

static ReadOnly()
#

private static

Check()
#

private

Reserve(i32 needed)
#

private

Room for at least needed bytes.

Grow(i32 needed)
#

private

WriteByteSlow(u8 value)
#

private

Miembros heredados (12)

Código fuente

MemoryStream en Antril, descompilado a partir de su Larva HIR.

System.IO.MemoryStream.ant
// 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;
			}
	}
}
Esc