Skip to content

Commit 9cddf7f

Browse files
committed
Add digestLegth(encoded) method to multihash + test
1 parent a79caac commit 9cddf7f

2 files changed

Lines changed: 69 additions & 1 deletion

File tree

src/main/java/com/apicatalog/multihash/Multihash.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,68 @@ public byte[] decode(byte[] encoded, int index, int length) {
242242
length + index);
243243
}
244244

245+
/**
246+
* Returns the digest length (in bytes) declared by the given multihash-encoded
247+
* value, starting at offset {@code 0}.
248+
*
249+
* <p>
250+
* This is a convenience method equivalent to {@link #digestLength(byte[], int)
251+
* hashLength(encoded, 0)}.
252+
* </p>
253+
*
254+
* @param encoded the multihash-encoded byte array
255+
* @return the declared digest length, in bytes
256+
*
257+
* @throws NullPointerException if {@code encoded} is {@code null}
258+
* @throws IllegalArgumentException if the input is shorter than
259+
* {@code codeVarint.length + 2} bytes, or if
260+
* the bytes at offset {@code 0} do not start
261+
* with this multihash's code
262+
*/
263+
public long digestLength(byte[] encoded) {
264+
return digestLength(encoded, 0);
265+
}
266+
267+
/**
268+
* Returns the digest length (in bytes) declared by the given multihash-encoded
269+
* value.
270+
*
271+
* <p>
272+
* The method validates that the input begins at {@code index} with this
273+
* multihash's varint code, then decodes the varint length that immediately
274+
* follows the code.
275+
* </p>
276+
*
277+
* @param encoded the multihash-encoded byte array
278+
* @param index the starting offset within {@code encoded} at which the
279+
* multihash begins
280+
* @return the declared digest length, in bytes
281+
*
282+
* @throws NullPointerException if {@code encoded} is {@code null}
283+
* @throws IllegalArgumentException if the input is shorter than
284+
* {@code codeVarint.length + 2} bytes, or if
285+
* the bytes at {@code index} do not start
286+
* with this multihash's code
287+
* @throws IndexOutOfBoundsException if {@code index} is negative or exceeds the
288+
* available range
289+
*/
290+
public long digestLength(byte[] encoded, int index) {
291+
Objects.requireNonNull(encoded);
292+
293+
if (encoded.length < (codeVarint.length + 2)) {
294+
throw new IllegalArgumentException(
295+
"The value to decode must be a non-empty byte array with a minimum length of "
296+
+ (codeVarint.length + 2) + " bytes, but the actual length is " + encoded.length + " bytes.");
297+
}
298+
299+
if (!IntStream.range(0, codeVarint.length).allMatch(i -> codeVarint[i] == encoded[i + index])) {
300+
throw new IllegalArgumentException(
301+
"The provided value is not encoded with this multihash: " + toString() + ".");
302+
}
303+
304+
return UVarInt.decode(encoded, index + codeVarint.length);
305+
}
306+
245307
@Override
246308
public String toString() {
247309
return "Multihash [name=" + name + ", tag=" + tag + ", code=" + code + "]";

src/test/java/com/apicatalog/multihash/MultihashTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import org.junit.jupiter.params.provider.Arguments;
1212
import org.junit.jupiter.params.provider.MethodSource;
1313

14-
import com.apicatalog.multicodec.MulticodecDecoder;
1514
import com.apicatalog.multicodec.Multicodec.Tag;
15+
import com.apicatalog.multicodec.MulticodecDecoder;
1616
import com.apicatalog.multicodec.codec.MultihashCodec;
1717

1818
class MultihashTest {
@@ -94,6 +94,12 @@ void testDecoderGet(byte[] input, Multihash expected) {
9494
assertEquals(expected, DECODER.getCodec(input).orElseThrow(IllegalArgumentException::new));
9595
}
9696

97+
@ParameterizedTest(name = "{index}")
98+
@MethodSource("testData")
99+
void testDigestLength(byte[] input, Multihash codec, byte[] expected) {
100+
assertEquals(expected.length, codec.digestLength(input));
101+
}
102+
97103
static Stream<Arguments> testData() {
98104
return Stream.of(
99105
Arguments.of(Base64.getDecoder().decode("ERSIwvEfss45KstbKYbmQCEcRpAHPg=="),

0 commit comments

Comments
 (0)