(import (rnrs)) ;R6RS (import (rnrs bytevectors)) ;R6RS
(bytevector-s16-ref bytevector k endianness) (bytevector-s32-ref bytevector k endianness) (bytevector-s64-ref bytevector k endianness) (bytevector-u16-ref bytevector k endianness) (bytevector-u32-ref bytevector k endianness) (bytevector-u64-ref bytevector k endianness) (bytevector-ieee-double-ref bytevector k endianness) (bytevector-ieee-single-ref bytevector k endianness) (bytevector-s16-native-ref bytevector k) (bytevector-s32-native-ref bytevector k) (bytevector-s64-native-ref bytevector k) (bytevector-u16-native-ref bytevector k) (bytevector-u32-native-ref bytevector k) (bytevector-u64-native-ref bytevector k) (bytevector-ieee-single-native-ref bytevector k) (bytevector-ieee-double-native-ref bytevector k)
The signed variants use the two's complement representation.
The endianness is normally one of the following symbols:
The -native variants use the machine's native endianness and furthermore impose an alignment requirement: the index k must be evenly divisible by the data type size (2, 4 or 8). Such an access is said to be aligned, as opposed to an unaligned access.
The number of bytes n used depends on the data type and is either two, four or eight (corresponding to 16, 32 or 64 bits). The bytevector must be at least k+n bytes in length.
Unlike the equivalent operation in e.g. C, the index is not multiplied by the element size.
(define b #vu8(#xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFF #xFD)) (bytevector-u16-ref b 14 (endianness little)) => 65023 ;#xFDFF (bytevector-s16-ref b 14 (endianness little)) => -513 ;#x-201 (bytevector-u16-ref b 14 (endianness big)) => 65533 ;#xFFFD (bytevector-s16-ref b 14 (endianness big)) => -3 (bytevector-u32-ref b 12 (endianness little)) => 4261412863 ;#xFDFFFFFF (bytevector-s32-ref b 12 (endianness little)) => -33554433 ;#x-2000001 (bytevector-u32-ref b 12 (endianness big)) => 4294967293 ;#xFFFFFFFD (bytevector-s32-ref b 12 (endianness big)) => -3 (bytevector-u64-ref b 8 (endianness little)) => 18302628885633695743 ;#xFDFFFFFFFFFFFFFF (bytevector-s64-ref b 8 (endianness little)) => -144115188075855873 ;#x-200000000000001 (bytevector-u64-ref b 8 (endianness big)) => 18446744073709551613 ;#xFFFFFFFFFFFFFFFD (bytevector-s64-ref b 8 (endianness big)) => -3 ;; Native endianness can be little, big or something else. ;; R6RS leaves room for other native endianness choices. (bytevector-u32-native-ref b 12) => unspecified
The native procedures check that the index is aligned. This is because hardware generally does not handle unaligned accesses the same way as aligned accesses. An unaligned access is slower and more complicated than an aligned access for several reasons that are outside the scope of this document to explain.
Careless use of the native procedures can make a program unportable, because the program's handling of bytes will depend on the particular machine it is running on. Most computers today are little-endian, but some big-endian machines are still being made. Except for this difference, any portability concerns at lower machine layers are abstracted away.
https://github.com/schemedoc/manpages/
.