Skip to content

Commit bead573

Browse files
committed
core: Opaque: Add support for mutable byte arrays
Similar to mutable ByteBuffers, provide support for mutable byte[] backing Opaque. Related: #149 Signed-off-by: Christian Kohlschütter <[email protected]>
1 parent 2f4923c commit bead573

File tree

2 files changed

+63
-5
lines changed

2 files changed

+63
-5
lines changed

core/src/main/java/org/dcache/nfs/util/Opaque.java

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ static Opaque forBytes(byte[] bytes) {
4343
return new OpaqueImpl(bytes.clone());
4444
}
4545

46+
/**
47+
* Returns an mutable {@link Opaque} instance based on the given byte array.
48+
* <p>
49+
* Note that the returned {@link Opaque} is typically not suitable for <em>storing</em> in a
50+
* {@link java.util.HashMap}, but merely for lookups. Call {@link #toImmutableOpaque()} when necessary.
51+
*
52+
* @param bytes The bytes.
53+
* @return The {@link Opaque} instance.
54+
*/
55+
static Opaque forMutableByteArray(byte[] bytes) {
56+
return new OpaqueMutableImpl(bytes);
57+
}
58+
4659
/**
4760
* Returns an immutable {@link Opaque} instance based on a copy of the {@code length} bytes from the given
4861
* {@link ByteBuffer}.
@@ -161,12 +174,12 @@ default void putBytes(ByteBuffer buf) {
161174
@Override
162175
boolean equals(Object o);
163176

164-
final class OpaqueImpl implements Opaque {
165-
private final byte[] _opaque;
177+
class OpaqueImpl implements Opaque {
178+
final byte[] _opaque;
166179
private String base64 = null;
167180
private int hashCode;
168181

169-
private OpaqueImpl(byte[] opaque) {
182+
OpaqueImpl(byte[] opaque) {
170183
_opaque = opaque;
171184
}
172185

@@ -175,10 +188,14 @@ public byte[] toBytes() {
175188
return _opaque.clone();
176189
}
177190

191+
protected String toBase64Impl() {
192+
return Base64.getEncoder().withoutPadding().encodeToString(_opaque);
193+
}
194+
178195
@Override
179196
public String toBase64() {
180197
if (base64 == null) {
181-
base64 = Base64.getEncoder().withoutPadding().encodeToString(_opaque);
198+
base64 = toBase64Impl();
182199
}
183200
return base64;
184201
}
@@ -246,6 +263,28 @@ public Opaque toImmutableOpaque() {
246263
}
247264
}
248265

266+
final class OpaqueMutableImpl extends OpaqueImpl {
267+
protected OpaqueMutableImpl(byte[] opaque) {
268+
super(opaque);
269+
}
270+
271+
@Override
272+
public Opaque toImmutableOpaque() {
273+
return Opaque.forBytes(_opaque);
274+
}
275+
276+
@Override
277+
public String toBase64() {
278+
return toBase64Impl();
279+
}
280+
281+
@Override
282+
public int hashCode() {
283+
return Arrays.hashCode(_opaque);
284+
}
285+
286+
}
287+
249288
final class OpaqueBufferImpl implements Opaque {
250289
private final ByteBuffer buf;
251290
private final int index;

core/src/test/java/org/dcache/nfs/util/OpaqueTest.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
public class OpaqueTest {
1111
@Test
12-
public void testMutable() {
12+
public void testMutableByteBuffer() {
1313
ByteBuffer buf = ByteBuffer.allocate(64);
1414
buf.putInt(3, 0xAABBCCDD);
1515
buf.putInt(7, 0xEEFF0011);
@@ -37,4 +37,23 @@ public void testMutable() {
3737
assertNotEquals(bytesOpaque, bufOpaque);
3838
assertNotEquals(bytesOpaque.hashCode(), bufOpaque.hashCode());
3939
}
40+
41+
@Test
42+
public void testMutableByteArray() throws Exception {
43+
byte[] buf = new byte[] {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04};
44+
Opaque bufOpaque = Opaque.forMutableByteArray(buf);
45+
Opaque bytesOpaque = Opaque.forBytes(new byte[] {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04});
46+
47+
assertEquals(bufOpaque.toBase64(), bytesOpaque.toBase64());
48+
assertEquals(bufOpaque, bytesOpaque);
49+
assertEquals(bytesOpaque, bufOpaque);
50+
assertEquals(bytesOpaque.hashCode(), bufOpaque.hashCode());
51+
52+
// change contents of mutable buffer
53+
buf[3] = (byte) 0xDD;
54+
assertNotEquals(bufOpaque.toBase64(), bytesOpaque.toBase64());
55+
assertNotEquals(bufOpaque, bytesOpaque);
56+
assertNotEquals(bytesOpaque, bufOpaque);
57+
assertNotEquals(bytesOpaque.hashCode(), bufOpaque.hashCode());
58+
}
4059
}

0 commit comments

Comments
 (0)