diff --git a/src/main/java/eu/mulk/jgvariant/core/Decoder.java b/src/main/java/eu/mulk/jgvariant/core/Decoder.java
new file mode 100644
index 0000000..2ebd0af
--- /dev/null
+++ b/src/main/java/eu/mulk/jgvariant/core/Decoder.java
@@ -0,0 +1,418 @@
+package eu.mulk.jgvariant.core;
+
+import static java.nio.ByteOrder.LITTLE_ENDIAN;
+
+import eu.mulk.jgvariant.core.Value.Array;
+import eu.mulk.jgvariant.core.Value.Bool;
+import eu.mulk.jgvariant.core.Value.Float64;
+import eu.mulk.jgvariant.core.Value.Int16;
+import eu.mulk.jgvariant.core.Value.Int32;
+import eu.mulk.jgvariant.core.Value.Int64;
+import eu.mulk.jgvariant.core.Value.Int8;
+import eu.mulk.jgvariant.core.Value.Maybe;
+import eu.mulk.jgvariant.core.Value.Str;
+import eu.mulk.jgvariant.core.Value.Structure;
+import eu.mulk.jgvariant.core.Value.Variant;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.RecordComponent;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Type class for decodable {@link Value} types.
+ *
+ * <p>Use the {@code of*} family of constructor methods to acquire a suitable {@link Decoder} for
+ * the type you wish to decode.
+ *
+ * @param <T> the type that the {@link Decoder} can decode.
+ */
+@SuppressWarnings("java:S1610")
+public abstract class Decoder<T extends Value> {
+
+  private Decoder() {}
+
+  /**
+   * @throws java.nio.BufferUnderflowException if the byte buffer is shorter than the requested
+   *     data.
+   */
+  public abstract T decode(ByteBuffer byteSlice);
+
+  abstract byte alignment();
+
+  @Nullable
+  abstract Integer fixedSize();
+
+  final boolean hasFixedSize() {
+    return fixedSize() != null;
+  }
+
+  public Decoder<T> withByteOrder(ByteOrder byteOrder) {
+    var delegate = this;
+
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return delegate.alignment();
+      }
+
+      @Override
+      public @Nullable Integer fixedSize() {
+        return delegate.fixedSize();
+      }
+
+      @Override
+      public T decode(ByteBuffer byteSlice) {
+        byteSlice.order(byteOrder);
+        return delegate.decode(byteSlice);
+      }
+    };
+  }
+
+  public static <U extends Value> Decoder<Array<U>> ofArray(Decoder<U> elementDecoder) {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return elementDecoder.alignment();
+      }
+
+      @Override
+      @Nullable
+      Integer fixedSize() {
+        return null;
+      }
+
+      @Override
+      public Array<U> decode(ByteBuffer byteSlice) {
+        List<U> elements;
+
+        var elementSize = elementDecoder.fixedSize();
+        if (elementSize != null) {
+          // A simple C-style array.
+          elements = new ArrayList<>(byteSlice.limit() / elementSize);
+          for (int i = 0; i < byteSlice.limit(); i += elementSize) {
+            var element = elementDecoder.decode(byteSlice.slice(i, elementSize));
+            elements.add(element);
+          }
+        } else {
+          // An array with aligned elements and a vector of framing offsets in the end.
+          int framingOffsetSize = byteCount(byteSlice.limit());
+          int lastFramingOffset =
+              getIntN(byteSlice.slice(byteSlice.limit() - framingOffsetSize, framingOffsetSize));
+          int elementCount = (byteSlice.limit() - lastFramingOffset) / framingOffsetSize;
+
+          elements = new ArrayList<>(elementCount);
+          int position = 0;
+          for (int i = 0; i < elementCount; i++) {
+            int framingOffset =
+                getIntN(
+                    byteSlice.slice(lastFramingOffset + i * framingOffsetSize, framingOffsetSize));
+            elements.add(
+                elementDecoder.decode(byteSlice.slice(position, framingOffset - position)));
+            position = align(framingOffset, alignment());
+          }
+        }
+
+        return new Array<>(elements);
+      }
+    };
+  }
+
+  private static int align(int offset, byte alignment) {
+    return offset % alignment == 0 ? offset : offset + alignment - (offset % alignment);
+  }
+
+  private static int getIntN(ByteBuffer byteSlice) {
+    var intBytes = new byte[4];
+    byteSlice.get(intBytes, 0, Math.min(4, byteSlice.limit()));
+    return ByteBuffer.wrap(intBytes).order(LITTLE_ENDIAN).getInt();
+  }
+
+  @SuppressWarnings("java:S3358")
+  private static int byteCount(int n) {
+    return n < (1 << 8) ? 1 : n < (1 << 16) ? 2 : 4;
+  }
+
+  public static <U extends Value> Decoder<Maybe<U>> ofMaybe(Decoder<U> elementDecoder) {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return elementDecoder.alignment();
+      }
+
+      @Override
+      @Nullable
+      Integer fixedSize() {
+        return null;
+      }
+
+      @Override
+      public Maybe<U> decode(ByteBuffer byteSlice) {
+        if (!byteSlice.hasRemaining()) {
+          return new Maybe<>(Optional.empty());
+        } else {
+          if (!elementDecoder.hasFixedSize()) {
+            // Remove trailing zero byte.
+            byteSlice.limit(byteSlice.limit() - 1);
+          }
+
+          return new Maybe<>(Optional.of(elementDecoder.decode(byteSlice)));
+        }
+      }
+    };
+  }
+
+  @SafeVarargs
+  public static <U extends Record> Decoder<Structure<U>> ofStructure(
+      Class<U> recordType, Decoder<? extends Value>... componentDecoders) {
+    var recordComponents = recordType.getRecordComponents();
+    if (componentDecoders.length != recordComponents.length) {
+      throw new IllegalArgumentException(
+          "number of decoders (%d) does not match number of structure components (%d)"
+              .formatted(componentDecoders.length, recordComponents.length));
+    }
+
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return (byte) Arrays.stream(componentDecoders).mapToInt(Decoder::alignment).max().orElse(1);
+      }
+
+      @Override
+      public Integer fixedSize() {
+        int position = 0;
+        for (var componentDecoder : componentDecoders) {
+          var fixedComponentSize = componentDecoder.fixedSize();
+          if (fixedComponentSize == null) {
+            return null;
+          }
+
+          position = align(position, componentDecoder.alignment());
+          position += fixedComponentSize;
+        }
+
+        if (position == 0) {
+          return 1;
+        }
+
+        return align(position, alignment());
+      }
+
+      @Override
+      public Structure<U> decode(ByteBuffer byteSlice) {
+        int framingOffsetSize = byteCount(byteSlice.limit());
+
+        var recordConstructorArguments = new Object[recordComponents.length];
+
+        int position = 0;
+        int framingOffsetIndex = 0;
+        int componentIndex = 0;
+        for (var componentDecoder : componentDecoders) {
+          position = align(position, componentDecoder.alignment());
+
+          var fixedComponentSize = componentDecoder.fixedSize();
+          if (fixedComponentSize != null) {
+            recordConstructorArguments[componentIndex] =
+                componentDecoder.decode(byteSlice.slice(position, fixedComponentSize));
+            position += fixedComponentSize;
+          } else {
+            if (componentIndex == recordComponents.length - 1) {
+              // The last component never has a framing offset.
+              int endPosition = byteSlice.limit() - framingOffsetIndex * framingOffsetSize;
+              recordConstructorArguments[componentIndex] =
+                  componentDecoder.decode(byteSlice.slice(position, endPosition - position));
+              position = endPosition;
+            } else {
+              int framingOffset =
+                  getIntN(
+                      byteSlice.slice(
+                          byteSlice.limit() - (1 + framingOffsetIndex) * framingOffsetSize,
+                          framingOffsetSize));
+              recordConstructorArguments[componentIndex] =
+                  componentDecoder.decode(byteSlice.slice(position, framingOffset - position));
+              position = framingOffset;
+              ++framingOffsetIndex;
+            }
+          }
+
+          ++componentIndex;
+        }
+
+        try {
+          var recordComponentTypes =
+              Arrays.stream(recordType.getRecordComponents())
+                  .map(RecordComponent::getType)
+                  .toArray(Class<?>[]::new);
+          var recordConstructor = recordType.getDeclaredConstructor(recordComponentTypes);
+          return new Structure<>(recordConstructor.newInstance(recordConstructorArguments));
+        } catch (NoSuchMethodException
+            | InstantiationException
+            | IllegalAccessException
+            | InvocationTargetException e) {
+          throw new IllegalStateException(e);
+        }
+      }
+    };
+  }
+
+  public static Decoder<Variant> ofVariant() {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return 8;
+      }
+
+      @Override
+      @Nullable
+      Integer fixedSize() {
+        return null;
+      }
+
+      @Override
+      public Variant decode(ByteBuffer byteSlice) {
+        // TODO
+        throw new UnsupportedOperationException("not implemented");
+      }
+    };
+  }
+
+  public static Decoder<Bool> ofBoolean() {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return 1;
+      }
+
+      @Override
+      public Integer fixedSize() {
+        return 1;
+      }
+
+      @Override
+      public Bool decode(ByteBuffer byteSlice) {
+        return new Bool(byteSlice.get() != 0);
+      }
+    };
+  }
+
+  public static Decoder<Int8> ofInt8() {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return 1;
+      }
+
+      @Override
+      public Integer fixedSize() {
+        return 1;
+      }
+
+      @Override
+      public Int8 decode(ByteBuffer byteSlice) {
+        return new Int8(byteSlice.get());
+      }
+    };
+  }
+
+  public static Decoder<Int16> ofInt16() {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return 2;
+      }
+
+      @Override
+      public Integer fixedSize() {
+        return 2;
+      }
+
+      @Override
+      public Int16 decode(ByteBuffer byteSlice) {
+        return new Int16(byteSlice.getShort());
+      }
+    };
+  }
+
+  public static Decoder<Int32> ofInt32() {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return 4;
+      }
+
+      @Override
+      public Integer fixedSize() {
+        return 4;
+      }
+
+      @Override
+      public Int32 decode(ByteBuffer byteSlice) {
+        return new Int32(byteSlice.getInt());
+      }
+    };
+  }
+
+  public static Decoder<Int64> ofInt64() {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return 8;
+      }
+
+      @Override
+      public Integer fixedSize() {
+        return 8;
+      }
+
+      @Override
+      public Int64 decode(ByteBuffer byteSlice) {
+        return new Int64(byteSlice.getLong());
+      }
+    };
+  }
+
+  public static Decoder<Float64> ofFloat64() {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return 8;
+      }
+
+      @Override
+      public Integer fixedSize() {
+        return 8;
+      }
+
+      @Override
+      public Float64 decode(ByteBuffer byteSlice) {
+        return new Float64(byteSlice.getDouble());
+      }
+    };
+  }
+
+  public static Decoder<Str> ofStr(Charset charset) {
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return 1;
+      }
+
+      @Override
+      @Nullable
+      Integer fixedSize() {
+        return null;
+      }
+
+      @Override
+      public Str decode(ByteBuffer byteSlice) {
+        byteSlice.limit(byteSlice.limit() - 1);
+        return new Str(charset.decode(byteSlice).toString());
+      }
+    };
+  }
+}
diff --git a/src/main/java/eu/mulk/jgvariant/core/Value.java b/src/main/java/eu/mulk/jgvariant/core/Value.java
new file mode 100644
index 0000000..969f240
--- /dev/null
+++ b/src/main/java/eu/mulk/jgvariant/core/Value.java
@@ -0,0 +1,35 @@
+package eu.mulk.jgvariant.core;
+
+import java.util.List;
+import java.util.Optional;
+
+/** A value representable by the GVariant serialization format. */
+public sealed interface Value {
+
+  // Composite types
+  record Array<T extends Value>(List<T> values) implements Value {}
+
+  record Maybe<T extends Value>(Optional<T> value) implements Value {}
+
+  record Structure<T extends Record>(T values) implements Value {}
+
+  record Variant(Class<? extends Value> type, Value value) implements Value {}
+
+  // Primitive types
+  record Bool(boolean value) implements Value {
+    static Bool TRUE = new Bool(true);
+    static Bool FALSE = new Bool(false);
+  }
+
+  record Int8(byte value) implements Value {}
+
+  record Int16(short value) implements Value {}
+
+  record Int32(int value) implements Value {}
+
+  record Int64(long value) implements Value {}
+
+  record Float64(double value) implements Value {}
+
+  record Str(String value) implements Value {}
+}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000..8880c0b
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,7 @@
+module eu.mulk.jgvariant.core {
+  requires java.base;
+  requires com.google.errorprone.annotations;
+  requires org.jetbrains.annotations;
+
+  exports eu.mulk.jgvariant.core;
+}
diff --git a/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java b/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java
new file mode 100644
index 0000000..4deb8bc
--- /dev/null
+++ b/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java
@@ -0,0 +1,278 @@
+package eu.mulk.jgvariant.core;
+
+import static java.nio.ByteOrder.LITTLE_ENDIAN;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import eu.mulk.jgvariant.core.Value.Array;
+import eu.mulk.jgvariant.core.Value.Bool;
+import eu.mulk.jgvariant.core.Value.Int32;
+import eu.mulk.jgvariant.core.Value.Int8;
+import eu.mulk.jgvariant.core.Value.Maybe;
+import eu.mulk.jgvariant.core.Value.Str;
+import eu.mulk.jgvariant.core.Value.Structure;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests based on the examples given in <a
+ * href="https://people.gnome.org/~desrt/gvariant-serialisation.pdf">~desrt/gvariant-serialisation.pdf</a>.
+ */
+class DecoderTest {
+
+  @Test
+  void testString() {
+    var data = new byte[] {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x00};
+    var decoder = Decoder.ofStr(UTF_8);
+    assertEquals(new Str("hello world"), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testMaybe() {
+    var data =
+        new byte[] {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x00, 0x00};
+    var decoder = Decoder.ofMaybe(Decoder.ofStr(UTF_8));
+    assertEquals(
+        new Maybe<>(Optional.of(new Str("hello world"))), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testBooleanArray() {
+    var data = new byte[] {0x01, 0x00, 0x00, 0x01, 0x01};
+    var decoder = Decoder.ofArray(Decoder.ofBoolean());
+    assertEquals(
+        new Array<>(List.of(Bool.TRUE, Bool.FALSE, Bool.FALSE, Bool.TRUE, Bool.TRUE)),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testStructure() {
+    var data =
+        new byte[] {
+          0x66, 0x6F, 0x6F, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 0x04
+        };
+
+    record TestRecord(Str s, Int32 i) {}
+
+    var decoder = Decoder.ofStructure(TestRecord.class, Decoder.ofStr(UTF_8), Decoder.ofInt32());
+    assertEquals(
+        new Structure<>(new TestRecord(new Str("foo"), new Int32(-1))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testComplexStructureArray() {
+    var data =
+        new byte[] {
+          0x68,
+          0x69,
+          0x00,
+          0x00,
+          (byte) 0xfe,
+          (byte) 0xff,
+          (byte) 0xff,
+          (byte) 0xff,
+          0x03,
+          0x00,
+          0x00,
+          0x00,
+          0x62,
+          0x79,
+          0x65,
+          0x00,
+          (byte) 0xff,
+          (byte) 0xff,
+          (byte) 0xff,
+          (byte) 0xff,
+          0x04,
+          0x09,
+          0x15
+        };
+
+    record TestRecord(Str s, Int32 i) {}
+
+    var decoder =
+        Decoder.ofArray(
+            Decoder.ofStructure(
+                TestRecord.class,
+                Decoder.ofStr(UTF_8),
+                Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN)));
+    assertEquals(
+        new Array<>(
+            List.of(
+                new Structure<>(new TestRecord(new Str("hi"), new Int32(-2))),
+                new Structure<>(new TestRecord(new Str("bye"), new Int32(-1))))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testStringArray() {
+    var data =
+        new byte[] {
+          0x69, 0x00, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E,
+          0x67, 0x73, 0x3F, 0x00, 0x02, 0x06, 0x0a, 0x13
+        };
+    var decoder = Decoder.ofArray(Decoder.ofStr(UTF_8));
+    assertEquals(
+        new Array<>(List.of(new Str("i"), new Str("can"), new Str("has"), new Str("strings?"))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testNestedStructure() {
+    var data =
+        new byte[] {
+          0x69, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
+          0x73, 0x3F, 0x00, 0x04, 0x0d, 0x05
+        };
+
+    record TestChild(Int8 b, Str s) {}
+    record TestParent(Structure<TestChild> tc, Array<Str> as) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestParent.class,
+            Decoder.ofStructure(TestChild.class, Decoder.ofInt8(), Decoder.ofStr(UTF_8)),
+            Decoder.ofArray(Decoder.ofStr(UTF_8)));
+
+    assertEquals(
+        new Structure<>(
+            new TestParent(
+                new Structure<>(new TestChild(new Int8((byte) 0x69), new Str("can"))),
+                new Array<>(List.of(new Str("has"), new Str("strings?"))))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testSimpleStructure() {
+    var data = new byte[] {0x60, 0x70};
+
+    record TestRecord(Int8 b1, Int8 b2) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestRecord.class,
+            Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN),
+            Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN));
+
+    assertEquals(
+        new Structure<>(new TestRecord(new Int8((byte) 0x60), new Int8((byte) 0x70))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testPaddedStructureRight() {
+    var data = new byte[] {0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00};
+
+    record TestRecord(Int32 b1, Int8 b2) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestRecord.class,
+            Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN),
+            Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN));
+
+    assertEquals(
+        new Structure<>(new TestRecord(new Int32(0x60), new Int8((byte) 0x70))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testPaddedStructureLeft() {
+    var data = new byte[] {0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00};
+
+    record TestRecord(Int8 b1, Int32 b2) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestRecord.class,
+            Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN),
+            Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN));
+
+    assertEquals(
+        new Structure<>(new TestRecord(new Int8((byte) 0x60), new Int32(0x70))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testSimpleStructureArray() {
+    var data =
+        new byte[] {
+          0x60,
+          0x00,
+          0x00,
+          0x00,
+          0x70,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0x88,
+          0x02,
+          0x00,
+          0x00,
+          (byte) 0xF7,
+          0x00,
+          0x00,
+          0x00
+        };
+
+    record TestRecord(Int32 b1, Int8 b2) {}
+
+    var decoder =
+        Decoder.ofArray(
+            Decoder.ofStructure(
+                TestRecord.class,
+                Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN),
+                Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN)));
+
+    assertEquals(
+        new Array<>(
+            List.of(
+                new Structure<>(new TestRecord(new Int32(96), new Int8((byte) 0x70))),
+                new Structure<>(new TestRecord(new Int32(648), new Int8((byte) 0xf7))))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testByteArray() {
+    var data = new byte[] {0x04, 0x05, 0x06, 0x07};
+
+    var decoder = Decoder.ofArray(Decoder.ofInt8());
+
+    assertEquals(
+        new Array<>(
+            List.of(
+                new Int8((byte) 0x04),
+                new Int8((byte) 0x05),
+                new Int8((byte) 0x06),
+                new Int8((byte) 0x07))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testIntegerArray() {
+    var data = new byte[] {0x04, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00};
+
+    var decoder = Decoder.ofArray(Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN));
+
+    assertEquals(
+        new Array<>(List.of(new Int32(4), new Int32(258))), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testDictionaryEntry() {
+    var data =
+        new byte[] {0x61, 0x20, 0x6B, 0x65, 0x79, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x06};
+
+    record TestEntry(Str key, Int32 value) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestEntry.class, Decoder.ofStr(UTF_8), Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN));
+    assertEquals(
+        new Structure<>(new TestEntry(new Str("a key"), new Int32(514))),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+}
