Cursor
Reads, writes and seeks a window of in-memory data or another stream.
The target is a Str, Bin,
BinBuf, StrBuf, or an Io that reads and
seeks. A Str or Bin is only read. A buffer is read and written in place, so the cursor sees changes
made to it by other means: reads stop at its current length, and a write
overwrites from the position and extends the buffer when it reaches the end.
A BinBuf is padded with zero bytes up to a position past its end before a
write there.
range limits the cursor to a window of the target. Positions count from
the window's start, and seeking to the end lands on the window's end, or the
target's end when the window is open. Reads stop at the window's end, and a
write is cut short there.
An Io target is read and written through, and written only if it writes.
The cursor keeps its own position and seeks the target before each read or
write, so the target's position changes but doesn't matter. Don't use the
target while a read or write through the cursor is in progress, such as
from another strand.
A StrBuf stays valid UTF-8, so a cursor over one also lets text written
in arbitrary pieces reach it:
- The bytes of an unfinished final character are held back until a later
write completes it. Positions don't count them, a seek that moves raises
while they are held, and
flushkeeps them held. - An overwrite must start and end on character boundaries of the contents, or at their end.
Closing the cursor leaves the target as it is.
Errors
| Exception | Condition |
|---|---|
TypeError |
target is not one of the types above, or range is not a Range |
ValueError |
An Io target doesn't read and seek |
ValueError |
range has a negative or non-integer bound, runs backward, or steps by other than 1 |
ValueError |
A StrBuf write would split a character, or a seek moves while bytes are held |
DataError |
A StrBuf write is not valid UTF-8, or the cursor is closed while bytes are held |
StateError |
The cursor is closed, or a write targets a Str, a Bin or an Io that doesn't write |
Example
let buf = BinBuf()
buf.extend b"size: ????\n"
let field = Cursor $buf (6..10)
field.write "1234"
let text = StrBuf()
let out = Cursor $text
compress.decompress (Cursor $data) do |stream|
stream.copy_to $out
out.close()
# An archive stored at `offset` within a file
fs.open bundle.bin do |file|
zip.open (Cursor $file (offset..(offset + size))) do |archive|
archive.open README do |entry|
echo (entry.read_all_str())
Inherits from: Io
Constructor
Cursor target …
Opens a cursor over target.
Parameters
| Name | Type | Description |
|---|---|---|
target |
(Str | Bin | BinBuf | StrBuf | Io) |
Data to read and write. |
range? |
(Range[Int] | nil) |
Byte range of the window, such as (offset..) or
(offset..(offset + size)); the whole target when omitted. |
Fields
readable @ Bool[get]Whether the cursor reads, which it does until it is closed.
seekable @ Bool[get]Whether the cursor seeks, which it does until it is closed.
writable @ Bool[get]Whether the cursor writes: while open, when the target is a buffer or an
Iothat writes.
Methods
close()
Closes the cursor, dropping any held bytes, after flushing an Io target.
The target stays open. Closing a closed cursor does nothing.
flush()
Flushes an Io target. Writes reach a memory target at once, and held
bytes stay held.
read size -> Bin
Reads bytes.
Parameters
| Name | Type | Description |
|---|---|---|
size |
Int |
Number of bytes to read. |
Returns
At most size bytes. A memory target gives fewer only at the end of the
window or the target. An empty result means the end.
seek … -> Int
Moves the position.
Parameters
| Name | Type | Description |
|---|---|---|
offset? |
Int |
Byte offset relative to the current position. |
:start? |
Int |
Byte offset from the start of the window. |
:end? |
Int |
Byte offset relative to the end of the window. |
Returns
The new position within the window.
write *data -> Int
Writes data, given in pieces.
Parameters
| Name | Type | Description |
|---|---|---|
*data |
(Str | Bin) |
Data to write. |
Returns
The number of bytes written. A memory target writes fewer only at the end
of a bounded window. Bytes a StrBuf cursor holds back count as written.