On this page:
Bytes
Mutable  Bytes
Immutable  Bytes
Bytes.make
Bytes.length
Bytes.get
Bytes.set
Bytes.append
Bytes.subbytes
Bytes.copy
Bytes.copy_  from
Bytes.fill
Bytes.snapshot
Bytes.utf8_  string
Bytes.latin1_  string
Bytes.locale_  string
Bytes.utf8_  length
Bytes.utf8_  ref
Bytes.utf8_  index
Bytes.to_  sequence
9.0

7.7 Byte Strings🔗ℹ

A byte string is a sequence of bytes. A byte string works with map-referencing [] to access a byte via #%index. A byte string also works with the ++ operator to append bytes strings. A byte string can be used as sequence, in which case it supplies its bytes in order.

A byte string is normally mutable, but byte-string literals are immutable. The Bytes annotation is satisfied by both mutable and immutable byte strings, while MutableBytes and ImmutableBytes require one or the other.

Two byte strings are equal by is_now as long as they have equal contents, even if one is mutable and the other is immutable.

Byte strings are comparable, which means that generic operations like < and > work on byte strings.

annotation

Bytes

 

annotation

MutableBytes

 

annotation

ImmutableBytes

Matches byte strings, where MutableBytes matches only mutable byte strings, and and ImmutableBytes matches only immutable byte strings.

Static information associated by Bytes, etc., makes an expression acceptable as a sequence to for in static mode.

function

fun Bytes.make(length :: Nat, byte :: Byte = 0)

  :: MutableBytes

Creates a fresh byte string with length bytes, where each byte is initialized to byte.

