Skip to content

StrBuf

Mutable UTF-8 string buffer; the mutable counterpart to Str.

StrBuf is a sink, so it can be the target of a pipeline, of strand.put, or of a run redirect. put is append: the value's string form goes in verbatim, with no line terminator added.

let buf = StrBuf()
run uname -r stdout: $buf

Line termination is the caller's to choose, so a StrBuf can stand in for any other sink without changing what gets written:

let buf = StrBuf()
let out = buf.precrimp()
out.put "first"
out.put "second"
assert_eq $buf.freeze() "first\nsecond\n"

A StrBuf is not an Io, since bytes written in pieces can split a character. An io.Cursor over it takes bytes from anything that writes to a stream, holding back a split character until it is complete.

Inherits from: Sink[Value]

Implements: Index[Range[Int], Str], Assign[Range[Int], Str]

Constructor

StrBuf …

Builds a buffer, optionally seeded with the contents of an existing string.

Parameters

NameTypeDescription
initial? Str initial contents

Example

let buf = StrBuf("hello")
assert_eq $buf.len 5

Fields

len @ Int [get]

Returns the byte length of the buffer's current contents.

Example
assert_eq (StrBuf("hello").len) 5

Methods

(assign) range value

Replaces the text in a range. The replacement may differ in length from the range, growing or shrinking the buffer. The range's endpoints must fall on UTF-8 character boundaries.

Parameters

NameTypeDescription
range Range[Int]
value Str

(index) range -> Str

Returns the text in a range as a new string.

Like Str, StrBuf supports only range indexing and assignment, since a single byte is rarely useful on its own.

let buf = StrBuf("foobar")
assert_eq $buf[2..4] "ob"
buf[1..3] = "XYZ"
assert_eq $buf.freeze() "fXYZbar"

The range's endpoints must fall on UTF-8 character boundaries.

Parameters

NameTypeDescription
range Range[Int]

append value

Appends value to the buffer. Str input is copied byte-for-byte; anything else is converted the same way str would convert it, written directly into the buffer.

Parameters

NameTypeDescription
value Value value to append

Example

let buf = StrBuf()
buf.append "foo"
buf.append 42
assert_eq $buf.freeze() "foo42"

clear()

Empties the buffer, retaining its allocated capacity.

let buf = StrBuf("foobar")
buf.clear()
assert_eq $buf.len 0
buf.append "x"
assert_eq $buf.freeze() "x"

contains needle -> Bool

Tests whether the buffer's contents contain the given substring.

Parameters

NameTypeDescription
needle Str the substring to find

Example

assert (StrBuf("foobar").contains "oob")

drain … -> Iter[Str]

Returns an iterator that removes and yields up to size bytes at a time from the front of the buffer as it's consumed.

Each chunk boundary is rounded down to the nearest UTF-8 code point boundary, unless that would produce an empty chunk (size smaller than the first remaining code point), in which case it rounds up instead so every chunk yielded is non-empty.

Parameters

NameTypeDescription
size? Int Maximum bytes per chunk; 512 KiB when omitted.

Example

let buf = StrBuf("hello world")
assert_eq [...buf.drain(4)] ["hell", "o wo", "rld"]
assert_eq $buf.len 0

Draining doesn't move the remaining contents for each chunk, so its cost grows with the bytes drained, not with what is left. Indexes given to other methods count from the start of what remains. Several drain iterators over one buffer take turns removing from the same content.

ends_with suffix -> Bool

Tests whether the buffer's contents end with the given suffix.

Parameters

NameTypeDescription
suffix Str the suffix string

Example

assert (StrBuf("foobar").ends_with "bar")

extend value

Appends the raw bytes of value, which must be a Str.

Parameters

NameTypeDescription
value Str string to append

Example

let buf = StrBuf("foo")
buf.extend "bar"
assert_eq $buf.freeze() "foobar"

freeze() -> Str

Converts the buffer's current contents into an immutable Str in place, without copying, and empties the buffer. The buffer stays usable afterward, and the returned string is unaffected by later mutation.

Example

let buf = StrBuf("abc")
let frozen = buf.freeze()
assert_eq $frozen "abc"
assert_eq $buf.len 0
buf.append "def"
assert_eq $frozen "abc"

insert index value

Inserts value at the given byte index, shifting the rest of the buffer right in place.

Parameters

NameTypeDescription
index Int insertion point; must fall on a UTF-8 boundary
value Str string to insert

Example

let buf = StrBuf("foobar")
buf.insert 3 "XYZ"
assert_eq $buf.freeze() "fooXYZbar"

remove range -> Str

Removes and returns the substring covered by range, shifting the rest of the buffer left in place.

Parameters

NameTypeDescription
range Range[Int] byte range to remove; must fall on UTF-8 boundaries

Example

let buf = StrBuf("foobar")
assert_eq (buf.remove (1..3)) "oo"
assert_eq $buf.freeze() "fbar"

Unlike insert, remove only accepts a range — a scalar index would remove a single UTF-8 code unit, which is rarely a useful result.

starts_with prefix -> Bool

Tests whether the buffer's contents start with the given prefix.

Parameters

NameTypeDescription
prefix Str the prefix string

Example

assert (StrBuf("foobar").starts_with "foo")

truncate len

Shrinks the buffer to len bytes, discarding anything past that point.

Parameters

NameTypeDescription
len Int new length; must fall on a UTF-8 boundary

Example

let buf = StrBuf("foobar")
buf.truncate 3
assert_eq $buf.freeze() "foo"