The segmentation primitive is allocation-free: it fills the caller’s array with segment lengths and returns the count. Segments tile the text, so each starts where the previous one ended.
int decoded = StringZilla.decode(text, codepoints); // fill an int[]; ill-formed or truncated -> U+FFFD
long[] lengths = new long[64];
int count = StringZilla.segment(text, 0, text.length, StringZilla.SegmentKind.WORDS, lengths); // UAX-29
int start = 0;
for (int segment = 0; segment < count; segment++) {
use(text, start, (int) lengths[segment]);
start += (int) lengths[segment];
}Codepoints count scalar values, not bytes or UTF-16 chars. Segmentation tiles the text — every byte belongs to exactly one segment — and a grapheme cluster can span several codepoints.
StringZilla.countRunes("你好世界".getBytes(UTF_8)); // 4 codepoints
StringZilla.countRunes("Hello🌍".getBytes(UTF_8)); // 6 — the astral emoji is one scalar
for (MemorySegment cluster : StringZilla.graphemes("👍🏽🇺🇸".getBytes(UTF_8))) use(cluster); // 👍🏽 (emoji + skin tone), 🇺🇸 (flag)
for (MemorySegment word : StringZilla.words("Hello, 世界".getBytes(UTF_8))) use(word); // Latin run, then CJK run