diff options
Diffstat (limited to 'jgvariant-core/src/main/java')
-rw-r--r-- | jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Decoder.java | 40 |
1 files changed, 40 insertions, 0 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 96e1332..8297d79 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 @@ -1,6 +1,7 @@ package eu.mulk.jgvariant.core; import static java.nio.ByteOrder.LITTLE_ENDIAN; +import static java.util.stream.Collectors.toMap; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.RecordComponent; @@ -13,6 +14,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.function.Function; import org.apiguardian.api.API; @@ -110,6 +112,18 @@ public abstract class Decoder<T> { } /** + * Creates a {@link Decoder} for a {@code Dictionary} type. + * + * @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<K, V>> ofDictionary( + Decoder<K> keyDecoder, Decoder<V> valueDecoder) { + return new DictionaryDecoder<>(keyDecoder, valueDecoder); + } + + /** * Creates a {@link Decoder} for an {@code Array} type of element type {@code byte} into a * primitive {@code byte[]} array. * @@ -346,6 +360,32 @@ public abstract class Decoder<T> { } } + private static class DictionaryDecoder<K, V> extends Decoder<Map<K, V>> { + + private final ArrayDecoder<Map.Entry<K, V>> entryArrayDecoder; + + DictionaryDecoder(Decoder<K> keyDecoder, Decoder<V> valueDecoder) { + this.entryArrayDecoder = + new ArrayDecoder<>(new DictionaryEntryDecoder<>(keyDecoder, valueDecoder)); + } + + @Override + public byte alignment() { + return entryArrayDecoder.alignment(); + } + + @Override + public Integer fixedSize() { + return entryArrayDecoder.fixedSize(); + } + + @Override + public Map<K, V> decode(ByteBuffer byteSlice) { + List<Map.Entry<K, V>> entries = entryArrayDecoder.decode(byteSlice); + return entries.stream().collect(toMap(Entry::getKey, Entry::getValue)); + } + } + private static class ByteArrayDecoder extends Decoder<byte[]> { private static final int ELEMENT_SIZE = 1; |