blob: edcf2bf8b78e108167950fcc93b744e0ad3bd773 [file] [log] [blame]
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +01001package eu.mulk.jgvariant.ostree;
2
3import eu.mulk.jgvariant.core.Decoder;
Matthias Andreas Benkard05114642021-12-29 21:51:29 +01004import java.nio.ByteBuffer;
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +01005import java.nio.ByteOrder;
Matthias Andreas Benkard05114642021-12-29 21:51:29 +01006import java.util.ArrayList;
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +01007import java.util.List;
8
Matthias Andreas Benkard05114642021-12-29 21:51:29 +01009/**
10 * A static delta.
11 *
12 * <p>Reference: {@code ostree-repo-static-delta-private.h#OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT}
13 *
14 * @param metadata arbitrary user-supplied metadata.
15 * @param timestamp UNIX epoch seconds of when the commit was done.
16 * @param fromChecksum a (possibly {@link Checksum#isEmpty()}) reference to the starting commit.
17 * @param toChecksum a (non-{@link Checksum#isEmpty()}) reference to the end commit.
18 * @param commit the commit metadata of the end commit.
19 * @param dependencies a list of other {@link DeltaSuperblock}s that need to be applied before this
20 * one.
21 * @param entries a list of metadata on the {@link DeltaPartPayload}s that make up the delta.
22 * @param fallbacks a list of objects included in the delta as plain files that have to be fetched
23 * separately.
24 */
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010025public record DeltaSuperblock(
26 Metadata metadata,
27 long timestamp,
28 Checksum fromChecksum,
29 Checksum toChecksum,
30 Commit commit,
31 List<DeltaName> dependencies,
32 List<DeltaMetaEntry> entries,
33 List<DeltaFallback> fallbacks) {
34
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010035 /**
36 * A specifier for another static delta.
37 *
38 * <p>Used to specify {@link DeltaSuperblock#dependencies()}.
39 *
40 * @param fromChecksum the {@link DeltaSuperblock#fromChecksum()} of the referenced delta.
41 * @param toChecksum the {@link DeltaSuperblock#toChecksum()} of the referenced delta.
42 */
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010043 public record DeltaName(Checksum fromChecksum, Checksum toChecksum) {
44
45 private static final Decoder<DeltaName> DECODER =
46 Decoder.ofStructure(DeltaName.class, Checksum.decoder(), Checksum.decoder());
47
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010048 /**
49 * Acquires a {@link Decoder} for the enclosing type.
50 *
51 * @return a possibly shared {@link Decoder}.
52 */
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010053 public static Decoder<DeltaName> decoder() {
54 return DECODER;
55 }
56 }
57
58 private static final Decoder<DeltaSuperblock> DECODER =
59 Decoder.ofStructure(
60 DeltaSuperblock.class,
61 Metadata.decoder(),
62 Decoder.ofLong().withByteOrder(ByteOrder.BIG_ENDIAN),
63 Checksum.decoder(),
64 Checksum.decoder(),
65 Commit.decoder(),
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010066 Decoder.ofByteArray().map(DeltaSuperblock::parseDeltaNameList),
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010067 Decoder.ofArray(DeltaMetaEntry.decoder()),
68 Decoder.ofArray(DeltaFallback.decoder()));
69
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010070 private static List<DeltaName> parseDeltaNameList(byte[] bytes) {
71 var byteBuffer = ByteBuffer.wrap(bytes);
72 List<DeltaName> deltaNames = new ArrayList<>();
73
74 while (byteBuffer.hasRemaining()) {
75 var fromChecksum = Checksum.readFrom(byteBuffer);
76 var toChecksum = Checksum.readFrom(byteBuffer);
77 deltaNames.add(new DeltaName(fromChecksum, toChecksum));
78 }
79
80 return deltaNames;
81 }
82
83 /**
84 * Acquires a {@link Decoder} for the enclosing type.
85 *
86 * @return a possibly shared {@link Decoder}.
87 */
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010088 public static Decoder<DeltaSuperblock> decoder() {
89 return DECODER;
90 }
91}