> Bytes.make(5, Byte#"!")

Bytes.copy(#"!!!!!")

method

method (bstr :: Bytes).length() :: Nat

Returns the number of bytes in bstr.

> #"hello".length()

5

> Bytes.length(#"hello")

5

method

method (bstr :: Bytes).get(n :: Nat) :: Byte

Equivalent to bstr[n] (with the default implicit #%index form). Returns the nth byte of bstr (starting from 0).

> #"abc"[0]

97

> #"abc".get(0)

97

method

method (bstr :: Bytes).set(n :: Nat, byte :: Byte)

  :: Void

Equivalent to bstr[n] := byte (with the default implicit #%index form). Updates the nth position of bstr to byte.

> def b = #"abc".copy()

> b[0] := Byte#"h"

> b

Bytes.copy(#"hbc")

> b.set(1, Byte#"h")

> b

Bytes.copy(#"hhc")

method

method (bstr :: Bytes).append(bstr :: Bytes, ...) :: MutableBytes

 

function

fun Bytes.append(bstr :: Bytes, ...) :: MutableBytes

Appends bstrs by creating a new mutable byte string with all bytes.

> #"abc".append(#"def", #"ghi")

Bytes.copy(#"abcdefghi")

method

method (bstr :: Bytes).subbytes(rge :: Range)

  :: MutableBytes

 

method

method (bstr :: Bytes).subbytes(start :: Nat,

                                end :: Nat)

  :: MutableBytes

When given two arguments, returns the substring of bstr from start (inclusive) to end (exclusive).

When given one argument, rge is used to derive start and end as in String.substring.

> #"hello".subbytes(2, 4)

Bytes.copy(#"ll")

> #"hello".subbytes(2..=4)

Bytes.copy(#"llo")

> #"hello".subbytes(2..)

Bytes.copy(#"llo")

> #"hello".subbytes(..4)

Bytes.copy(#"hell")

> #"hello".subbytes(..)

Bytes.copy(#"hello")

method

method (bstr :: Bytes).copy() :: MutableBytes

Returns a fresh mutable byte string with the same initial content as bstr.

> def b = #"apple"

> b.copy()

Bytes.copy(#"apple")

> b.copy() is_now b

#true

method

method Bytes.copy_from(dest_bstr :: MutableBytes,

                       dest_start :: Nat,

                       src_bstr :: Bytes,

                       src_start :: Nat = 0,

                       src_end :: Nat = Bytes.length(src_bstr))

  :: Void

Copies bytes from src_bstr at src_start (inclusive) to src_end (exclusive) into dest_bstr starting at dest_start. The length of dest_bstr must be at least dest_start + (src_end - src_start).

method

method Bytes.fill(bstr :: MutableBytes, byte :: Byte) :: Void

Sets every byte in bstr to byte.

> def b = #"apple".copy()

> b.fill(Byte#"x")

> b

Bytes.copy(#"xxxxx")

method

method (bstr :: Bytes).snapshot(str :: Bytes) :: ImmutableBytes

Returns an immutable byte string as-is or copies a mutable byte string’s content to an immutable byte string.

> def b = #"apple"

> b.snapshot()

#"apple"

> b.snapshot() === b

#true

> def b = #"apple".copy()

> b.snapshot()

#"apple"

> b.snapshot() is_now b

#true

method

method (bstr :: Bytes).utf8_string(

  err_char :: maybe(Char) = #false,

  start :: Nat = 0,

  end :: Nat = Bytes.length(bstr)

) :: String

 

method

method (bstr :: Bytes).latin1_string(

  err_char :: maybe(Char) = #false,

  start :: Nat = 0,

  end :: Nat = Bytes.length(bstr)

) :: String

 

method

method (bstr :: Bytes).locale_string(

  err_char :: maybe(Char) = #false,

  start :: Nat = 0,

  end :: Nat = Bytes.length(bstr)

) :: String

Converts a byte string to a string, decoding as UTF-8, Latin-1, or the current locale’s encoding. The err_char argument provides a character to use in place of an encoding error, where #false means that an exception is thrown.

> #"hello".utf8_string()

"hello"

> #"hi \316\273".utf8_string()

"hi λ"

> #"hi \316 xxx \273".utf8_string()

Bytes.utf8_string: byte string is not a well-formed UTF-8 encoding

  byte string: Bytes.copy(#"hi \316 xxx \273")

> #"hi \316 xxx \273".utf8_string(Char"?")

"hi ? xxx ?"

method

method (bstr :: Bytes).utf8_length(

  err_char :: maybe(Char) = #false,

  start :: Nat = 0,

  end :: Nat = Bytes.length(bstr)

) :: maybe(Nat)

 

method

method (bstr :: Bytes).utf8_ref(

  skip :: Nat,

  err_char :: maybe(Char) = #false,

  start :: Nat = 0,

  end :: Nat = Bytes.length(bstr)

) :: maybe(Char)

 

method

method (bstr :: Bytes).utf8_index(

  skip :: Nat,

  err_char :: maybe(Char) = #false,

  start :: Nat = 0,

  end :: Nat = Bytes.length(bstr)

) :: maybe(Nat)

Returns information about the UTF-8 decoding of bstr’s substring from start to end, but without actually generating the decoded characters—except for the one character returned by Bytes.utf8_ref. If err_char is #false and the substring is not a UTF-8 encoding up to the point of getting a result value, the result is #false. Otherwise, err_char is used to resolve decoding errors as in Bytes.utf8_string and the result is never #false.

The Bytes.utf8_length method returns the length in characters of the decoded substring from start to end.

The Bytes.utf8_ref method returns the character decoded in substring from start to end, skipping skip decoded characters.

The Bytes.utf8_index method returns the byte index starting the character that would be decoded in substring from start to end, skipping skip decoded characters. Note that a non-#false result does not mean that bytes at the returned index are well formed as UTF-8, only that the bytes up to the returned index are available and well-formed. The returned index is relative to the start of bstr, not to start, and it is always less than end.

> #"hi \316\273".utf8_length()

4

> #"hi \316 xxx \273".utf8_length()

#false

> #"hi \316 xxx \273".utf8_length(Char"?")

10

> #"hi \316\273".utf8_ref(0)

Char"h"

> #"hi \316\273".utf8_ref(3)

Char"λ"

> #"hi \316\273".utf8_index(0)

0

> #"hi \316\273!".utf8_index(4)

5

method

method (bstr :: Bytes).to_sequence(bstr :: Bytes) :: Sequence

Implements Sequenceable by returning a sequence of bstr’s bytes in order.