From 4e8423db22a77af394bb519e2a828714ab48898d Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sun, 19 Dec 2021 22:56:09 +0100 Subject: Add jgvariant-ostree module. Change-Id: Idf7bacad28d7cf65eb1ddd0994dcc2c2c2a7e18e --- .../main/java/eu/mulk/jgvariant/core/Decoder.java | 68 +++++++++++++++++++++- .../java/eu/mulk/jgvariant/core/Signature.java | 2 +- jgvariant-core/src/main/java/module-info.java | 5 ++ .../java/eu/mulk/jgvariant/core/DecoderTest.java | 27 +++++++++ 4 files changed, 100 insertions(+), 2 deletions(-) (limited to 'jgvariant-core/src') 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 d2f2403..fc11eab 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 @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.function.Function; import org.apiguardian.api.API; import org.apiguardian.api.API.Status; import org.jetbrains.annotations.Nullable; @@ -80,7 +81,7 @@ public abstract class Decoder { * @param byteOrder the byte order to use. * @return a new, decorated {@link Decoder}. */ - public Decoder withByteOrder(ByteOrder byteOrder) { + public final Decoder withByteOrder(ByteOrder byteOrder) { var delegate = this; return new Decoder<>() { @@ -102,6 +103,34 @@ public abstract class Decoder { }; } + /** + * Creates a new {@link Decoder} from an existing one by applying a function to the result. + * + * @param function the function to apply. + * @return a new, decorated {@link Decoder}. + * @see java.util.stream.Stream#map + */ + public final Decoder map(Function function) { + var delegate = this; + + return new Decoder<>() { + @Override + public byte alignment() { + return delegate.alignment(); + } + + @Override + public @Nullable Integer fixedSize() { + return delegate.fixedSize(); + } + + @Override + public U decode(ByteBuffer byteSlice) { + return function.apply(delegate.decode(byteSlice)); + } + }; + } + /** * Creates a {@link Decoder} for an {@code Array} type. * @@ -113,6 +142,16 @@ public abstract class Decoder { return new ArrayDecoder<>(elementDecoder); } + /** + * Creates a {@link Decoder} for an {@code Array} type of element type {@code byte} into a + * primitive {@code byte[]} array. + * + * @return a new {@link Decoder}. + */ + public static Decoder ofByteArray() { + return new ByteArrayDecoder(); + } + /** * Creates a {@link Decoder} for a {@code Maybe} type. * @@ -299,6 +338,9 @@ public abstract class Decoder { var element = elementDecoder.decode(byteSlice.slice(i, elementSize)); elements.add(element); } + } else if (byteSlice.limit() == 0) { + // A degenerate zero-length array of variable width. + elements = List.of(); } else { // An array with aligned elements and a vector of framing offsets in the end. int framingOffsetSize = byteCount(byteSlice.limit()); @@ -321,6 +363,30 @@ public abstract class Decoder { } } + private static class ByteArrayDecoder extends Decoder { + + private static final int ELEMENT_SIZE = 1; + + @Override + public byte alignment() { + return ELEMENT_SIZE; + } + + @Override + @Nullable + Integer fixedSize() { + return null; + } + + @Override + public byte[] decode(ByteBuffer byteSlice) { + // A simple C-style array. + byte[] elements = new byte[byteSlice.limit() / ELEMENT_SIZE]; + byteSlice.get(elements); + return elements; + } + } + private static class MaybeDecoder extends Decoder> { private final Decoder elementDecoder; 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 d9de5f1..78e4bdd 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 @@ -43,7 +43,7 @@ public final class Signature { return new Signature(signatureBytes); } - static Signature parse(String signatureString) throws ParseException { + public static Signature parse(String signatureString) throws ParseException { var signatureBytes = ByteBuffer.wrap(signatureString.getBytes(StandardCharsets.US_ASCII)); return parse(signatureBytes); } diff --git a/jgvariant-core/src/main/java/module-info.java b/jgvariant-core/src/main/java/module-info.java index a1830f6..0ef35cc 100644 --- a/jgvariant-core/src/main/java/module-info.java +++ b/jgvariant-core/src/main/java/module-info.java @@ -49,6 +49,10 @@ * eu.mulk.jgvariant * jgvariant-core * + * + * eu.mulk.jgvariant + * jgvariant-ostree + * * * ... * @@ -65,6 +69,7 @@ * * implementation(platform("eu.mulk.jgvariant:jgvariant-bom:0.1.4") * implementation("eu.mulk.jgvariant:jgvariant-core") + * implementation("eu.mulk.jgvariant:jgvariant-ostree") * * ... * } diff --git a/jgvariant-core/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java b/jgvariant-core/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java index 5cf1a1c..d72a1b6 100644 --- a/jgvariant-core/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java +++ b/jgvariant-core/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java @@ -241,6 +241,26 @@ class DecoderTest { decoder.decode(ByteBuffer.wrap(data))); } + @Test + void testPrimitiveByteArray() { + var data = new byte[] {0x04, 0x05, 0x06, 0x07}; + + var decoder = Decoder.ofByteArray(); + + assertArrayEquals(data, decoder.decode(ByteBuffer.wrap(data))); + } + + @Test + void testPrimitiveByteArrayRecord() { + var data = new byte[] {0x04, 0x05, 0x06, 0x07}; + + record TestRecord(byte[] bytes) {} + + var decoder = Decoder.ofStructure(TestRecord.class, Decoder.ofByteArray()); + + assertArrayEquals(data, decoder.decode(ByteBuffer.wrap(data)).bytes()); + } + @Test void testIntegerArray() { var data = new byte[] {0x04, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00}; @@ -434,4 +454,11 @@ class DecoderTest { var signature = Signature.parse(ByteBuffer.wrap(data)); assertEquals("(bynqiuxtdsogvmiai)", signature.toString()); } + + @Test + void testMap() { + var data = new byte[] {0x0A, 0x0B, 0x0C}; + var decoder = Decoder.ofByteArray().map(bytes -> bytes.length); + assertEquals(3, decoder.decode(ByteBuffer.wrap(data))); + } } -- cgit v1.2.3