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 --- .../java/eu/mulk/jgvariant/ostree/ByteString.java | 41 +++++++++++++++++ .../java/eu/mulk/jgvariant/ostree/Checksum.java | 24 ++++++++++ .../main/java/eu/mulk/jgvariant/ostree/Commit.java | 51 ++++++++++++++++++++++ .../eu/mulk/jgvariant/ostree/DeltaFallback.java | 25 +++++++++++ .../eu/mulk/jgvariant/ostree/DeltaMetaEntry.java | 38 ++++++++++++++++ .../eu/mulk/jgvariant/ostree/DeltaPartPayload.java | 41 +++++++++++++++++ .../eu/mulk/jgvariant/ostree/DeltaSuperblock.java | 43 ++++++++++++++++++ .../java/eu/mulk/jgvariant/ostree/DirMeta.java | 25 +++++++++++ .../java/eu/mulk/jgvariant/ostree/DirTree.java | 49 +++++++++++++++++++++ .../java/eu/mulk/jgvariant/ostree/FileMeta.java | 25 +++++++++++ .../java/eu/mulk/jgvariant/ostree/Metadata.java | 33 ++++++++++++++ .../java/eu/mulk/jgvariant/ostree/SignedDelta.java | 38 ++++++++++++++++ .../java/eu/mulk/jgvariant/ostree/Summary.java | 47 ++++++++++++++++++++ .../eu/mulk/jgvariant/ostree/SummarySignature.java | 35 +++++++++++++++ .../main/java/eu/mulk/jgvariant/ostree/Xattr.java | 18 ++++++++ .../eu/mulk/jgvariant/ostree/package-info.java | 10 +++++ 16 files changed, 543 insertions(+) create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/ByteString.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Checksum.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Commit.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaFallback.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaMetaEntry.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaPartPayload.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaSuperblock.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DirMeta.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DirTree.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/FileMeta.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Metadata.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/SignedDelta.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Summary.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/SummarySignature.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Xattr.java create mode 100644 jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/package-info.java (limited to 'jgvariant-ostree/src/main/java/eu') diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/ByteString.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/ByteString.java new file mode 100644 index 0000000..1a85547 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/ByteString.java @@ -0,0 +1,41 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.util.Arrays; +import java.util.HexFormat; + +/** + * A wrapper for a {@code byte[]} that implements {@link #equals(Object)}, {@link #hashCode()}, and + * {@link #toString()} according to value semantics. + */ +public record ByteString(byte[] bytes) { + + private static final Decoder DECODER = Decoder.ofByteArray().map(ByteString::new); + + public static Decoder decoder() { + return DECODER; + } + + @Override + public boolean equals(Object o) { + return (o instanceof ByteString byteString) && Arrays.equals(bytes, byteString.bytes); + } + + @Override + public int hashCode() { + return Arrays.hashCode(bytes); + } + + @Override + public String toString() { + return "ByteString{hex=\"%s\"}".formatted(hex()); + } + + public String hex() { + return HexFormat.of().formatHex(bytes); + } + + public static ByteString ofHex(String hex) { + return new ByteString(HexFormat.of().parseHex(hex)); + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Checksum.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Checksum.java new file mode 100644 index 0000000..f77eb57 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Checksum.java @@ -0,0 +1,24 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; + +/** + * A wrapper for {@link ByteString} that refers to a content-addressed object in an OSTree + * repository. + */ +public record Checksum(ByteString bytes) { + + private static final Decoder DECODER = ByteString.decoder().map(Checksum::new); + + public static Decoder decoder() { + return DECODER; + } + + public String hex() { + return bytes.hex(); + } + + public static Checksum ofHex(String hex) { + return new Checksum(ByteString.ofHex(hex)); + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Commit.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Commit.java new file mode 100644 index 0000000..43909ba --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Commit.java @@ -0,0 +1,51 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * A commit in an OSTree repository. + * + *

Has an optional parent, a root directory, and various metadata. + * + *

Reference: {@code ostree-core.h#OSTREE_COMMIT_GVARIANT_STRING} + */ +public record Commit( + Metadata metadata, + Checksum parentChecksum, + List relatedObjects, + String subject, + String body, + long timestamp, + Checksum rootDirTreeChecksum, + Checksum rootDirMetaChecksum) { + + public record RelatedObject(String ref, Checksum commitChecksum) { + + private static final Decoder DECODER = + Decoder.ofStructure( + RelatedObject.class, Decoder.ofString(StandardCharsets.UTF_8), Checksum.decoder()); + + public static Decoder decoder() { + return DECODER; + } + } + + private static final Decoder DECODER = + Decoder.ofStructure( + Commit.class, + Metadata.decoder(), + Checksum.decoder(), + Decoder.ofArray(RelatedObject.decoder()), + Decoder.ofString(StandardCharsets.UTF_8), + Decoder.ofString(StandardCharsets.UTF_8), + Decoder.ofLong().withByteOrder(ByteOrder.BIG_ENDIAN), + Checksum.decoder(), + Checksum.decoder()); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaFallback.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaFallback.java new file mode 100644 index 0000000..1b3cc0a --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaFallback.java @@ -0,0 +1,25 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.nio.ByteOrder; + +/** + * A fallback entry in a {@link DeltaSuperblock}. + * + *

Reference: {@code ostree-repo-static-delta-private.h#OSTREE_STATIC_DELTA_FALLBACK_FORMAT} + */ +public record DeltaFallback( + byte objectType, Checksum checksum, long compressedSize, long uncompressedSize) { + + private static final Decoder DECODER = + Decoder.ofStructure( + DeltaFallback.class, + Decoder.ofByte(), + Checksum.decoder(), + Decoder.ofLong().withByteOrder(ByteOrder.LITTLE_ENDIAN), // FIXME: non-canonical + Decoder.ofLong().withByteOrder(ByteOrder.LITTLE_ENDIAN)); // FIXME: non-canonical + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaMetaEntry.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaMetaEntry.java new file mode 100644 index 0000000..39ada86 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaMetaEntry.java @@ -0,0 +1,38 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.nio.ByteOrder; +import java.util.List; + +/** + * An entry in a {@link DeltaSuperblock}. + * + *

Reference: {@code ostree-repo-static-delta-private.h#OSTREE_STATIC_DELTA_META_ENTRY_FORMAT} + */ +public record DeltaMetaEntry( + int version, Checksum checksum, long size, long usize, List objects) { + + record DeltaObject(byte objectType, Checksum checksum) { + + private static final Decoder DECODER = + Decoder.ofStructure(DeltaObject.class, Decoder.ofByte(), Checksum.decoder()); + + public static Decoder decoder() { + return DECODER; + } + } + + private static final Decoder DECODER = + Decoder.ofStructure( + DeltaMetaEntry.class, + Decoder.ofInt().withByteOrder(ByteOrder.LITTLE_ENDIAN), // FIXME: non-canonical + Checksum.decoder(), + Decoder.ofLong().withByteOrder(ByteOrder.LITTLE_ENDIAN), // FIXME: non-canonical + Decoder.ofLong().withByteOrder(ByteOrder.LITTLE_ENDIAN), // FIXME: non-canonical + Decoder.ofByteArray().map(x -> List.of()) // FIXME + ); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaPartPayload.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaPartPayload.java new file mode 100644 index 0000000..c8c5fe7 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaPartPayload.java @@ -0,0 +1,41 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.nio.ByteOrder; +import java.util.List; + +/** + * Reference: {@code ostree-repo-static-delta-private.h#OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0} + */ +public record DeltaPartPayload( + List fileModes, + List> xattrs, + ByteString rawDataSource, + ByteString operations) { + + private static final Decoder DECODER = + Decoder.ofStructure( + DeltaPartPayload.class, + Decoder.ofArray(FileMode.decoder()), + Decoder.ofArray(Decoder.ofArray(Xattr.decoder())), + ByteString.decoder(), + ByteString.decoder()); + + public record FileMode(int uid, int gid, int mode) { + + private static final Decoder DECODER = + Decoder.ofStructure( + FileMode.class, + Decoder.ofInt().withByteOrder(ByteOrder.LITTLE_ENDIAN), + Decoder.ofInt().withByteOrder(ByteOrder.LITTLE_ENDIAN), + Decoder.ofInt().withByteOrder(ByteOrder.LITTLE_ENDIAN)); + + public static Decoder decoder() { + return DECODER; + } + } + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaSuperblock.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaSuperblock.java new file mode 100644 index 0000000..2b09645 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaSuperblock.java @@ -0,0 +1,43 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.nio.ByteOrder; +import java.util.List; + +/** Reference: {@code ostree-repo-static-delta-private.h#OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT} */ +public record DeltaSuperblock( + Metadata metadata, + long timestamp, + Checksum fromChecksum, + Checksum toChecksum, + Commit commit, + List dependencies, + List entries, + List fallbacks) { + + public record DeltaName(Checksum fromChecksum, Checksum toChecksum) { + + private static final Decoder DECODER = + Decoder.ofStructure(DeltaName.class, Checksum.decoder(), Checksum.decoder()); + + public static Decoder decoder() { + return DECODER; + } + } + + private static final Decoder DECODER = + Decoder.ofStructure( + DeltaSuperblock.class, + Metadata.decoder(), + Decoder.ofLong().withByteOrder(ByteOrder.BIG_ENDIAN), + Checksum.decoder(), + Checksum.decoder(), + Commit.decoder(), + Decoder.ofByteArray().map(x -> List.of()), // FIXME + Decoder.ofArray(DeltaMetaEntry.decoder()), + Decoder.ofArray(DeltaFallback.decoder())); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DirMeta.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DirMeta.java new file mode 100644 index 0000000..3a9672d --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DirMeta.java @@ -0,0 +1,25 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.nio.ByteOrder; +import java.util.List; + +/** + * Permission bits and extended attributes for a directory. + * + *

Reference: {@code ostree-core.h#OSTREE_DIRMETA_GVARIANT_STRING} + */ +public record DirMeta(int uid, int gid, int mode, List xattrs) { + + private static final Decoder DECODER = + Decoder.ofStructure( + DirMeta.class, + Decoder.ofInt().withByteOrder(ByteOrder.BIG_ENDIAN), + Decoder.ofInt().withByteOrder(ByteOrder.BIG_ENDIAN), + Decoder.ofInt().withByteOrder(ByteOrder.BIG_ENDIAN), + Decoder.ofArray(Xattr.decoder())); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DirTree.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DirTree.java new file mode 100644 index 0000000..3a14abb --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DirTree.java @@ -0,0 +1,49 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * Metadata describing files and directories of a file tree. + * + *

Referenced by {@link Commit#rootDirTreeChecksum()} and recursively by {@link + * Directory#treeChecksum()}. + * + *

Reference: {@code ostree-core.h#OSTREE_TREE_GVARIANT_STRING} + */ +public record DirTree(List files, List directories) { + + public record File(String name, Checksum checksum) { + + private static final Decoder DECODER = + Decoder.ofStructure( + File.class, Decoder.ofString(StandardCharsets.UTF_8), Checksum.decoder()); + + public static Decoder decoder() { + return DECODER; + } + } + + public record Directory(String name, Checksum treeChecksum, Checksum dirChecksum) { + + private static final Decoder DECODER = + Decoder.ofStructure( + Directory.class, + Decoder.ofString(StandardCharsets.UTF_8), + Checksum.decoder(), + Checksum.decoder()); + + public static Decoder decoder() { + return DECODER; + } + } + + private static final Decoder DECODER = + Decoder.ofStructure( + DirTree.class, Decoder.ofArray(File.decoder()), Decoder.ofArray(Directory.decoder())); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/FileMeta.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/FileMeta.java new file mode 100644 index 0000000..19e0677 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/FileMeta.java @@ -0,0 +1,25 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.nio.ByteOrder; +import java.util.List; + +/** + * Permission bits and extended attributes for a file. + * + *

Reference: {@code ostree-core.h#OSTREE_FILEMETA_GVARIANT_STRING} + */ +public record FileMeta(int uid, int gid, int mode, List xattrs) { + + private static final Decoder DECODER = + Decoder.ofStructure( + FileMeta.class, + Decoder.ofInt().withByteOrder(ByteOrder.BIG_ENDIAN), + Decoder.ofInt().withByteOrder(ByteOrder.BIG_ENDIAN), + Decoder.ofInt().withByteOrder(ByteOrder.BIG_ENDIAN), + Decoder.ofArray(Xattr.decoder())); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Metadata.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Metadata.java new file mode 100644 index 0000000..cf838d3 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Metadata.java @@ -0,0 +1,33 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import eu.mulk.jgvariant.core.Variant; +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * A wrapper for a list of metadata fields. + * + *

Reference: (embedded in other data types) + */ +public record Metadata(List fields) { + + /** A metadata field with a key and a value. */ + public record Field(String key, Variant value) { + + private static final Decoder DECODER = + Decoder.ofStructure( + Field.class, Decoder.ofString(StandardCharsets.UTF_8), Decoder.ofVariant()); + + public static Decoder decoder() { + return DECODER; + } + } + + private static final Decoder DECODER = + Decoder.ofArray(Field.decoder()).map(Metadata::new); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/SignedDelta.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/SignedDelta.java new file mode 100644 index 0000000..2fc5c25 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/SignedDelta.java @@ -0,0 +1,38 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import eu.mulk.jgvariant.core.Variant; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * A {@link DeltaSuperblock} signed with some sort of key. + * + *

Reference: {@code ostree-repo-static-delta-private.h#OSTREE_STATIC_DELTA_SIGNED_FORMAT} + */ +public record SignedDelta( + long magicNumber, ByteString superblock, List signatures) { + + /** A cryptographic signature. */ + public record Signature(String key, Variant data) { + private static final Decoder DECODER = + Decoder.ofStructure( + Signature.class, Decoder.ofString(StandardCharsets.US_ASCII), Decoder.ofVariant()); + + public static Decoder decoder() { + return DECODER; + } + } + + private static final Decoder DECODER = + Decoder.ofStructure( + SignedDelta.class, + Decoder.ofLong().withByteOrder(ByteOrder.BIG_ENDIAN), + ByteString.decoder(), + Decoder.ofArray(Signature.decoder())); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Summary.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Summary.java new file mode 100644 index 0000000..8f4ddf6 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Summary.java @@ -0,0 +1,47 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * The summary file of an OSTree repository. + * + *

Stored as a file named {@code summary} in the OSTree repository root. + * + *

Reference: {@code ostree-core.h#OSTREE_SUMMARY_GVARIANT_STRING} + */ +public record Summary(List entries, Metadata metadata) { + + public record Entry(String ref, Value value) { + + public record Value(long size, Checksum checksum, Metadata metadata) { + + private static final Decoder DECODER = + Decoder.ofStructure( + Value.class, + Decoder.ofLong().withByteOrder(ByteOrder.LITTLE_ENDIAN), + Checksum.decoder(), + Metadata.decoder()); + + public static Decoder decoder() { + return DECODER; + } + } + + private static final Decoder DECODER = + Decoder.ofStructure(Entry.class, Decoder.ofString(StandardCharsets.UTF_8), Value.decoder()); + + public static Decoder decoder() { + return DECODER; + } + } + + private static final Decoder

DECODER = + Decoder.ofStructure(Summary.class, Decoder.ofArray(Entry.decoder()), Metadata.decoder()); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/SummarySignature.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/SummarySignature.java new file mode 100644 index 0000000..a05b96d --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/SummarySignature.java @@ -0,0 +1,35 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; +import eu.mulk.jgvariant.core.Variant; +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * A collection of cryptographic signatures for a {@link Summary}. + * + *

Stored as a file named {@code summary.sig} in the OSTree repository root. + * + *

Reference: {@code ostree-repo-static-delta-private.h#OSTREE_SUMMARY_SIG_GVARIANT_STRING} + */ +public record SummarySignature(List signatures) { + + /** A cryptographic signature. */ + public record Signature(String key, Variant data) { + + private static final Decoder DECODER = + Decoder.ofStructure( + Signature.class, Decoder.ofString(StandardCharsets.UTF_8), Decoder.ofVariant()); + + public static Decoder decoder() { + return DECODER; + } + } + + private static final Decoder DECODER = + Decoder.ofArray(Signature.decoder()).map(SummarySignature::new); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Xattr.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Xattr.java new file mode 100644 index 0000000..68628c4 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/Xattr.java @@ -0,0 +1,18 @@ +package eu.mulk.jgvariant.ostree; + +import eu.mulk.jgvariant.core.Decoder; + +/** + * Reference: (embedded in other data types, e.g. {@code + * ostree-core.h#OSTREE_DIRMETA_GVARIANT_STRING}, {@code + * ostree-core.h#OSTREE_FILEMETA_GVARIANT_STRING}) + */ +public record Xattr(ByteString name, ByteString value) { + + private static final Decoder DECODER = + Decoder.ofStructure(Xattr.class, ByteString.decoder(), ByteString.decoder()); + + public static Decoder decoder() { + return DECODER; + } +} diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/package-info.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/package-info.java new file mode 100644 index 0000000..c6a61f1 --- /dev/null +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/package-info.java @@ -0,0 +1,10 @@ +/** + * Provides record classes describing the elements of OSTree repositories and factory methods to create + * {@link eu.mulk.jgvariant.core.Decoder} instances for them. + */ +@API(status = Status.EXPERIMENTAL) +package eu.mulk.jgvariant.ostree; + +import org.apiguardian.api.API; +import org.apiguardian.api.API.Status; -- cgit v1.2.3