+;; Unpack all dbus messages in the given DATA block. Each message
+;; consists of head and body. The head has signature "yyyyuua(yv)"
+;; where the array is an alist of key-value pairs, optionally
+;; including the 'SIGNATURE key with the signature for the body; if
+;; omitted, then the body is empty.
+;;
+;; The function returns the header list of key-value pairs optionally
+;; extended with the pair ("" body).
+(define (unpack-messages DATA)
+ (let ((AT 0) (OUT '()) (M nil) (D nil) (S nil))
+ (while (and (< AT (length DATA))
+ (setf M (unpack-data "yyyyuua(yv)" DATA AT)))
+ (setf AT (M 1))
+ (setf M (M 0 -1)) ; Drop all but the headers then map to symbol keys
+ (dotimes (i (length M 0))
+ (setf (M i 0) (MESSAGE-HEADERS (M i 0) 0)))
+ ;; Add the body, if any, keyed by "".
+ (setf S (if (lookup 'SIGNATURE M) $it ""))
+ (when (and (!= S "") (setf D (unpack-data S DATA AT)))
+ (setf AT (D 1))
+ (extend M (list (list "" (D 0)))))
+ ;; Collate message and move to the next portion in DATA
+ (push M OUT -1)
+ (setf DATA (AT DATA))
+ (setf AT 0)
+ )
+ OUT ))
+
+"lsp-dbus-marshal.lsp"