From e9a5b640ac2498a8d45fe9ba8d21a188422d1c6d Mon Sep 17 00:00:00 2001 From: Joshua Suskalo Date: Thu, 7 Jul 2022 16:08:41 -0500 Subject: [PATCH] Add support for flagset composite types --- README.md | 1 - src/clj/coffi/mem.clj | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 71ae4ea..461233e 100644 --- a/README.md +++ b/README.md @@ -1104,7 +1104,6 @@ These features are planned for future releases. - Support for va_args type - Header parsing tool for generating a data model? - Generic type aliases -- Helpers for generating bitflags - Unsigned integer types - Record-based struct types - Helper macro for out arguments diff --git a/src/clj/coffi/mem.clj b/src/clj/coffi/mem.clj index e95a518..792c04f 100644 --- a/src/clj/coffi/mem.clj +++ b/src/clj/coffi/mem.clj @@ -1279,6 +1279,28 @@ [obj [_enum variants & {:keys [_repr]}]] ((set/map-invert (enum-variants-map variants)) obj)) +;;; Flagsets + +(defmethod primitive-type ::flagset + [[_flagset _bits & {:keys [repr]}]] + (if repr + (primitive-type repr) + ::int)) + +(defmethod serialize* ::flagset + [obj [_flagset bits & {:keys [repr]}] scope] + (let [bits-map (enum-variants-map bits)] + (reduce #(bit-set %1 (get bits-map %2)) (serialize* 0 (or repr ::int) scope) obj))) + +(defmethod deserialize* ::flagset + [obj [_flagset bits & {:keys [repr]}]] + (let [bits-map (set/map-invert (enum-variants-map bits))] + (reduce #(if-not (zero? (bit-and 1 (bit-shift-right obj %2))) + (conj %1 (bits-map %2)) + %1) + #{} + (range (* 8 (size-of (or repr ::int))))))) + (s/def ::type (s/spec (s/nonconforming