get-bytevector-n!(3scm)

πŸ“¦ version 0-unstable-2024-02, in nixpkgs unstable

πŸ’… get-bytevector-n! β€” bestie edition πŸ’…

okay so this page is all about get-bytevector-n! and read-bytevector! from the Scheme Programmer's Manual β€” we're reading bytes from a port straight into a bytevector, and honestly? it's giving buffer energy ✨


🌸 LIBRARY 🌸

import these, no cap:

(import (rnrs))                     ;R6RS
(import (rnrs io ports))            ;R6RS
(import (scheme base))              ;R7RS

✨ SYNOPSIS ✨

R6RS girlies, this is your moment:

;; R6RS
(get-bytevector-n! binary-input-port bytevector start count)

R7RS besties, you get the whole overloaded menu:

;; R7RS
(read-bytevector! bytevector)
(read-bytevector! bytevector binary-input-port)
(read-bytevector! bytevector binary-input-port start)
(read-bytevector! bytevector binary-input-port start end)

πŸ¦‹ DESCRIPTION πŸ¦‹

so what it does: it reads from binary-input-port, and it blocks as necessary (yes, like it will literally just sit there and wait, main character patience πŸ’…) until count bytes are available from binary-input-port, or until we hit an end of file. the return value depends on how the read went, and there are three whole vibes:

  • if count bytes are available before an end of file, they get written into bytevector starting at index start, and the result is count. slay πŸŽ€
  • if fewer bytes are available before the next end of file, those available bytes get written into bytevector starting at index start, and the result is a number object representing the number of bytes actually read. lowkey a partial, ngl.
  • if an end of file is reached before any bytes are available, you get an end-of-file object back. that's it, that's the tea πŸ«–

The input port gets updated to point just past the bytes read. periodt.

πŸ’œ R7RS πŸ’œ

The procedure call (read-bytevector! bv port start end) is analogous to (get-bytevector-n! port bv start (- end start)). like, twins fr fr.

The argument binary-input-port defaults to the object returned by current-input-port(3scm), start defaults to 0, and end defaults to the length of bytevector. defaults are your friends 🫢

πŸŒ€ Multiple end-of-file conditions πŸŒ€

The port may return an end-of-file object and then still keep producing data if another read is attempted. like, rude but okay πŸ’€. Files do not normally work this way, but it is possible for other types of ports to do so, such as terminals. R6RS explicitly mentions this situation while R7RS does not. so if you're on R7RS and this happens... iykyk πŸ™ˆ


πŸ’– RETURN VALUES πŸ’–

Returns a single value β€” an exact nonnegative integer, or an end-of-file object. one value, no drama ✨

R6RS β€” There is a single, unique end-of-file object. the one and only πŸ‘‘


🌈 EXAMPLES 🌈

;; Apologies for the nonsensical example.
(call-with-port (open-file-input-port "/dev/zero")
  (lambda (p)
    (let ((bv (make-bytevector 4 1)))
      (get-bytevector-n! p bv 1 1)
      bv)))
      => #vu8(1 0 1 1)

the author literally apologised for it being nonsensical and honestly? iconic. we love a self-aware king πŸŽ€


πŸ“ APPLICATION USAGE πŸ“

This procedure is suitable when you need to read binary data directly into a buffer β€” which tends to be the case for some types of binary structures. it's giving "i brought my own container" energy 🧺

Other times it is more appropriate to use get-bytevector-n(3scm), which will automatically give you a bytevector limited to the length of the data returned by the read operation. so like, if you don't wanna do the math, that one's for you πŸ’…


πŸ’€ ERRORS πŸ’€

This procedure can raise exceptions with the following condition types β€” buckle up bestie:

  • &assertion (R6RS) β€” The wrong number of arguments was passed or an argument was outside its domain. In particular, start and count must be exact, nonnegative integer objects, and bytevector must be a mutable bytevector with at least start+count elements. read that twice, it matters 🫢
  • &i/o-read (R6RS) β€” There was an I/O error during the read operation. it happens, don't panic 😭
  • &i/o-port (R6RS) β€” This condition specifies the port object related to an &i/o-read condition.

R7RS β€” The assertions described above are errors. Implementations may signal an error, extend the procedure's domain of definition to include such arguments, or fail catastrophically. fail catastrophically is such a mood but also please don't πŸ’€


πŸ”₯ SEE ALSO πŸ”₯

go read these next, they're all linked:


⭐ STANDARDS ⭐

R6RS, R7RS. both of them. we stan a cross-standard icon πŸ’–


πŸŽ€ HISTORY πŸŽ€

Reports prior to R6RS did not support binary I/O. so like, before R6RS there was no binary I/O situation at all. the dark ages, truly πŸ•―οΈ


πŸ‘‘ AUTHORS πŸ‘‘

This page is part of the scheme-manpages project. It includes materials from the RnRS documents. More information can be found at https://github.com/schemedoc/manpages/. go say hi to the maintainers, they ate 🫢


πŸ™ˆ BUGS πŸ™ˆ

The default port used by read-bytevector! is the current input port β€” which is normally a textual port that is not expected to support binary I/O. so like... the default is a little bit of a setup 😭 watch out for that one bestie.


that's the whole page!! this manual page is from 2023-01-31, brought to you by the Scheme Programmer's Manual (the get-bytevector-n!(3scm) of it all πŸ’…). go read some bytes, you've got this βœ¨πŸ¦‹πŸŒΈπŸ’œ

πŸ“¦ where this page comes from