String Methods
DQ has four main text forms:
| Type | Meaning |
|---|---|
str |
dynamic heap-managed string |
rostr |
read-only borrowed zero-terminated string |
strslice |
non-owning string view, including unterminated slices |
embstr(n) |
Embedded String: fixed-size zero-terminated storage |
str is an owned byte string with an enforced trailing zero. Its .length
counts bytes, not Unicode scalar values, and the hidden terminator is not
included in that length. A string may contain arbitrary bytes, including
internal zero bytes, so a str is not automatically valid UTF-8.
str is copy-on-write. Assigning a string shares storage until one copy is
mutated.
var a : str = "abc"
var b : str = a
b[0] = 'X' // a is still "abc"
rostr provides read-only byte and Unicode access. It borrows storage without
copying, converts directly to C string pointers, and returns strslice slices.
AddFmt format arguments use rostr; mutation sources still accept arbitrary
text views. See Strings and Characters
for conversions and lifetime requirements.
Common Operations
Dynamic strings expose:
| Member | Meaning |
|---|---|
.length |
current byte length |
.capacity |
allocated capacity |
Set(text) |
replace contents |
Append(value) / Add(value) |
append text or a char byte |
AppendChar(ch) |
append one char byte |
Prepend(value) |
insert at the beginning |
Insert(index, value) |
insert text or a char byte |
Delete(index, count = 1) |
remove bytes |
SetLength(length, fill) |
resize, filling new bytes |
Truncate(length) |
shrink only |
Pop(count) / PopFirst(count) |
remove and return text |
Pop() / PopFirst() |
remove and return one char byte |
Reserve(capacity) |
ensure capacity |
Compact() |
set capacity to current length |
Clear(free_storage = false) |
clear contents, optionally free storage |
Clone() |
force an independent copy |
AddFmt(fmt, args) |
append formatted text |
var s : str = "abc"
s.Append("def")
s.Insert(0, '>')
s.Delete(0)
s.AddFmt(" {}", [123])
String indexing and slicing use byte offsets and return or copy char values.
They do not validate UTF-8.
var b : char = s[0]
var part : str = s[3:10]
Indices are normalized by the runtime operations. For example, deleting past
the end is clamped, and inserting with $end appends.
Utility Methods
The following read-only methods are available on str, rostr, strslice,
and embstr values. They accept a char or a text value where a search,
prefix, suffix, trim set, or fill value is required. Search positions and
lengths are byte-based, just like .length and normal indexing.
| Member | Result | Meaning |
|---|---|---|
Trim() / Trim(set) |
str |
remove whitespace, or bytes in set, from both ends |
LTrim() / LTrim(set) |
str |
remove whitespace, or bytes in set, from the left end |
RTrim() / RTrim(set) |
str |
remove whitespace, or bytes in set, from the right end |
LPad(length, fill) |
str |
pad the left side to length bytes |
RPad(length, fill) |
str |
pad the right side to length bytes |
IndexOf(needle, start = 0) |
int |
first matching byte offset, or -1 |
LastIndexOf(needle) |
int |
last matching byte offset, or -1 |
Contains(needle) |
bool |
whether the value contains needle |
StartsWith(prefix) |
bool |
whether the value begins with prefix |
EndsWith(suffix) |
bool |
whether the value ends with suffix |
These methods do not modify the receiver. Assign a returned str to retain a
trimmed or padded value.
var text : str = " abc "
text = text.Trim() // "abc"
Trim, LTrim, and RTrim use the ASCII whitespace bytes space, tab,
line feed, carriage return, vertical tab, and form feed by default. With an
argument, that argument is a set of bytes rather than a substring pattern.
var marked : str = "---abc---"
var name : str = marked.Trim("-") // "abc"
Padding repeats the fill value and truncates the final repetition to produce exactly the requested length. A target length no greater than the receiver length returns an unchanged copy. An empty fill value raises a runtime error.
var code : str = "abc"
code.LPad(8, "01") // "01010abc"
code.RPad(5, '.') // "abc.."
IndexOf clamps start to 0 .. text.length. An empty needle matches at the
normalized start position. LastIndexOf("") returns text.length; an empty
prefix or suffix matches every text value.
var text : str = "abcdefabc"
text.IndexOf("abc", 1) // 6
text.IndexOf("", 100) // 9
text.LastIndexOf("abc") // 6
text.StartsWith("abc") // true
text.EndsWith("abc") // true
The trim and padding methods create a str, so they are unavailable on
targets built with dynamic strings disabled. The search methods only return
scalar values and remain available for the supported text views.
Unicode Operations
Unicode-oriented operations decode string bytes as UTF-8 and work with wchar,
the 32-bit Unicode scalar type.
| Member | Meaning |
|---|---|
.wclen |
number of decoded Unicode scalar values |
.wchar[index] |
Unicode scalar at a scalar index |
.wchar[start:end] |
decoded scalar slice as [*]wchar |
.wcstr[start:end] |
scalar-indexed slice encoded back to str |
ToWchars() |
decode UTF-8 to [*]wchar |
ToUtf16() |
decode UTF-8 to zero-terminated [*]char16 |
var text : str = "Aé€"
var n : int = text.wclen
var wc : wchar = text.wchar[1]
var chars : [*]wchar = text.wchar[:]
var utf8_part : str = text.wcstr[1:$end]
These operations report a runtime encoding error for malformed UTF-8. For
repeated indexed Unicode processing, convert once with ToWchars() and index
the resulting array.
StrFromWchars(chars) encodes Unicode scalar values as UTF-8. UTF-16
interoperability uses ToUtf16() and StrFromUtf16(...); the UTF-16 array
returned by ToUtf16() includes a final zero terminator as an ordinary element.
C String Access
str and embstr expose .pchar, a borrowed ^char pointer to their
zero-terminated byte storage.
var p : ^char = s.pchar
The pointer is valid only while the source value remains alive and its storage
is not reallocated. Internal zero bytes are preserved in the str, but C APIs
using zero-terminated semantics see only the bytes before the first internal
zero.
embstr
embstr(n) owns exactly n bytes of fixed storage, including the zero
terminator. Its maximum content length is n - 1 bytes.
Appending and assigning truncate to fit.
var cs : embstr(6) = "abc"
cs.Append("def") // stores "abcde"
embstr supports many of the same mutation methods as str, including Set,
Append, Add, AppendChar, Prepend, Insert, Delete, Clear, and
AddFmt. It does not support dynamic capacity operations such as Reserve or
Compact.
An unsized embstr is an alias/view over existing C string storage, commonly
used for parameters. Aliases share descriptor metadata, including the cached
length, so mutations through one alias are observed by the others.