class · System.IO
StreamReader
public class StreamReader : TextReader
Text read from a stream as UTF-8 (a byte order mark at the start is skipped), through a buffer.
- Tipo
- class
- Espacio de nombres
- System.IO
- Ensamblado
- System.Core
- Acceso
- public
- Archivo fuente
TextIO.ant
Herencia
- Clases base
-
AnyTextReaderStreamReader
Constructores
Propiedades
The stream it reads from.
Whether everything has been read.
Métodos
Miembros privados e internos (10)
A line that does not fit in what is buffered gathers here.
Whether there are bytes to read (reading more when the buffer is used up).
The code point starting at the next byte, taken when take.
Miembros heredados (5)
GetTypemétodo de AnyUndescribedmétodo de AnyToStringmétodo de AnyHashmétodo de Anydestroymétodo de Any
Código fuente
StreamReader en Antril, descompilado a partir de su Larva HIR.
// System.IO.StreamReader — System.Core (decompiled from Larva HIR)
import System;
import System.Text;
into namespace System.IO
{
/// Text read from a stream as UTF-8 (a byte order mark at the start is skipped), through a buffer.
public class StreamReader : TextReader
{
Stream stream;
u8[] buffer;
i32 at;
i32 end;
bool started;
/// A line that does not fit in what is buffered gathers here.
u8[] pending;
i32 pendingLength;
/// Whether there are bytes to read (reading more when the buffer is used up).
Fill() : bool
{
if (at < end)
return true;
at = 0;
end = stream.Read(buffer, 0, buffer.Length);
if (!started)
{
started = true;
if (end >= 3 && buffer[0] == 239 && buffer[1] == 187 && buffer[2] == 191)
at = 3;
}
return at < end;
}
Keep(i32 from, i32 count)
{
if (pendingLength + count > pending.Length)
{
i32 capacity = pending.Length * 2;
if (capacity < pendingLength + count)
capacity = pendingLength + count;
u8[] grown = new u8[capacity];
Array.Copy(pending, 0, grown, 0, pendingLength);
pending = grown;
}
Array.Copy(buffer, from, pending, pendingLength, count);
pendingLength += count;
}
/// The code point starting at the next byte, taken when `take`.
Decode(bool take) : i32
{
if (!Fill())
return -1;
i32 b = (i32)buffer[at];
if (b < 128)
{
if (take)
at++;
return b;
}
i32 extra = b >= 245 ? 0 : b >= 240 ? 3 : b >= 224 ? 2 : b >= 194 ? 1 : 0;
if (extra == 0)
{
if (take)
at++;
return 65533;
}
if (at + extra >= end)
{
i32 left = end - at;
Array.Copy(buffer, at, buffer, 0, left);
at = 0;
end = left;
i32 read = stream.Read(buffer, end, buffer.Length - end);
loop (read > 0 && end + read <= extra)
{
end += read;
read = stream.Read(buffer, end, buffer.Length - end);
}
end += read;
if (extra >= end)
{
if (take)
at++;
return 65533;
}
}
i32 point = b & (extra == 1 ? 31 : extra == 2 ? 15 : 7);
loop (i32 k = 1..=extra)
{
i32 next = (i32)buffer[at + k];
if ((next & 192) != 128)
{
if (take)
at++;
return 65533;
}
point = point << 6 | next & 63;
}
if (take)
at += extra + 1;
return point;
}
public:
new(Stream stream) : (stream, 4096)
{
}
new(Stream stream, i32 bufferSize)
{
if (!stream.CanRead)
throw new ArgumentError("StreamReader: the stream cannot be read");
this.stream = stream;
buffer = new u8[bufferSize < 16 ? 16 : bufferSize];
pending = new u8[0];
}
new(str path) : (new FileStream(path, FileMode.Open, FileAccess.Read))
{
}
override Peek() : i32 => Decode(false);
override Read() : i32 => Decode(true);
override ReadLine() : str?
{
if (!Fill())
return null;
pendingLength = 0;
loop (true)
{
i32 i = at;
loop (i < end && buffer[i] != 10)
i++;
if (i < end)
{
i32 start = at;
at = i + 1;
if (pendingLength == 0)
return Encoding.UTF8.GetString(buffer, start, i > start && buffer[i - 1] == 13 ? i - start - 1 : i - start);
Keep(start, i - start);
return Encoding.UTF8.GetString(pending, 0, pending[pendingLength - 1] == 13 ? pendingLength - 1 : pendingLength);
}
Keep(at, end - at);
at = end;
if (!Fill())
{
i32 count = pendingLength > 0 && pending[pendingLength - 1] == 13 ? pendingLength - 1 : pendingLength;
return Encoding.UTF8.GetString(pending, 0, count);
}
}
return null;
}
override ReadToEnd() : str
{
pendingLength = 0;
loop (Fill())
{
Keep(at, end - at);
at = end;
}
return Encoding.UTF8.GetString(pending, 0, pendingLength);
}
override Close()
{
stream.Close();
}
/// The stream it reads from.
Stream BaseStream
{
get => stream;
}
/// Whether everything has been read.
bool EndOfStream
{
get => !Fill();
}
}
}