TaylanUB / scheme-bytestructures

Structured access to bytevector contents.
GNU General Public License v3.0
36 stars 6 forks source link

Using a bytevector offset in the macro API #45

Closed vijaymarupudi closed 2 years ago

vijaymarupudi commented 2 years ago

Thank for very much for this library. I had a question about the macro API, and whether it is currently possible to use it with an offset into the bytevector. That is, when part of a bytevector follows the struct.

For example, let's say I define a bytestructure like this:

(define-bytestructure-accessors
  (bs:struct `((x ,int)
               (y ,int)))
  numbers-unwrap numbers-ref numbers-set!)

And I have a bytevector like this:

(define bv #vu8(1 2 3 4 5 6 7 8 9 10))

I would like to interpret this bytevector as the struct at offset 2. However, it seems like the macro API's -ref macro works like this.

(numbers-ref bytevector struct-index)

I can't seem to include an offset. If there's a way, I wonder if it could be made clearer in the documentation. If not, I wonder if it can be included. Currently, it seems like a lot of spurious allocation and copying needs to be done to achieve what I want (using the macro API).

TaylanUB commented 2 years ago

Hmm, good question.

You could use the unwrap form and add an offset to the result, but then you will have to specify the correct accessor function yourself every time.

Example:

(define-bytestructure-accessors
  (bs:struct `((x ,int)
               (y ,int)))
  numbers-unwrap numbers-ref numbers-set!)

(bytevector-s32-ref bv (+ offset (numbers-unwrap ...))) ;; assumes 32-bit int

That's quite sub-optimal...

I think the most user-friendly way of adding this feature properly would be:

Expand define-bytestructure-accessors to allow two more arguments, something like numbers-ref* and numbers-set!*, which take an offset argument after the bytevector argument and before the actual indices.

Example:

(define-bytestructure-accessors
  (bs:struct `((x ,int)
               (y ,int)))
  numbers-unwrap
  numbers-ref
  numbers-set!
  numbers-ref*
  numbers-set!*)

(numbers-ref* bv offset index)

WDYT?

vijaymarupudi commented 2 years ago

That would work really well! Thank you!

As a sidenote: I think it was not clear in the documentation what the macro signature of the macro API's unwrapper macro is. I had to figure it out via experimenting. I believe it's (unwrapper bv offset index ...), and returns (values bv offset). It might be useful to include this in the documentation.

TaylanUB commented 2 years ago

There's an example in the code snippet here:

https://github.com/TaylanUB/scheme-bytestructures#macro-based-api

But I guess I could document the generated macros more explicitly.

vijaymarupudi commented 2 years ago

Ah you're right! I think all of the indices being numbers confused me.