From d6a25d1cfd834e5a218d37549b802dc137b563e7 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Tue, 28 Dec 2021 01:13:58 +0100 Subject: Decode dictionary entry arrays as dictionaries. Change-Id: If31659887dcd2d219d421f78e50cdeb1be3709a9 --- .../main/java/eu/mulk/jgvariant/core/Decoder.java | 1 + .../java/eu/mulk/jgvariant/core/Signature.java | 32 ++++++++++++++++------ .../main/java/eu/mulk/jgvariant/core/Variant.java | 1 + 3 files changed, 25 insertions(+), 9 deletions(-) (limited to 'jgvariant-core/src/main/java/eu') diff --git a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Decoder.java b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Decoder.java index 8297d79..33b0480 100644 --- a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Decoder.java +++ b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Decoder.java @@ -198,6 +198,7 @@ public abstract class Decoder { *
  • {@link Optional} (a GVariant {@code Maybe} type) *
  • {@link List} (a GVariant array) *
  • {@code Object[]} (a GVariant structure) + *
  • {@link java.util.Map} (a dictionary) *
  • {@link java.util.Map.Entry} (a dictionary entry) *
  • {@link Variant} (a nested variant) * diff --git a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Signature.java b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Signature.java index 6a4d01d..c697730 100644 --- a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Signature.java +++ b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Signature.java @@ -91,23 +91,37 @@ public final class Signature { case 's', 'o', 'g' -> Decoder.ofString(StandardCharsets.UTF_8); case 'v' -> Decoder.ofVariant(); case 'm' -> Decoder.ofMaybe(parseSignature(signature)); - case 'a' -> Decoder.ofArray(parseSignature(signature)); case '(' -> Decoder.ofStructure(parseTupleTypes(signature).toArray(new Decoder[0])); - case '{' -> { - var tupleTypes = parseTupleTypes(signature); - if (tupleTypes.size() != 2) { - throw new ParseException( - String.format( - "dictionary entry type with %d components, expected 2", tupleTypes.size()), - signature.position()); + case 'a' -> { + char elementC = (char) signature.get(signature.position()); + if (elementC == '{') { + signature.get(); + List> entryTypes = parseDictionaryEntryTypes(signature); + yield Decoder.ofDictionary(entryTypes.get(0), entryTypes.get(1)); + } else { + yield Decoder.ofArray(parseSignature(signature)); } - yield Decoder.ofDictionaryEntry(tupleTypes.get(0), tupleTypes.get(1)); + } + case '{' -> { + List> entryTypes = parseDictionaryEntryTypes(signature); + yield Decoder.ofDictionaryEntry(entryTypes.get(0), entryTypes.get(1)); } default -> throw new ParseException( String.format("encountered unknown signature byte '%c'", c), signature.position()); }; } + private static List> parseDictionaryEntryTypes(ByteBuffer signature) + throws ParseException { + var tupleTypes = parseTupleTypes(signature); + if (tupleTypes.size() != 2) { + throw new ParseException( + String.format("dictionary entry type with %d components, expected 2", tupleTypes.size()), + signature.position()); + } + return tupleTypes; + } + private static List> parseTupleTypes(ByteBuffer signature) throws ParseException { List> decoders = new ArrayList<>(); diff --git a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Variant.java b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Variant.java index 34d3945..d9e13dd 100644 --- a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Variant.java +++ b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Variant.java @@ -18,6 +18,7 @@ import org.apiguardian.api.API.Status; *
  • {@link java.util.Optional} (a GVariant {@code Maybe} type) *
  • {@link java.util.List} (a GVariant array) *
  • {@code Object[]} (a GVariant structure) + *
  • {@link java.util.Map} (a dictionary) *
  • {@link java.util.Map.Entry} (a dictionary entry) *
  • {@link Variant} (a nested variant) * -- cgit v1.2.3