bytevector-sint-ref(3scm)

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

πŸ’… bytevector-sint-ref β€” the girlies are doing variable-length integer math

ok so this is the bytevector-sint-ref(3scm) page from the Scheme Programmer's Manual, and honestly? it's giving byte-level main character energy ✨


πŸŽ€ LIBRARY πŸŽ€

(import (rnrs))                     ;R6RS
(import (rnrs bytevectors))         ;R6RS

two ways to get it, both R6RS, pick your fighter 🫢


✨ SYNOPSIS ✨

(bytevector-sint-ref bytevector k endianness size)
(bytevector-uint-ref bytevector k endianness size)
(bytevector-sint-set! bytevector k n endianness size)
(bytevector-uint-set! bytevector k n endianness size)

four functions, one vibe check, no cap. πŸ“‹


🌸 NAME 🌸

bytevector-sint-ref, bytevector-sint-set!, bytevector-uint-ref, bytevector-uint-set! β€” literally the variable length bytevector operations, bestie πŸ’–


πŸ¦‹ DESCRIPTION πŸ¦‹

okay so these procedures are for working with variable-length integers encoded in bytevectors. yes, the whole point is that the int doesn't have to be the usual fixed width β€” you tell it how many bytes to use and it just goes.

bytevector-sint-ref and bytevector-uint-ref decode a signed or unsigned integer (respectively) out of bytevector, starting at index k, following endianness, and reading size bytes. that's the whole read pipeline, slay.

the integers themselves are encoded according to signedness, endianness and size β€” all three, all mattering:

  • signed vs unsigned? that's chosen by which procedure you call. no flag, just vibes and the right function name πŸ™ˆ
  • size is a positive exact integer that determines how many bytes the encoded integer uses β€” so a 128-bit integer would have a size of 16. iconic math moment.
  • endianness is normally one of these symbols:
  • big β€” Big endian. The more significant bytes come before the less significant bytes. so big stuff first, obviously πŸ‘‘
  • little β€” Little endian. The less significant bytes come before the more significant bytes. tiny stuff first, it's giving underdog energy 🐣

the signed variants use the two's complement representation. (iykyk, two's complement is the bit-twiddling girlie representation.)

the range that can be encoded by the unsigned variants is [0,(256^size)βˆ’1]. the range of the signed variants is [βˆ’(256^size)/2,((256^size)/2)-1].

write those ranges down, they're important. periodt. πŸ“


πŸ’œ RETURN VALUES πŸ’œ

  • bytevector-sint-ref and bytevector-uint-ref return a single exact integer object. one value, exact, gorgeous.
  • bytevector-sint-set! and bytevector-uint-set! return unspecified values. they did their job, don't ask them for receipts πŸ’€

πŸ“ EXAMPLES πŸ“

okay this example is genuinely a little work of art, watch this:

(define b (make-bytevector 16 -127))

;; Using (endianness little) is the same as writing
;; (quote little), but it gives a free typo check.
(bytevector-uint-set! b 0 (- (expt 2 128) 3)
                     (endianness little) 16)

(bytevector-uint-ref b 0 (endianness little) 16)
          =>
    #xfffffffffffffffffffffffffffffffd

(bytevector-sint-ref b 0 (endianness little) 16)
          => -3

(bytevector->u8-list b)
          => (253 255 255 255 255 255 255 255
              255 255 255 255 255 255 255 255)

(bytevector-uint-set! b 0 (- (expt 2 128) 3)
                 (endianness big) 16)
(bytevector-uint-ref b 0 (endianness big) 16)
          =>
    #xfffffffffffffffffffffffffffffffd

(bytevector-sint-ref b 0 (endianness big) 16)
          => -3

(bytevector->u8-list b)
          => (255 255 255 255 255 255 255 255
              255 255 255 255 255 255 255 253))
quick note on that comment in the example, bestie: using (endianness little) is the same as writing (quote little), but it gives a free typo check. free typo check!! we love a self-care API πŸ’…

and notice how the unsigned ref gives you #xfffffffffffffffffffffffffffffffd but the signed ref gives you -3? same bytes, different attitude. also notice how flipping little β†’ big moves the 253 from the front to the back. that's endianness, baby 🌈


πŸ”₯ APPLICATION USAGE πŸ”₯

these procedures are used in some data formats that encode variable-length integers by using an explicit length encoding. so the length is just... right there, spelled out. cute.

but heads up β€” Base-128 compression, where the highest bit in every byte is a continuation flag, is more common. so these aren't the popular girlies of variable-length encoding, they're the niche iconique ones. 🧚

they are sometimes used in code that is easier to express as operations on integers rather than bytevectors. fair, honestly β€” sometimes the integer is the vibe and the bytevector is just the middleman.


😭 ERRORS 😭

this procedure can raise exceptions with the following condition types:

  • &assertion (R6RS) β€” The wrong number of arguments was passed or an argument was outside its domain. In particular, if size is zero or k+size-1 is not a valid index of bytevector.

so yeah. wrong arg count, out-of-domain arg, size of zero, or an index that doesn't exist β€” all of those get you an &assertion. it's giving strict boundaries and honestly we respect it. 🚧


🌟 SEE ALSO 🌟

the fixed-width cousins!! go say hi, they're also doing great πŸ’–


πŸ‘‘ STANDARDS πŸ‘‘

R6RS

that's it. that's the standard. periodt.


πŸŽ€ 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/.

shoutout to the scheme-manpages girlies for compiling all this, absolute legends 🫢


πŸ’€ BUGS πŸ’€

In some type of code it is easy to make the mistake of passing a zero size argument, which will raise an exception.

so like… if you're in that kind of code where size might accidentally be zero, you WILL get an exception thrown at you. no warning, no chill, just an exception. love that for us. πŸ™ˆ


βœ¨πŸ’– and that's the page!! brought to you by the Scheme Programmer's Manual, dated 2021-03-02 β€” yes bestie, that's the source, the version and the date all folded into one adorable little sign-off. go forth and encode your variable-length integers with confidence. slay. πŸ’–βœ¨
πŸ“¦ where this page comes from