aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/eu/mulk/jgvariant/core/Decoder.java652
-rw-r--r--src/main/java/eu/mulk/jgvariant/core/Signature.java116
-rw-r--r--src/main/java/eu/mulk/jgvariant/core/Variant.java30
-rw-r--r--src/main/java/eu/mulk/jgvariant/core/package-info.java27
-rw-r--r--src/main/java/module-info.java63
5 files changed, 0 insertions, 888 deletions
diff --git a/src/main/java/eu/mulk/jgvariant/core/Decoder.java b/src/main/java/eu/mulk/jgvariant/core/Decoder.java
deleted file mode 100644
index d2f2403..0000000
--- a/src/main/java/eu/mulk/jgvariant/core/Decoder.java
+++ /dev/null
@@ -1,652 +0,0 @@
-package eu.mulk.jgvariant.core;
-
-import static java.nio.ByteOrder.LITTLE_ENDIAN;
-
-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.text.ParseException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-import org.apiguardian.api.API;
-import org.apiguardian.api.API.Status;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Type class for decodable types.
- *
- * <p>Use the {@code of*} family of constructor methods to acquire a suitable {@link Decoder} for
- * the type you wish to decode.
- *
- * <p><strong>Example</strong>
- *
- * <p>To parse a GVariant of type {@code "a(si)"}, which is an array of pairs of {@link String} and
- * {@code int}, you can use the following code:
- *
- * <pre>{@code
- * record ExampleRecord(String s, int i) {}
- *
- * var decoder =
- * Decoder.ofArray(
- * Decoder.ofStructure(
- * ExampleRecord.class,
- * Decoder.ofString(UTF_8),
- * Decoder.ofInt().withByteOrder(LITTLE_ENDIAN)));
- *
- * byte[] bytes = ...;
- * List<ExampleRecord> example = decoder.decode(ByteBuffer.wrap(bytes));
- * }</pre>
- *
- * @param <T> the type that the {@link Decoder} can decode.
- */
-@SuppressWarnings("java:S1610")
-@API(status = Status.EXPERIMENTAL)
-public abstract class Decoder<T> {
-
- private Decoder() {}
-
- /**
- * Decodes a {@link ByteBuffer} holding a serialized GVariant into a value of type {@code T}.
- *
- * <p><strong>Note:</strong> Due to the way the GVariant serialization format works, it is
- * important that the start and end boundaries of the passed byte slice correspond to the actual
- * start and end of the serialized value. The format does generally not allow for the dynamic
- * discovery of the end of the data structure.
- *
- * @param byteSlice a byte slice holding a serialized GVariant.
- * @return the deserialized value.
- * @throws java.nio.BufferUnderflowException if the byte buffer is shorter than the requested
- * data.
- * @throws IllegalArgumentException if the serialized GVariant is ill-formed
- */
- public abstract T decode(ByteBuffer byteSlice);
-
- abstract byte alignment();
-
- @Nullable
- abstract Integer fixedSize();
-
- final boolean hasFixedSize() {
- return fixedSize() != null;
- }
-
- /**
- * Switches the input {@link ByteBuffer} to a given {@link ByteOrder} before reading from it.
- *
- * @param byteOrder the byte order to use.
- * @return a new, decorated {@link Decoder}.
- */
- 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);
- }
- };
- }
-
- /**
- * Creates a {@link Decoder} for an {@code Array} type.
- *
- * @param elementDecoder a {@link Decoder} for the elements of the array.
- * @param <U> the element type.
- * @return a new {@link Decoder}.
- */
- public static <U> Decoder<List<U>> ofArray(Decoder<U> elementDecoder) {
- return new ArrayDecoder<>(elementDecoder);
- }
-
- /**
- * Creates a {@link Decoder} for a {@code Maybe} type.
- *
- * @param elementDecoder a {@link Decoder} for the contained element.
- * @param <U> the element type.
- * @return a new {@link Decoder}.
- */
- public static <U> Decoder<Optional<U>> ofMaybe(Decoder<U> elementDecoder) {
- return new MaybeDecoder<>(elementDecoder);
- }
-
- /**
- * Creates a {@link Decoder} for a {@code Structure} type, decoding into a {@link Record}.
- *
- * @param recordType the {@link Record} type that represents the components of the structure.
- * @param componentDecoders a {@link Decoder} for each component of the structure.
- * @param <U> the {@link Record} type that represents the components of the structure.
- * @return a new {@link Decoder}.
- */
- public static <U extends Record> Decoder<U> ofStructure(
- Class<U> recordType, Decoder<?>... componentDecoders) {
- return new StructureDecoder<>(recordType, componentDecoders);
- }
-
- /**
- * Creates a {@link Decoder} for a {@code Structure} type, decoding into a {@link List}.
- *
- * <p>Prefer {@link #ofStructure(Class, Decoder[])} if possible, which is both more type-safe and
- * more convenient.
- *
- * @param componentDecoders a {@link Decoder} for each component of the structure.
- * @return a new {@link Decoder}.
- */
- public static Decoder<Object[]> ofStructure(Decoder<?>... componentDecoders) {
- return new TupleDecoder(componentDecoders);
- }
-
- /**
- * Creates a {@link Decoder} for the {@link Variant} type.
- *
- * <p>The contained {@link Object} can be of one of the following types:
- *
- * <ul>
- * <li>{@link Boolean}
- * <li>{@link Byte}
- * <li>{@link Short}
- * <li>{@link Integer}
- * <li>{@link Long}
- * <li>{@link String}
- * <li>{@link Optional} (a GVariant {@code Maybe} type)
- * <li>{@link List} (a GVariant array)
- * <li>{@code Object[]} (a GVariant structure)
- * <li>{@link Variant} (a nested variant)
- * </ul>
- *
- * @return a new {@link Decoder}.
- */
- public static Decoder<Variant> ofVariant() {
- return new VariantDecoder();
- }
-
- /**
- * Creates a {@link Decoder} for the {@code boolean} type.
- *
- * @return a new {@link Decoder}.
- */
- public static Decoder<Boolean> ofBoolean() {
- return new BooleanDecoder();
- }
-
- /**
- * Creates a {@link Decoder} for the 8-bit {@code byte} type.
- *
- * <p><strong>Note:</strong> It is often useful to apply {@link #withByteOrder(ByteOrder)} to the
- * result of this method.
- *
- * @return a new {@link Decoder}.
- */
- public static Decoder<Byte> ofByte() {
- return new ByteDecoder();
- }
-
- /**
- * Creates a {@link Decoder} for the 16-bit {@code short} type.
- *
- * <p><strong>Note:</strong> It is often useful to apply {@link #withByteOrder(ByteOrder)} to the
- * result of this method.
- *
- * @return a new {@link Decoder}.
- */
- public static Decoder<Short> ofShort() {
- return new ShortDecoder();
- }
-
- /**
- * Creates a {@link Decoder} for the 32-bit {@code int} type.
- *
- * <p><strong>Note:</strong> It is often useful to apply {@link #withByteOrder(ByteOrder)} to the
- * result of this method.
- *
- * @return a new {@link Decoder}.
- */
- public static Decoder<Integer> ofInt() {
- return new IntegerDecoder();
- }
-
- /**
- * Creates a {@link Decoder} for the 64-bit {@code long} type.
- *
- * <p><strong>Note:</strong> It is often useful to apply {@link #withByteOrder(ByteOrder)} to the
- * result of this method.
- *
- * @return a new {@link Decoder}.
- */
- public static Decoder<Long> ofLong() {
- return new LongDecoder();
- }
-
- /**
- * Creates a {@link Decoder} for the {@code double} type.
- *
- * @return a new {@link Decoder}.
- */
- public static Decoder<Double> ofDouble() {
- return new DoubleDecoder();
- }
-
- /**
- * Creates a {@link Decoder} for the {@link String} type.
- *
- * <p><strong>Note:</strong> While GVariant does not prescribe any particular encoding, {@link
- * java.nio.charset.StandardCharsets#UTF_8} is the most common choice.
- *
- * @param charset the {@link Charset} the string is encoded in.
- * @return a new {@link Decoder}.
- */
- public static Decoder<String> ofString(Charset charset) {
- return new StringDecoder(charset);
- }
-
- 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;
- }
-
- private static class ArrayDecoder<U> extends Decoder<List<U>> {
-
- private final Decoder<U> elementDecoder;
-
- ArrayDecoder(Decoder<U> elementDecoder) {
- this.elementDecoder = elementDecoder;
- }
-
- @Override
- public byte alignment() {
- return elementDecoder.alignment();
- }
-
- @Override
- @Nullable
- Integer fixedSize() {
- return null;
- }
-
- @Override
- public List<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 elements;
- }
- }
-
- private static class MaybeDecoder<U> extends Decoder<Optional<U>> {
-
- private final Decoder<U> elementDecoder;
-
- MaybeDecoder(Decoder<U> elementDecoder) {
- this.elementDecoder = elementDecoder;
- }
-
- @Override
- public byte alignment() {
- return elementDecoder.alignment();
- }
-
- @Override
- @Nullable
- Integer fixedSize() {
- return null;
- }
-
- @Override
- public Optional<U> decode(ByteBuffer byteSlice) {
- if (!byteSlice.hasRemaining()) {
- return Optional.empty();
- } else {
- if (!elementDecoder.hasFixedSize()) {
- // Remove trailing zero byte.
- byteSlice.limit(byteSlice.limit() - 1);
- }
-
- return Optional.of(elementDecoder.decode(byteSlice));
- }
- }
- }
-
- private static class StructureDecoder<U extends Record> extends Decoder<U> {
-
- private final Class<U> recordType;
- private final TupleDecoder tupleDecoder;
-
- StructureDecoder(Class<U> recordType, Decoder<?>... 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));
- }
-
- this.recordType = recordType;
- this.tupleDecoder = new TupleDecoder(componentDecoders);
- }
-
- @Override
- public byte alignment() {
- return tupleDecoder.alignment();
- }
-
- @Override
- public Integer fixedSize() {
- return tupleDecoder.fixedSize();
- }
-
- @Override
- public U decode(ByteBuffer byteSlice) {
- Object[] recordConstructorArguments = tupleDecoder.decode(byteSlice);
-
- try {
- var recordComponentTypes =
- Arrays.stream(recordType.getRecordComponents())
- .map(RecordComponent::getType)
- .toArray(Class<?>[]::new);
- var recordConstructor = recordType.getDeclaredConstructor(recordComponentTypes);
- return recordConstructor.newInstance(recordConstructorArguments);
- } catch (NoSuchMethodException
- | InstantiationException
- | IllegalAccessException
- | InvocationTargetException e) {
- throw new IllegalStateException(e);
- }
- }
- }
-
- private static class TupleDecoder extends Decoder<Object[]> {
-
- private final Decoder<?>[] componentDecoders;
-
- TupleDecoder(Decoder<?>... componentDecoders) {
- this.componentDecoders = componentDecoders;
- }
-
- @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 Object[] decode(ByteBuffer byteSlice) {
- int framingOffsetSize = byteCount(byteSlice.limit());
-
- var objects = new Object[componentDecoders.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) {
- objects[componentIndex] =
- componentDecoder.decode(byteSlice.slice(position, fixedComponentSize));
- position += fixedComponentSize;
- } else {
- if (componentIndex == componentDecoders.length - 1) {
- // The last component never has a framing offset.
- int endPosition = byteSlice.limit() - framingOffsetIndex * framingOffsetSize;
- objects[componentIndex] =
- componentDecoder.decode(byteSlice.slice(position, endPosition - position));
- position = endPosition;
- } else {
- int framingOffset =
- getIntN(
- byteSlice.slice(
- byteSlice.limit() - (1 + framingOffsetIndex) * framingOffsetSize,
- framingOffsetSize));
- objects[componentIndex] =
- componentDecoder.decode(byteSlice.slice(position, framingOffset - position));
- position = framingOffset;
- ++framingOffsetIndex;
- }
- }
-
- ++componentIndex;
- }
-
- return objects;
- }
- }
-
- private static class VariantDecoder extends Decoder<Variant> {
-
- @Override
- public byte alignment() {
- return 8;
- }
-
- @Override
- @Nullable
- Integer fixedSize() {
- return null;
- }
-
- @Override
- public Variant decode(ByteBuffer byteSlice) {
- for (int i = byteSlice.limit() - 1; i >= 0; --i) {
- if (byteSlice.get(i) != 0) {
- continue;
- }
-
- var dataBytes = byteSlice.slice(0, i);
- var signatureBytes = byteSlice.slice(i + 1, byteSlice.limit() - (i + 1));
-
- Signature signature;
- try {
- signature = Signature.parse(signatureBytes);
- } catch (ParseException e) {
- throw new IllegalArgumentException(e);
- }
-
- return new Variant(signature, signature.decoder().decode(dataBytes));
- }
-
- throw new IllegalArgumentException("variant signature not found");
- }
- }
-
- private static class BooleanDecoder extends Decoder<Boolean> {
-
- @Override
- public byte alignment() {
- return 1;
- }
-
- @Override
- public Integer fixedSize() {
- return 1;
- }
-
- @Override
- public Boolean decode(ByteBuffer byteSlice) {
- return byteSlice.get() != 0;
- }
- }
-
- private static class ByteDecoder extends Decoder<Byte> {
-
- @Override
- public byte alignment() {
- return 1;
- }
-
- @Override
- public Integer fixedSize() {
- return 1;
- }
-
- @Override
- public Byte decode(ByteBuffer byteSlice) {
- return byteSlice.get();
- }
- }
-
- private static class ShortDecoder extends Decoder<Short> {
-
- @Override
- public byte alignment() {
- return 2;
- }
-
- @Override
- public Integer fixedSize() {
- return 2;
- }
-
- @Override
- public Short decode(ByteBuffer byteSlice) {
- return byteSlice.getShort();
- }
- }
-
- private static class IntegerDecoder extends Decoder<Integer> {
-
- @Override
- public byte alignment() {
- return 4;
- }
-
- @Override
- public Integer fixedSize() {
- return 4;
- }
-
- @Override
- public Integer decode(ByteBuffer byteSlice) {
- return byteSlice.getInt();
- }
- }
-
- private static class LongDecoder extends Decoder<Long> {
-
- @Override
- public byte alignment() {
- return 8;
- }
-
- @Override
- public Integer fixedSize() {
- return 8;
- }
-
- @Override
- public Long decode(ByteBuffer byteSlice) {
- return byteSlice.getLong();
- }
- }
-
- private static class DoubleDecoder extends Decoder<Double> {
-
- @Override
- public byte alignment() {
- return 8;
- }
-
- @Override
- public Integer fixedSize() {
- return 8;
- }
-
- @Override
- public Double decode(ByteBuffer byteSlice) {
- return byteSlice.getDouble();
- }
- }
-
- private static class StringDecoder extends Decoder<String> {
-
- private final Charset charset;
-
- public StringDecoder(Charset charset) {
- this.charset = charset;
- }
-
- @Override
- public byte alignment() {
- return 1;
- }
-
- @Override
- @Nullable
- Integer fixedSize() {
- return null;
- }
-
- @Override
- public String decode(ByteBuffer byteSlice) {
- byteSlice.limit(byteSlice.limit() - 1);
- return charset.decode(byteSlice).toString();
- }
- }
-}
diff --git a/src/main/java/eu/mulk/jgvariant/core/Signature.java b/src/main/java/eu/mulk/jgvariant/core/Signature.java
deleted file mode 100644
index d9de5f1..0000000
--- a/src/main/java/eu/mulk/jgvariant/core/Signature.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package eu.mulk.jgvariant.core;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import org.apiguardian.api.API;
-import org.apiguardian.api.API.Status;
-
-/**
- * A GVariant signature string.
- *
- * <p>Describes a type in the GVariant type system. The type can be arbitrarily complex.
- *
- * <p><strong>Examples</strong>
- *
- * <dl>
- * <dt>{@code "i"}
- * <dd>a single 32-bit integer
- * <dt>{@code "ai"}
- * <dd>an array of 32-bit integers
- * <dt>{@code "(bbb(sai))"}
- * <dd>a record consisting of three booleans and a nested record, which consists of a string and
- * an array of 32-bit integers
- * </dl>
- */
-@API(status = Status.STABLE)
-public final class Signature {
-
- private final String signatureString;
- private final Decoder<?> decoder;
-
- Signature(ByteBuffer signatureBytes) throws ParseException {
- this.decoder = parseSignature(signatureBytes);
-
- signatureBytes.rewind();
- this.signatureString = StandardCharsets.US_ASCII.decode(signatureBytes).toString();
- }
-
- static Signature parse(ByteBuffer signatureBytes) throws ParseException {
- return new Signature(signatureBytes);
- }
-
- static Signature parse(String signatureString) throws ParseException {
- var signatureBytes = ByteBuffer.wrap(signatureString.getBytes(StandardCharsets.US_ASCII));
- return parse(signatureBytes);
- }
-
- /**
- * Returns a {@link Decoder} that can decode values conforming to this signature.
- *
- * @return a {@link Decoder} for this signature
- */
- @SuppressWarnings("unchecked")
- Decoder<Object> decoder() {
- return (Decoder<Object>) decoder;
- }
-
- /**
- * Returns the signature formatted as a GVariant signature string.
- *
- * @return a GVariant signature string.
- */
- @Override
- public String toString() {
- return signatureString;
- }
-
- @Override
- public boolean equals(Object o) {
- return (o instanceof Signature signature)
- && Objects.equals(signatureString, signature.signatureString);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(signatureString);
- }
-
- private static Decoder<?> parseSignature(ByteBuffer signature) throws ParseException {
- char c = (char) signature.get();
- return switch (c) {
- case 'b' -> Decoder.ofBoolean();
- case 'y' -> Decoder.ofByte();
- case 'n', 'q' -> Decoder.ofShort();
- case 'i', 'u' -> Decoder.ofInt();
- case 'x', 't' -> Decoder.ofLong();
- case 'd' -> Decoder.ofDouble();
- 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]));
- default -> throw new ParseException(
- String.format("encountered unknown signature byte '%c'", c), signature.position());
- };
- }
-
- private static List<Decoder<?>> parseTupleTypes(ByteBuffer signature) throws ParseException {
- List<Decoder<?>> decoders = new ArrayList<>();
-
- while (true) {
- char c = (char) signature.get(signature.position());
- if (c == ')' || c == '}') {
- signature.get();
- break;
- }
-
- decoders.add(parseSignature(signature));
- }
-
- return decoders;
- }
-}
diff --git a/src/main/java/eu/mulk/jgvariant/core/Variant.java b/src/main/java/eu/mulk/jgvariant/core/Variant.java
deleted file mode 100644
index d1c1049..0000000
--- a/src/main/java/eu/mulk/jgvariant/core/Variant.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package eu.mulk.jgvariant.core;
-
-import org.apiguardian.api.API;
-import org.apiguardian.api.API.Status;
-
-/**
- * A dynamically typed GVariant value carrying a {@link Signature} describing its type.
- *
- * <p>{@link #value()} can be of one of the following types:
- *
- * <ul>
- * <li>{@link Boolean}
- * <li>{@link Byte}
- * <li>{@link Short}
- * <li>{@link Integer}
- * <li>{@link Long}
- * <li>{@link String}
- * <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 Variant} (a nested variant)
- * </ul>
- *
- * @param signature the signature describing the type of the value.
- * @param value the value itself; one of {@link Boolean}, {@link Byte}, {@link Short}, {@link
- * Integer}, {@link Long}, {@link String}, {@link java.util.Optional}, {@link java.util.List},
- * {@code Object[]}, {@link Variant}.
- */
-@API(status = Status.EXPERIMENTAL)
-public record Variant(Signature signature, Object value) {}
diff --git a/src/main/java/eu/mulk/jgvariant/core/package-info.java b/src/main/java/eu/mulk/jgvariant/core/package-info.java
deleted file mode 100644
index 1754096..0000000
--- a/src/main/java/eu/mulk/jgvariant/core/package-info.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Provides {@link eu.mulk.jgvariant.core.Decoder}, the foundational class for <a
- * href="https://docs.gtk.org/glib/struct.Variant.html">GVariant</a> parsing.
- *
- * <p>Instances of {@link eu.mulk.jgvariant.core.Decoder} read a given value type from a {@link
- * java.nio.ByteBuffer}. The class also contains factory methods to create those instances.
- *
- * <p><strong>Example</strong>
- *
- * <p>To parse a GVariant of type {@code "a(si)"}, which is an array of pairs of {@link
- * java.lang.String} and {@code int}, you can use the following code:
- *
- * <pre>{@code
- * record ExampleRecord(String s, int i) {}
- *
- * var decoder =
- * Decoder.ofArray(
- * Decoder.ofStructure(
- * ExampleRecord.class,
- * Decoder.ofString(UTF_8),
- * Decoder.ofInt().withByteOrder(LITTLE_ENDIAN)));
- *
- * byte[] bytes = ...;
- * List<ExampleRecord> example = decoder.decode(ByteBuffer.wrap(bytes));
- * }</pre>
- */
-package eu.mulk.jgvariant.core;
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
deleted file mode 100644
index 0282ff8..0000000
--- a/src/main/java/module-info.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Provides a parser for the <a href="https://docs.gtk.org/glib/struct.Variant.html">GVariant</a>
- * serialization format.
- *
- * <ul>
- * <li><a href="#sect-overview">Overview</a>
- * <li><a href="#sect-installation">Installation</a>
- * </ul>
- *
- * <h2 id="sect-overview">Overview</h2>
- *
- * <p>The {@link eu.mulk.jgvariant.core} package contains the {@link eu.mulk.jgvariant.core.Decoder}
- * type, which contains classes to parse and represent serialized <a
- * href="https://docs.gtk.org/glib/struct.Variant.html">GVariant</a> values.
- *
- * <h2 id="sect-installation">Installation</h2>
- *
- * <ul>
- * <li><a href="#sect-installation-maven">Usage with Maven</a>
- * <li><a href="#sect-installation-gradle">Usage with Gradle</a>
- * </ul>
- *
- * <h3 id="sect-installation-maven">Usage with Maven</h3>
- *
- * <pre>{@code
- * <project>
- * ...
- *
- * <dependencies>
- * ...
- *
- * <dependency>
- * <groupId>eu.mulk.jgvariant</groupId>
- * <artifactId>jgvariant-core</artifactId>
- * <version>0.1.3</version>
- * </dependency>
- *
- * ...
- * </dependencies>
- *
- * ...
- * </project>
- * }</pre>
- *
- * <h3 id="sect-installation-gradle">Usage with Gradle</h3>
- *
- * <pre>{@code
- * dependencies {
- * ...
- *
- * implementation("eu.mulk.jgvariant:jgvariant-core:0.1.3")
- *
- * ...
- * }
- * }</pre>
- */
-module eu.mulk.jgvariant.core {
- requires com.google.errorprone.annotations;
- requires org.jetbrains.annotations;
- requires org.apiguardian.api;
-
- exports eu.mulk.jgvariant.core;
-}