class · System.IO
BufferedStream
public class BufferedStream : Stream
A buffer in front of another stream: small reads and writes become few large ones.
- Tipo
- class
- Espacio de nombres
- System.IO
- Ensamblado
- System.Core
- Acceso
- public
- Archivo fuente
Stream.ant
Herencia
Constructores
Propiedades
The stream behind the buffer.
Métodos
Miembros privados e internos (7)
Miembros heredados (11)
Código fuente
BufferedStream en Antril, descompilado a partir de su Larva HIR.
// System.IO.BufferedStream — System.Core (decompiled from Larva HIR)
import System;
into namespace System.IO
{
/// A buffer in front of another stream: small reads and writes become few large ones.
public class BufferedStream : Stream
{
Stream inner;
u8[] buffer;
/// Bytes read ahead: buffer[readAt..readEnd].
i32 readAt;
i32 readEnd;
/// Bytes not written yet: buffer[0..writeEnd].
i32 writeEnd;
FlushWrites()
{
if (writeEnd > 0)
{
inner.Write(buffer, 0, writeEnd);
writeEnd = 0;
}
}
/// Gives back the bytes read ahead (moving the inner stream back to where this one is).
DropReads()
{
if (readAt < readEnd && inner.CanSeek)
inner.Seek((i64)readAt - (i64)readEnd, SeekOrigin.Current);
readAt = 0;
readEnd = 0;
}
public:
new(Stream stream) : (stream, 4096)
{
}
new(Stream stream, i32 bufferSize)
{
if (bufferSize <= 0)
throw new ArgumentError("BufferedStream: the buffer size must be positive");
inner = stream;
buffer = new u8[bufferSize];
}
override Read(u8[] target, i32 offset, i32 count) : i32
{
i32 buffered = readEnd - readAt;
if (buffered == 0)
{
FlushWrites();
if (count >= buffer.Length)
return inner.Read(target, offset, count);
readAt = 0;
readEnd = inner.Read(buffer, 0, buffer.Length);
buffered = readEnd;
if (buffered == 0)
return 0;
}
i32 n = buffered < count ? buffered : count;
Array.Copy(buffer, readAt, target, offset, n);
readAt += n;
return n;
}
override ReadByte() : i32
{
if (readAt < readEnd)
{
readAt++;
return (i32)buffer[readAt - 1];
}
FlushWrites();
readAt = 0;
readEnd = inner.Read(buffer, 0, buffer.Length);
if (readEnd == 0)
return -1;
readAt = 1;
return (i32)buffer[0];
}
override Write(u8[] source, i32 offset, i32 count)
{
if (readEnd > 0)
DropReads();
if (writeEnd == 0 && count >= buffer.Length)
{
inner.Write(source, offset, count);
return;
}
if (writeEnd + count <= buffer.Length)
{
Array.Copy(source, offset, buffer, writeEnd, count);
writeEnd += count;
return;
}
FlushWrites();
if (count >= buffer.Length)
{
inner.Write(source, offset, count);
return;
}
Array.Copy(source, offset, buffer, 0, count);
writeEnd = count;
}
override WriteByte(u8 value)
{
if (readEnd == 0 && writeEnd < buffer.Length)
{
buffer[writeEnd] = value;
writeEnd++;
return;
}
if (readEnd > 0)
DropReads();
if (writeEnd == buffer.Length)
FlushWrites();
buffer[writeEnd] = value;
writeEnd++;
}
override Seek(i64 offset, SeekOrigin origin) : i64
{
if (!inner.CanSeek)
throw new IOError("the stream cannot seek");
FlushWrites();
if (origin == SeekOrigin.Current)
offset -= (i64)readEnd - (i64)readAt;
readAt = 0;
readEnd = 0;
return inner.Seek(offset, origin);
}
override SetLength(i64 length)
{
FlushWrites();
DropReads();
inner.SetLength(length);
}
override Flush()
{
FlushWrites();
inner.Flush();
}
override Close()
{
FlushWrites();
inner.Close();
}
/// The stream behind the buffer.
Stream UnderlyingStream
{
get => inner;
}
i32 BufferSize
{
get => buffer.Length;
}
override bool CanRead
{
get => inner.CanRead;
}
override bool CanWrite
{
get => inner.CanWrite;
}
override bool CanSeek
{
get => inner.CanSeek;
}
override i64 Length
{
get
{
FlushWrites();
return inner.Length;
}
}
override i64 Position
{
get => inner.Position - ((i64)readEnd - (i64)readAt) + (i64)writeEnd;
set
{
Seek(value, SeekOrigin.Begin);
}
}
}
}