Bytes
This library provides primitives for operating on u8vectors as well as some utility functions.
To use the bindings from this module:
(import :std/misc/bytes)
endianness
(endianness big|little|native) -> endianness symbol
(def big 'big)
(def little 'little)
(def native 'native)
(def native-endianness ...)
Specifies the endianness for integer and floating point operations on u8vectors.
The supported endianness can be big
, little
, or native
; native-endianness
is bound
at runtime to the native architecture endianness.
u8vector-s8-ref
(u8vector-s8-ref v i) -> int
v := u8vector
i := integer; offset index in v
Retrieves the signed byte from v in position i, decoding from a 2's complement representation.
u8vector-s8-set!
(u8vector-s8-set! v i n) -> unspecified
v := u8vector
i := integer; offset index in v
n := signed byte
Sets the signed byte in v at position i from the value n, encoding to 2's complement representation.
u8vector-uint-ref
(u8vector-uint-ref v i endianness size) -> exact nonnegative integer
v := u8vector
i := integer; offset index in v
endianness := endianness symbol; the endianness of the binary representation of the integer
size := integer; the size of the integer in bytes
Retrieves an unsigned integer from its binary representation from v, starting at index i.
u8vector-uint-set!
(u8vector-uint-set! v i n endianness size) -> unspecified
v := u8vector
i := integer; offset index in v
n := exact nonnegative integer; the value to set
endianness := endianness symbol; the endianness of the binary representation of the integer
size := integer; the size of the integer in bytes
Encodes the unsigned integer n in its binary representation in v, starting at offset i.
u8vector-sint-ref
(u8vector-sint-ref v i endianness size) -> exact integer
v := u8vector
i := integer; offset index in v
endianness := endianness symbol; the endianness of the binary representation of the integer
size := integer; the size of the integer in bytes
Retrieves a signed integer from its binary representation from v, starting at index i.
u8vector-sint-set!
(u8vector-sint-set! v i n endianness size) -> unspecified
v := u8vector
i := integer; offset index in v
n := exact integer; the value to set
endianness := endianness symbol; the endianness of the binary representation of the integer
size := integer; the size of the integer in bytes
Encodes the signed integer n in its binary representation in v, starting at offset i.
u8vector->uint-list
(u8vector->uint-list v endianness size) -> list of exact nonnegative integers
v := u8vector
endianness := endianness symbol; the endianness of the binary representation of each integer
size := integer; the size of each integer in bytes
Decodes a u8vector v into a list of exact nonnegative integers.
uint-list->u8vector
(uint-list->u8vector lst endianness size) -> u8vcetor
lst := list of exact nonnegative integers
endianness := endianness symbol; the endianness of the binary representation of each integer
size := integer; the size of each integer in bytes
Encodes a list of unsigned integers to a u8vector.
u8vector->sint-list
(u8vector->sint-list v endianness size) -> list of exact integers
v := u8vector
endianness := endianness symbol; the endianness of the binary representation of each integer
size := integer; the size of each integer in bytes
Decodes a u8vector v into a list of exact integers.
sint-list->u8vector
(uint-list->u8vector lst endianness size) -> u8vector
lst := list of exact integers
endianness := endianness symbol; the endianness of the binary representation of each integer
size := integer; the size of each integer in bytes
Encodes a list of signed integers to a u8vector.
Operations on Machine-size Integers
(u8vector-u16-ref v i endianness) -> u16
(u8vector-u16-native-ref v i) -> u16
(u8vector-u16-ref-set! v i n endianness) -> unspecified
(u8vector-u16-native-set! v i n) -> unspecified
(u8vector-s16-ref v i endianness) -> s16
(u8vector-s16-native-ref v i) -> s16
(u8vector-s16-ref-set! v i n endianness) -> unspecified
(u8vector-s16-native-set! v i n) -> unspecified
(u8vector-u32-ref v i endianness) -> u32
(u8vector-u32-native-ref v i) -> u32
(u8vector-u32-ref-set! v i n endianness) -> unspecified
(u8vector-u32-native-set! v i n) -> unspecified
(u8vector-s32-ref v i endianness) -> s32
(u8vector-s32-native-ref v i) -> s32
(u8vector-s32-ref-set! v i n endianness) -> unspecified
(u8vector-s32-native-set! v i n) -> unspecified
(u8vector-u64-ref v i endianness) -> u64
(u8vector-u64-native-ref v i) -> u64
(u8vector-u64-ref-set! v i n endianness) -> unspecified
(u8vector-u64-native-set! v i n) -> unspecified
(u8vector-s64-ref v i endianness) -> s64
(u8vector-s64-native-ref v i) -> s64
(u8vector-s64-ref-set! v i n endianness) -> unspecified
(u8vector-s64-native-set! v i n) -> unspecified
Operations for encoding and decoding machine-sized integers. When the endianness matches the native endianness, then a faster native implementation is used.
Operations on Floating Point Numbers
(u8vector-float-ref v i endianness) -> flonum
(u8vector-float-native-ref v i) -> flonum
(u8vector-float-set! v i x endianness) -> unspecified
(u8vector-float-native-set! v i x) -> unspecified
(u8vector-double-ref v i endianness) -> flonum
(u8vector-double-native-ref v i) -> flonum
(u8vector-double-set! v i x endianness) -> unspecified
(u8vector-double-native-set! v i x) -> unspecified
Operations for encoding and decoding floating point numbers using the IEEE-754 representation.
u8vector-swap!
(u8vector-swap! v i j) -> unspecified
v := u8vector
i := integer element position
j := integer element position
Swaps elements i and j of u8vector
v.
Examples:
> (def u (u8vector 1 2))
> (u8vector-swap! u 0 1)
> u
#u8(2 1)
u8vector-reverse!
(u8vector-reverse! v) -> void
v := u8vector
Reverses the elements of u8vector
v in-place. Mutates the vector.
Examples:
> (def u (u8vector 1 2 3 4 5))
> (u8vector-reverse! u)
> u
#u8(5 4 3 2 1)
u8vector-reverse
(u8vector-reverse v) -> u8vector
v := u8vector
Reverses the elements of u8vector
v. Produces a new u8vector
.
Examples:
> (def u (u8vector 1 2 3 4 5))
> (u8vector-reverse u)
#u8(5 4 3 2 1)
u8vector->bytestring
(u8vector->bytestring v (delim #\space)) -> bytestring
v := u8vector
delim := char
Constructs a string of bytes in hexadecimal from u8vector
v.
Each byte is formatted as two uppercase hex characters
and separated using the specified delimiter character; the delimiter can
be #f
to specify simple concatenation.
Examples:
> (u8vector->bytestring (u8vector 255 127 11 1 0))
"FF 7F 0B 01 00"
> (displayln (u8vector->bytestring (u8vector 255 127 11 1 0)))
FF 7F 0B 01 00
> (u8vector->bytestring (u8vector 1 2 3) #f)
"010203"
bytestring->u8vector
(bytestring->u8vector bs (delim #\space)) -> u8vector
bs := bytestring
delim := char
Constructs a u8vector
from bytestring bs.
This function expects a string of bytes delimited by delim, which can be #f
to indicate
no delimiter. Each byte consists of two hexadecimal characters.
Examples:
> (bytestring->u8vector "FF AB 00")
#u8(255 171 0)
> (u8vector->bytestring (bytestring->u8vector "FF AB 00"))
"FF AB 00"
> (string->bytes "FF AB 00")
#u8(70 70 32 65 66 32 48 48)
u8vector->uint
(u8vector->uint v (endianness big) (size (u8vector-length v))) -> uint
v := u8vector
endianness := endianness symbol
size := size of the uint in bytes
Decodes a u8vector as an unsigned integer.
Examples:
> (u8vector->uint #u8(0 1))
1
> (u8vector->uint (make-u8vector 2 #xFF))
65535
> (u8vector->uint (make-u8vector 8 #xFF))
18446744073709551615
> (equal? (- (expt 2 64) 1) (u8vector->uint (make-u8vector 8 #xFF)))
#t
> (u8vector->uint #(1 2 3))
66051
> (u8vector->uint #u8(3 2 1 0) little 4)
66051
uint->u8vector
(uint->u8vector n (endianness big) (size uint-length-in-u8 uint)) -> u8vector
n := exact nonnegative integer
endianness := endianness symbol
size := size of the uint in bytes
Encodes an unsigned integer to its binary representation.
Examples:
> (uint->u8vector 1 big 2)
#u8(0 1)
> (uint->u8vector 1 little 2)
#u8(1 0)
> (uint->u8vector 258)
#u8(1 2)
> (uint->u8vector 18446744073709551615)
#u8(255 255 255 255 255 255 255 255)
> (uint->u8vector 66051)
#(1 2 3)
> (uint->u8vector 66051 little 4)
#u8(3 2 1 0)
u8vector->sint
(u8vector->sint v (endianness big) (size (u8vector-length v))) -> sint
v := u8vector
endianness := endianness symbol
size := size of the sint in bytes
Decodes a u8vector as an unsigned integer.
Examples:
> (u8vector->sint #u8(0 1))
1
> (u8vector->sint (make-u8vector 2 #xFF))
-1
> (u8vector->sint #(1 2 3))
66051
> (u8vector->sint #u8(3 2 1 0) little 4)
66051
> (u8vector->sint u8(0 233))
233
> (u8vector->sint #u8(233))
-23
sint->u8vector
(sint->u8vector n (endianness big) (size sint-length-in-u8 sint)) -> u8vector
n := exact nonnegative integer
endianness := endianness symbol
size := size of the sint in bytes
Encodes an unsigned integer to its binary representation.
Examples:
> (sint->u8vector 1 big 2)
#u8(0 1)
> (sint->u8vector 1 little 2)
#u8(1 0)
> (sint->u8vector 258)
#u8(1 2)
> (sint->u8vector 18446744073709551615)
#u8(0 255 255 255 255 255 255 255 255)
> (sint->u8vector 66051)
#(1 2 3)
> (sint->u8vector 66051 little 4)
#u8(3 2 1 0)
> (sint->u8vector 233)
u8(0 233))
> (sint->u8vector -23)
#u8(233)
Aliases
The following aliases are defined, using the canonical Scheme naming of u8vectors as bytevectors.
(defalias bytevector-u8-ref u8vector-ref)
(defalias bytevector-u8-set! u8vector-set!)
(defalias bytevector-s8-ref u8vector-s8-ref)
(defalias bytevector-s8-set! u8vector-s8-set!)
(defalias bytevector-uint-ref u8vector-uint-ref)
(defalias bytevector-uint-set! u8vector-uint-set!)
(defalias bytevector-sint-ref u8vector-sint-ref)
(defalias bytevector-sint-set! u8vector-sint-set!)
(defalias bytevector->uint-list u8vector->uint-list)
(defalias bytevector->sint-list u8vector->sint-list)
(defalias uint-list->bytevector uint-list->u8vector)
(defalias sint-list->bytevector sint-list->u8vector)
(defalias bytevector-u16-ref u8vector-u16-ref)
(defalias bytevector-u16-native-ref u8vector-u16-native-ref)
(defalias bytevector-u16-set! u8vector-u16-set!)
(defalias bytevector-u16-native-set! u8vector-u16-native-set!)
(defalias bytevector-s16-ref u8vector-s16-ref)
(defalias bytevector-s16-native-ref u8vector-s16-native-ref)
(defalias bytevector-s16-set! u8vector-s16-set!)
(defalias bytevector-s16-native-set! u8vector-s16-native-set!)
(defalias bytevector-u32-ref u8vector-u32-ref)
(defalias bytevector-u32-native-ref u8vector-u32-native-ref)
(defalias bytevector-u32-set! u8vector-u32-set!)
(defalias bytevector-u32-native-set! u8vector-u32-native-set!)
(defalias bytevector-s32-ref u8vector-s32-ref)
(defalias bytevector-s32-native-ref u8vector-s32-native-ref)
(defalias bytevector-s32-set! u8vector-s32-set!)
(defalias bytevector-s32-native-set! u8vector-s32-native-set!)
(defalias bytevector-u64-ref u8vector-u64-ref)
(defalias bytevector-u64-native-ref u8vector-u64-native-ref)
(defalias bytevector-u64-set! u8vector-u64-set!)
(defalias bytevector-u64-native-set! u8vector-u64-native-set!)
(defalias bytevector-s64-ref u8vector-s64-ref)
(defalias bytevector-s64-native-ref u8vector-s64-native-ref)
(defalias bytevector-s64-set! u8vector-s64-set!)
(defalias bytevector-s64-native-set! u8vector-s64-native-set!)
(defalias bytevector-ieee-single-ref u8vector-float-ref)
(defalias bytevector-ieee-single-set! u8vector-float-set!)
(defalias bytevector-ieee-single-native-ref u8vector-float-native-ref)
(defalias bytevector-ieee-single-native-set! u8vector-float-native-set!)
(defalias bytevector-ieee-double-ref u8vector-double-ref)
(defalias bytevector-ieee-double-set! u8vector-double-set!)
(defalias bytevector-ieee-double-native-ref u8vector-double-native-ref)
(defalias bytevector-ieee-double-native-set! u8vector-double-native-set!)
(defalias bytevector-swap! u8vector-swap!)
(defalias bytevector-reverse! u8vector-reverse!)
(defalias bytevector-reverse u8vector-reverse)
(defalias bytevector->bytestring u8vector->bytestring)
(defalias bytestring->bytevector bytestring->u8vector)
(defalias bytevector->uint u8vector->uint)
(defalias uint->bytevector uint->u8vector)
Low Level Unsafe Operations
The following low level unsafe operations are also exported.
(&u8vector-s8-ref v i) -> s8
(&u8vector-s8-set! v i n) -> unspecified
(&u8vector-uint-ref/be v i size) -> uint
(&u8vector-uint-ref/le v i size) -> uint
(&u8vector-uint-set!/be v i n size) -> unspecified
(&u8vector-uint-set!/le v i n size) -> unspecified
(&u8vector-sint-ref/be v i size) -> sint
(&u8vector-sint-ref/le v i size) -> sint
(&u8vector-sint-set!/be v i n size) -> unspecified
(&u8vector-sint-set!/le v i n size) -> unspecified
(&u8vector-u16-ref/native v i) -> u16
(&u8vector-u16-set!/native v i n) -> unspecified
(&u8vector-s16-ref/native v i) -> s16
(&u8vector-s16-set!/native v i n) -> unspecified
(&u8vector-u32-ref/native v i) -> u32
(&u8vector-u32-set!/native v i n) -> unspecified
(&u8vector-s32-ref/native v i) -> s32
(&u8vector-s32-set!/native v i n) -> unspecified
(&u8vector-u64-ref/native v i) -> u64
(&u8vector-u64-set!/native v i n) -> unspecified
(&u8vector-s64-ref/native v i) -> s64
(&u8vector-s64-set!/native v i n) -> unspecified
(&u8vector-float-ref/native v i) -> flonum
(&u8vector-float-set!/native v i x) -> unspecified
(&u8vector-double-ref/native v i) -> flonum
(&u8vector-double-set!/native v i x) -> unspecified
(&u8vector-swap! v i j) -> unspecified
u8vector-init!, bytevector-init!
(u8vector-init! len fun) -> u8vector
u8vector-init!
is take a non-negative fixnum len
and a one-argument function fun
and creates a new u8vector
of length len
where each element is initialized
in increasing index order with the result of calling fun
with the index as argument
(starting with 0
, assuming len
is positive).
Examples:
> (u8vector-init! 5 (lambda (x) (* x x)))
#u8(0 1 4 9 16)
u8vector-every
(u8vector-every pred? u8vector) -> bool
Return true if every element of the given u8vector
satisfies the unary predicate pred?
.
Examples:
> (u8vector-every odd? #u8(1 3 5))
#t
> (u8vector-every odd? #u8(1 2 3))
#f
n-bits->n-u8
(n-bits->n-u8 n) -> integer
Given a number n
of bits, return the number N
of 8-bit bytes necessary to store those n
bits,
i.e. N = (ceiling-align n-bits 8)
.
Examples:
> (map (lambda (x) (list x (n-bits->n-u8 x))) '(0 1 2 7 8 9 16 21 63 100 1000))
((0 0) (1 1) (2 1) (7 1) (8 1) (9 2) (16 2) (21 3) (63 8) (100 13) (1000 125))
nat-length-in-u8
(nat-length-in-u8 n) -> integer
Given a natural number n
(non-negative, "unsigned"),
return the number of 8-bit bytes necessary to store all the bits of n
.
Examples:
> (map (lambda (x) (list x (nat-length-in-u8 x))) '(0 42 127 128 255 256 65535 65536))
((0 0) (42 1) (127 1) (128 1) (255 1) (256 2) (65535 2) (65536 3))
nat->u8vector
(nat->u8vector n [length] [endianness]) -> u8vector
Given a natural number n
(non-negative, "unsigned"),
a length
(which defaults to the minimal length required to store all the bits of n
),
and an endianness (which defaults to big
),
return a u8vector of given length which stores the bits of n
in the given endianness.
Examples:
> (nat->u8vector 66051)
#u8(1 2 3)
> (nat->u8vector 66051 4 little)
#u8(3 2 1 0)
u8vector->nat
(u8vector->nat u8vector [length] [endianness]) -> integer
Given a u8vector
, a length
no greater than that of the vector,
and an endianness
(defaults to big
), decode the first length
bytes of u8vector
using the given endianness into a natural number (non-negative, "unsigned").
Assuming the length
and endianness
match and the number fits in the length
,
this is the inverse operation of nat->u8vector
.
Examples:
> (u8vector->nat #u8(1 2 3))
66051
> (u8vector->nat #u8(3 2 1 0) 4 little)
66051
integer-length-in-u8
(integer-length-in-u8 n) -> integer
Given a natural number n
(non-negative, "unsigned"),
return the number of 8-bit bytes necessary to store all the bits of n
.
Examples:
> (map (lambda (x) (list x (integer-length-in-u8 x))) '(0 42 127 128 255 256 65535 65536))
((0 0) (42 1) (127 1) (128 1) (255 1) (256 2) (65535 2) (65536 3))
integer->u8vector
(integer->u8vector n [length] [endianness]) -> u8vector
Given a relative integer n
(possibly negative, "signed"),
a length
(which defaults to the minimal length required to store all the bits of n
),
and an endianness (which defaults to big
),
return a u8vector of given length which stores the bits of n
in the given endianness.
Examples:
> (integer->u8vector 66051)
#u8(1 2 3)
> (integer->u8vector -255)
#u8(255 1)
> (integer->u8vector 66051 4 little)
#u8(3 2 1 0)
> (integer->u8vector -66051 4 little)
#u8(253 253 254 255)
u8vector->integer
(u8vector->integer u8vector [length] [endianness]) -> integer
Given a u8vector
, a length
no greater than that of the vector,
and an endianness
(defaults to big
), decode the first length
bytes of u8vector
using the given endianness into a natural number (non-negative, "unsigned").
Assuming the length
and endianness
match and the number fits in the length
,
this is the inverse operation of integer->u8vector
.
Examples:
> (u8vector->integer #u8(1 2 3))
66051
> (u8vector->integer #u8(255 1))
-255
> (u8vector->integer #u8(3 2 1 0) 4 little)
66051
> (u8vector->integer #u8(253 253 254 255) 4 little)
-66051