From 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 7 Apr 2024 13:41:34 -0500 Subject: new repository --- devdocs/elisp/bindat-computed-types.html | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 devdocs/elisp/bindat-computed-types.html (limited to 'devdocs/elisp/bindat-computed-types.html') diff --git a/devdocs/elisp/bindat-computed-types.html b/devdocs/elisp/bindat-computed-types.html new file mode 100644 index 00000000..7ffbdc90 --- /dev/null +++ b/devdocs/elisp/bindat-computed-types.html @@ -0,0 +1,28 @@ +

Advanced data layout specifications

Bindat type expressions are not limited to the types described earlier. They can also be arbitrary Lisp forms returning Bindat type expressions. For example, the type below describes data which can either contain a 24-bit error code or a vector of bytes:

(bindat-type
+  (len      u8)
+  (payload  . (if (zerop len) (uint 24) (vec (1- len)))))
+
+

Furthermore, while composite types are normally unpacked to (and packed from) association lists, this can be changed via the use of the following special keyword arguments:

:unpack-val exp
+

When the list of fields ends with this keyword argument, then the value returned when unpacking is the value of exp instead of the standard alist. exp can refer to all the previous fields by their name.

:pack-val exp
+

If a field’s type is followed by this keyword argument, then the value packed into this field is returned by exp instead of being extracted from the alist.

:pack-var name

If the list of fields is preceded by this keyword argument, then all the subsequent :pack-val arguments can refer to the overall value to pack into this composite type via the variable named name.

For example, one could describe a 16-bit signed integer as follows:

(defconst sint16-bindat-spec
+  (let* ((max (ash 1 15))
+         (wrap (+ max max)))
+    (bindat-type :pack-var v
+                 (n uint 16 :pack-val (if (< v 0) (+ v wrap) v))
+                 :unpack-val (if (>= n max) (- n wrap) n))))
+
+

Which would then behave as follows:

+
(bindat-pack sint16-bindat-spec -8)
+     ⇒ "\377\370"
+
+(bindat-unpack sint16-bindat-spec "\300\100")
+     ⇒ -16320
+
+

Finally, you can define new Bindat type forms to use in Bindat type expressions with bindat-defmacro:

Macro: bindat-defmacro name args &rest body +

Define a new Bindat type expression named name and taking arguments args. Its behavior follows that of defmacro, which the important difference that the new forms can only be used within Bindat type expressions.

+
+

+ Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
+ https://www.gnu.org/software/emacs/manual/html_node/elisp/Bindat-Computed-Types.html +

+
-- cgit v1.2.3