Closed joelreymont closed 1 month ago
There's nothing in the library that handles validation. The closest that's implemented is the custom type specifier, which allows you to provide functions to read and write the field. If a lambda
form is provided, it'll be a closure of a scope where all the fields of the struct that are available can be accessed as variables. In the writer, these variables are bound using cl:with-slots
. These functions can do validation, but that comes at the cost of not being able to have code generated to do the actual reading and writing.
Your use case could be the impetus to implement a whole new feature: Each slot in a defbinary
struct would have an optional :validator
function that would have the option of returning T or NIL to indicte whether the value is valid, or signalling to give the user a customized error message.
Instead of a function, :validator
could just be a form, which would be evaluated in a context where all the fields read so far would be bound to variables visible to the form.
Both usages could be supported simultaneously.
There would still be gaps for your use-case: When reading, Lisp-Binary only keeps the decoded versions of values read so far, but when checking a CRC, you'll want the raw bytes. When writing, I would want the writer for header-crc
and packet-crc
to calculate the CRC automatically. The best solution I can think of for this gap would be to wrap the stream in a Gray stream that caches the raw data being read or written, to make it available for the CRC calculation. Then, it's at least possible to check the CRC from a custom
reader, and generate it in the custom
writer function.
I have a packet header header defined as follows.
How do I ensure that
size
is less than 1023,header_crc
matches the checksum of the first 3 bytes of the packet, andpacket_crc
matches the checksum of the packet, excluding the 2 bytes of the checksum itself?I will supply both checksum functions.