blob: 261e2be27567b92d2d5e755151bc76ee44499eb9 [file] [log] [blame]
Matthias Andreas Benkardb5d657a2022-02-03 21:14:30 +01001// SPDX-FileCopyrightText: © 2021 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
2//
3// SPDX-License-Identifier: LGPL-3.0-or-later
4
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +01005package eu.mulk.jgvariant.ostree;
6
7import eu.mulk.jgvariant.core.Decoder;
Matthias Andreas Benkard05114642021-12-29 21:51:29 +01008import java.nio.ByteBuffer;
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +01009
10/**
11 * A wrapper for {@link ByteString} that refers to a content-addressed object in an OSTree
12 * repository.
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010013 *
14 * @param byteString the bytes that make up this {@link Checksum}.
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010015 */
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010016public record Checksum(ByteString byteString) {
17
18 private static final int SIZE = 32;
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010019
20 private static final Decoder<Checksum> DECODER = ByteString.decoder().map(Checksum::new);
21
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010022 public Checksum {
Matthias Andreas Benkardf96d0e32021-12-29 21:53:50 +010023 if (byteString.size() == 0) {
24 byteString = zero().byteString;
25 }
26
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010027 if (byteString.size() != SIZE) {
28 throw new IllegalArgumentException(
29 "attempted to construct Checksum of length %d (expected: %d)"
30 .formatted(byteString.size(), SIZE));
31 }
32 }
33
34 /**
35 * A decoder for a {@code byte[]} that wraps the result in a {@link Checksum}.
36 *
37 * @return a possibly shared {@link Decoder}.
38 */
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010039 public static Decoder<Checksum> decoder() {
40 return DECODER;
41 }
42
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010043 /**
44 * Returns an empty checksum.
45 *
46 * @return a checksum whose bits are all zero.
47 */
48 public static Checksum zero() {
49 return new Checksum(new ByteString(new byte[SIZE]));
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010050 }
51
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010052 /**
53 * Checks whether the checksum contains only zero bits.
54 *
55 * @return {@code true} if the byte string is equal to {@link #zero()}, {@code false} otherwise.
56 */
57 public boolean isEmpty() {
58 return equals(zero());
59 }
60
61 /**
62 * Converts the contained byte array into a hex string.
63 *
64 * <p>Useful for printing.
65 *
66 * @return a hex string representation of the bytes making up this checksum.
67 */
68 public String hex() {
69 return byteString.hex();
70 }
71
72 /**
73 * Parses a hex string into a {@link Checksum}.
74 *
75 * @param hex a hex string.
76 * @return a {@link Checksum} corresponding to the given hex string.
77 */
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +010078 public static Checksum ofHex(String hex) {
79 return new Checksum(ByteString.ofHex(hex));
80 }
Matthias Andreas Benkard05114642021-12-29 21:51:29 +010081
82 /**
Matthias Andreas Benkardc7aa2b62022-01-23 18:10:03 +010083 * Converts the contained byte array into modified Base64 (with {@code "/"} replaced with {@code
84 * "-"}).
85 *
86 * <p>Modified Base64 is Base64 with {@code "/"} replaced with {@code "_"}. It is used to address
87 * static deltas in an OSTree repository.
88 *
89 * <p>Useful for printing.
90 *
91 * @return a modified Base64 representation of the bytes making up this checksum.
92 */
93 public String modifiedBase64() {
94 return byteString.modifiedBase64();
95 }
96
97 /**
98 * Parses a modified Base64 string into a {@link Checksum}.
99 *
100 * <p>Modified Base64 is Base64 with {@code "/"} replaced with {@code "_"}. It is used to address
101 * static deltas in an OSTree repository.
102 *
103 * @param mbase64 a hex string.
104 * @return a {@link Checksum} corresponding to the given modified Base64 string.
105 */
106 public static Checksum ofModifiedBase64(String mbase64) {
107 return new Checksum(ByteString.ofModifiedBase64(mbase64));
108 }
109
110 /**
Matthias Andreas Benkard05114642021-12-29 21:51:29 +0100111 * Reads a Checksum for a {@link ByteBuffer}.
112 *
113 * @param byteBuffer the byte buffer to read from.
114 * @return a checksum.
115 */
116 public static Checksum readFrom(ByteBuffer byteBuffer) {
117 var bytes = new byte[SIZE];
118 byteBuffer.get(bytes);
119 return new Checksum(new ByteString(bytes));
120 }
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +0100121}