Open HugoNikanor opened 2 years ago
My above proposed scheme would also allows users to work with the string representation of DBus-types, instead of the sexp version if they so choose. Attached is a quick converter between the two.
(This assumes that the current DBus types are stable)
(use-modules (ice-9 match)
((rnrs io simple) :select (peek-char read-char)))
(define (dbus-type->string type)
(match type
('byte "y")
('boolean "b")
('int16 "n")
('uint16 "q")
('int32 "i")
('uint32 "u")
('int64 "x")
('uint64 "t")
('double "d")
('string "s")
('object-path "o")
('signature "g")
('unix-fd "h")
(('array type) (string-append "a" (dbus-type->string type)))
('variant "v")
(('struct types ...)
(with-output-to-string
(lambda ()
(display "(")
(for-each (compose display dbus-type->string) types)
(display ")"))))
(('dict-entry key-type value-type)
(string-append "{"
(dbus-type->string key-type)
(dbus-type->string value-type)
"}"))))
(define (read-dbus-type port)
;; (assert (not (eof-object? (peek-char port))
(case (read-char port)
((#\y) 'byte)
((#\b) 'boolean)
((#\n) 'int16)
((#\q) 'uint116)
((#\i) 'int32)
((#\u) 'uint32)
((#\x) 'int64)
((#\t) 'uint64)
((#\d) 'double)
((#\s) 'string)
((#\o) 'object-path)
((#\g) 'signature)
((#\h) 'unix-fd)
((#\a) `(array ,(read-dbus-type port)))
((#\v) 'variant)
((#\()
(cons 'struct
(let loop ()
(if (char=? #\) (peek-char port))
(begin (read-char port) '())
;; let to force order
(let ((t (read-dbus-type port)))
(cons t (loop)))))))
((#\{)
;; let* to ensure order
(let* ((key-type (read-dbus-type port))
(val-type (read-dbus-type port)))
(read-char port) ; "eat" ending brace
`(dict-entry ,key-type ,val-type)))
(else
(throw 'key-error "Unknown type char"))))
(define (string->dbus-type string)
(call-with-input-string string read-dbus-type))
Currently, simple types are represented as
(type-name value)
, while complex types are mostly missing (with a bit of an exception for Arrays. I have experimented with support for the DBus:s different complex types over at https://github.com/HugoNikanor/guile-dbus/tree/complex-types, and realized that the naïve approach will probably be way to verbose to be usable.My code currently encodes something like
a(i(ii))
asWhich obviously gets very verbose very quickly, and poses problems when sending the data, since something needs to be there to be able to see the type information.
I would suggest extending the form used for the simple types, so that any top-level value is represented by a pair of a type and a value (of that type). The example above would thet become (using lists for DBus arrays, and vectors for structs):
Some other miscellaneous items to look at:
a{KV}
(whereK
andV
are type), so that instead of an array (or vector) of pairs, we instead built a hash table directly.How do you feel about this? Do you like this idea? Or do you have something better yourself?