diff options
Diffstat (limited to 'jgvariant-core/src/main/java')
3 files changed, 54 insertions, 1 deletions
| 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 fee0407..96e1332 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 @@ -8,9 +8,11 @@ import java.nio.ByteBuffer;  import java.nio.ByteOrder;  import java.nio.charset.Charset;  import java.text.ParseException; +import java.util.AbstractMap.SimpleImmutableEntry;  import java.util.ArrayList;  import java.util.Arrays;  import java.util.List; +import java.util.Map;  import java.util.Optional;  import java.util.function.Function;  import org.apiguardian.api.API; @@ -155,6 +157,19 @@ public abstract class Decoder<T> {    }    /** +   * Creates a {@link Decoder} for a {@code Dictionary Entry} type, decoding into a {@link +   * Map.Entry}. +   * +   * @param keyDecoder a {@link Decoder} for the key component of the dictionary entry. +   * @param valueDecoder a {@link Decoder} for the value component of the dictionary entry. +   * @return a new {@link Decoder}. +   */ +  public static <K, V> Decoder<Map.Entry<K, V>> ofDictionaryEntry( +      Decoder<K> keyDecoder, Decoder<V> valueDecoder) { +    return new DictionaryEntryDecoder<>(keyDecoder, valueDecoder); +  } + +  /**     * Creates a {@link Decoder} for the {@link Variant} type.     *     * <p>The contained {@link Object} can be of one of the following types: @@ -169,6 +184,7 @@ public abstract class Decoder<T> {     *   <li>{@link Optional} (a GVariant {@code Maybe} type)     *   <li>{@link List} (a GVariant array)     *   <li>{@code Object[]} (a GVariant structure) +   *   <li>{@link java.util.Map.Entry} (a dictionary entry)     *   <li>{@link Variant} (a nested variant)     * </ul>     * @@ -515,6 +531,32 @@ public abstract class Decoder<T> {      }    } +  private static class DictionaryEntryDecoder<K, V> extends Decoder<Map.Entry<K, V>> { + +    private final TupleDecoder tupleDecoder; + +    DictionaryEntryDecoder(Decoder<K> keyDecoder, Decoder<V> valueDecoder) { +      this.tupleDecoder = new TupleDecoder(keyDecoder, valueDecoder); +    } + +    @Override +    public byte alignment() { +      return tupleDecoder.alignment(); +    } + +    @Override +    public Integer fixedSize() { +      return tupleDecoder.fixedSize(); +    } + +    @Override +    @SuppressWarnings("unchecked") +    public Map.Entry<K, V> decode(ByteBuffer byteSlice) { +      Object[] components = tupleDecoder.decode(byteSlice); +      return new SimpleImmutableEntry<>((K) components[0], (V) components[1]); +    } +  } +    private static class VariantDecoder extends Decoder<Variant> {      @Override 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 78e4bdd..6a4d01d 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 @@ -92,7 +92,17 @@ public final class Signature {        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 '(' -> 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()); +        } +        yield Decoder.ofDictionaryEntry(tupleTypes.get(0), tupleTypes.get(1)); +      }        default -> throw new ParseException(            String.format("encountered unknown signature byte '%c'", c), signature.position());      }; 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 d1c1049..34d3945 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;   *   <li>{@link java.util.Optional} (a GVariant {@code Maybe} type)   *   <li>{@link java.util.List} (a GVariant array)   *   <li>{@code Object[]} (a GVariant structure) + *   <li>{@link java.util.Map.Entry} (a dictionary entry)   *   <li>{@link Variant} (a nested variant)   * </ul>   * | 
