std/io
import std/io to use it. Source: src/std/io.iyi at v0.18.0.
The prelude's IyiIO reads and writes a descriptor. This module adds to it, on top of its public read_bytes/write only: read_byte, write_byte, read_char, lines, each_line, << and IyiIO.copy. Positioning (seek, pos, rewind) is not offered on a descriptor stream: the prelude has no seek intrinsic and its read buffer would make a kernel offset a lie.
Memory is an IyiIO over a byte buffer in memory: it grows as it is written, reads from a cursor that pos=, rewind and clear move, and to_s gives back everything written. Anything that takes an IyiIO takes a Memory.
Sized reads at most a given number of bytes from another IyiIO; Delimited reads up to (and consumes) a byte delimiter, leaving the inner stream just past it; MultiWriter writes to several IyiIOs at once. All three are IyiIOs themselves: a reader refuses writes, the writer refuses reads, each with a sentence.
Hexdump prints bytes sixteen to a line, as hexdump -C does: an eight-digit hex offset, the bytes in two groups of eight, the printable ASCII between bars.
ByteFormat::LittleEndian / BigEndian encode and decode Int32, Int64, UInt64 and UInt8 into bytes, into a pointer or an IyiIO, through unsigned byte arithmetic: every value, negative or not, round-trips. SystemEndian follows the target; NetworkEndian is big-endian.
Refused: a negative count or limit, a position past the buffer, reading a closed stream, writing a reader, reading a writer, malformed UTF-8 in read_char, and a decode that runs out of bytes.
ByteFormatstruct
pub struct ByteFormat
struct BigEndian
def self.decode_int32(buffer : Pointer(UInt8)) : Int32
def self.decode_int32(io : IyiIO) : Int32
def self.decode_int64(buffer : Pointer(UInt8)) : Int64
def self.decode_int64(io : IyiIO) : Int64
def self.decode_uint64(buffer : Pointer(UInt8)) : UInt64
def self.decode_uint64(io : IyiIO) : UInt64
def self.decode_uint8(buffer : Pointer(UInt8)) : UInt8
def self.decode_uint8(io : IyiIO) : UInt8
def self.encode(value : Int32, buffer : Pointer(UInt8)) : Nil
def self.encode(value : Int64, buffer : Pointer(UInt8)) : Nil
def self.encode(value : UInt64, buffer : Pointer(UInt8)) : Nil
def self.encode(value : UInt8, buffer : Pointer(UInt8)) : Nil
def self.encode(value : Int32, io : IyiIO) : Nil
def self.encode(value : Int64, io : IyiIO) : Nil
def self.encode(value : UInt64, io : IyiIO) : Nil
def self.encode(value : UInt8, io : IyiIO) : Nil
def initialize
end
# Two's complement by arithmetic, so a negative value never meets an
# unsigned conversion: the bit pattern of a signed integer as a UInt64
# and back.
struct Bits
def self.get_big(buffer : Pointer(UInt8), count : Int32) : UInt64
def self.get_little(buffer : Pointer(UInt8), count : Int32) : UInt64
def initialize
def self.of_int32(value : Int32) : UInt64
def self.of_int64(value : Int64) : UInt64
def self.put_big(bits : UInt64, buffer : Pointer(UInt8), count : Int32) : Nil
# The low `count` bytes of `bits`, least significant first.
def self.put_little(bits : UInt64, buffer : Pointer(UInt8), count : Int32) : Nil
# `count` bytes out of `io`, or a refusal naming the shortfall.
def self.take(io : IyiIO, count : Int32) : String
def self.to_int32(bits : UInt64) : Int32
def self.to_int64(bits : UInt64) : Int64
end
struct LittleEndian
def self.decode_int32(buffer : Pointer(UInt8)) : Int32
def self.decode_int32(io : IyiIO) : Int32
def self.decode_int64(buffer : Pointer(UInt8)) : Int64
def self.decode_int64(io : IyiIO) : Int64
def self.decode_uint64(buffer : Pointer(UInt8)) : UInt64
def self.decode_uint64(io : IyiIO) : UInt64
def self.decode_uint8(buffer : Pointer(UInt8)) : UInt8
def self.decode_uint8(io : IyiIO) : UInt8
def self.encode(value : Int32, buffer : Pointer(UInt8)) : Nil
def self.encode(value : Int64, buffer : Pointer(UInt8)) : Nil
def self.encode(value : UInt64, buffer : Pointer(UInt8)) : Nil
def self.encode(value : UInt8, buffer : Pointer(UInt8)) : Nil
def self.encode(value : Int32, io : IyiIO) : Nil
def self.encode(value : Int64, io : IyiIO) : Nil
def self.encode(value : UInt64, io : IyiIO) : Nil
def self.encode(value : UInt8, io : IyiIO) : Nil
def initialize
end
alias NetworkEndian = BigEndian
alias SystemEndian = LittleEndian
def initialize
endDelimitedclass
Another stream up to a delimiter. The delimiter is consumed and not answered; the inner stream is left just past it. Without a delimiter the whole rest of the stream is answered.
pub class Delimited < Reader
def delimiter : String
# Exact, as the prelude's is: the inner stream is read until a content
# byte is held or the delimiter (or the end) is met. Answering from the
# inner stream alone said "not yet" with nothing but the delimiter left,
# and the next read answered nil.
def eof? : Bool
def initialize(io : IyiIO, delimiter : String)
def read_byte : UInt8 | ::Nil
def write(bytes : Pointer(UInt8), count : Int32) : Nil
endHexdumpclass
Bytes printed sixteen to a line, hexdump -C style, on an IyiIO.
pub class Hexdump
def dump(bytes : Pointer(UInt8), count : Int32) : Nil
def dump(text : String) : Nil
# Everything left in `source`.
def dump(source : IyiIO) : Nil
def initialize(out __arg0 : IyiIO)
endMemoryclass
An IyiIO over bytes in memory. Writes land at the cursor and grow the buffer; reads advance the cursor; to_s is the whole buffer.
pub class Memory < ::IyiIO
# Forgets every byte; the cursor returns to the start.
def clear : Nil
def close : Nil
def closed? : Bool
def empty? : Bool
def eof? : Bool
def flush : Nil
def initialize(capacity : Int32 = 64)
# A buffer holding a copy of `text`'s bytes, the cursor at its start.
def initialize(text : String)
# The cursor, in bytes from the start. Int64, as a file's position is:
# with `std/file` imported every `IyiIO` has a `pos : Int64`, and a
# narrower answer here made `pos` on any `IyiIO` fail to compile.
def pos : Int64
def pos=(position : Int32) : Nil
# The cursor moved through an `IyiIO`: the stream's own position, not
# the descriptor's that `std/file` would move.
def pos=(position : Int64) : Int64
def read_all : String
def read_byte : UInt8 | ::Nil
def read_bytes(count : Int32) : String
def read_line(chomp : Bool = false) : String | ::Nil
def rewind : Nil
# Bytes held, written or given.
def size : Int32
def to_s : String
def write(bytes : Pointer(UInt8), count : Int32) : Nil
endMultiWriterclass
One stream written to several. close closes this writer, not the streams behind it.
pub class MultiWriter < ::IyiIO
def close : Nil
def closed? : Bool
def eof? : Bool
def flush : Nil
def initialize(writers : Array(IyiIO))
def read_all : String
def read_byte : UInt8 | ::Nil
def read_bytes(count : Int32) : String
def read_line(chomp : Bool = false) : String | ::Nil
def write(bytes : Pointer(UInt8), count : Int32) : Nil
endPipeReaderclass
The reading end of IyiIO.pipe.
pub class PipeReader < ::IyiIO
def initialize(channel : Channel(String))
endPipeWriterclass
The writing end of IyiIO.pipe: every write is sent at once.
pub class PipeWriter < ::IyiIO
def initialize(channel : Channel(String))
endSizedclass
At most limit bytes of another stream.
pub class Sized < Reader
def eof? : Bool
def initialize(io : IyiIO, limit : Int32)
def read_all : String
def read_byte : UInt8 | ::Nil
# The inner stream is asked for at most 64 KB at a time: a descriptor
# stream's `read_bytes` allocates the whole count before it reads, and
# `read_all` under a limit of Int32::MAX took 2 GB to read two bytes.
def read_bytes(count : Int32) : String
# Bytes the limit still allows, whether or not the stream has them.
def remaining : Int32
def write(bytes : Pointer(UInt8), count : Int32) : Nil
endIyiIOclass, reopened
class ::IyiIO
def <<(value) : self
# Everything left in `source` (at most `limit` bytes) written to
# `target`, which is flushed; answers the number of bytes moved.
def self.copy(source : IyiIO, target : IyiIO, limit : Int32 | ::Nil = nil) : Int64
def each_line(chomp : Bool = false, &block : (String -> Nil)) : Nil
# Every remaining line, `chomp` dropping the line ends.
def lines(chomp : Bool = false) : Array(String)
# The two ends of a pipe between tasks: what is written to the writer is
# read from the reader, in order.
#
# reader, writer = IyiIO.pipe
# group do |g|
# g.spawn { IyiIO.copy(file, writer); writer.close; 0 }
# g.spawn { IyiIO.copy(reader, socket.io); 0 }
# end
#
# Each write is delivered at once, as one piece, and a write waits while
# *capacity* pieces are unread; a read waits for one. Closing the writer
# ends the reader after the last piece; closing the reader refuses the
# next write, as a pipe whose reader is gone does. The pipe is its
# thread's, for the tasks on the thread that made it.
def self.pipe(capacity : Int32 = 16) : ::Tuple(Std::Io::PipeReader, Std::Io::PipeWriter)
# The next byte, or nil at the end.
def read_byte : UInt8 | ::Nil
# The next UTF-8 code point, or nil at the end. A lead byte that is not
# one (a continuation byte, C0/C1, F5 and above), a continuation byte that
# is not one, or a sequence the stream ends inside is refused. The first
# continuation byte is held to the range its lead allows (Unicode Table
# 3-7), so an overlong form, a surrogate and a code point past U+10FFFF
# are refused at the byte that gives them away, not decoded into a Char
# outside Unicode.
def read_char : Char | ::Nil
def write_byte(byte : UInt8) : Nil
end
std/io: byte streams beyond the standard ones.