|
20 | 20 | package org.dcache.nfs.util;
|
21 | 21 |
|
22 | 22 | import java.nio.ByteBuffer;
|
| 23 | +import java.nio.ByteOrder; |
23 | 24 | import java.util.Arrays;
|
24 | 25 | import java.util.Base64;
|
25 | 26 | import java.util.Objects;
|
26 | 27 |
|
| 28 | +import org.dcache.oncrpc4j.util.Bytes; |
| 29 | + |
27 | 30 | /**
|
28 | 31 | * Describes something that can be used as a key for {@link java.util.HashMap} and that can be converted to a
|
29 | 32 | * {@code byte[]} and a Base64 string representation.
|
@@ -85,6 +88,9 @@ static Opaque forBytes(ByteBuffer buf, int length) {
|
85 | 88 | * @see #toImmutableOpaque()
|
86 | 89 | */
|
87 | 90 | static Opaque forMutableByteBuffer(ByteBuffer buf, int index, int length) {
|
| 91 | + if (buf.order() != ByteOrder.BIG_ENDIAN) { |
| 92 | + buf = buf.duplicate(); |
| 93 | + } |
88 | 94 | return new OpaqueBufferImpl(buf, index, length);
|
89 | 95 | }
|
90 | 96 |
|
@@ -174,10 +180,26 @@ default void putBytes(ByteBuffer buf) {
|
174 | 180 | @Override
|
175 | 181 | boolean equals(Object o);
|
176 | 182 |
|
177 |
| - class OpaqueImpl implements Opaque { |
| 183 | + /** |
| 184 | + * Returns the byte stored at the given position. |
| 185 | + * |
| 186 | + * @param byteOffset The byte offset |
| 187 | + * @return The byte. |
| 188 | + */ |
| 189 | + byte byteAt(int byteOffset); |
| 190 | + |
| 191 | + /** |
| 192 | + * Returns the {@code long} stored at the given position, using big-endian byte order. |
| 193 | + * |
| 194 | + * @param byteOffset The byte offset |
| 195 | + * @return The long. |
| 196 | + */ |
| 197 | + long longAt(int byteOffset); |
| 198 | + |
| 199 | + public class OpaqueImpl implements Opaque { |
178 | 200 | final byte[] _opaque;
|
179 | 201 |
|
180 |
| - OpaqueImpl(byte[] opaque) { |
| 202 | + protected OpaqueImpl(byte[] opaque) { |
181 | 203 | _opaque = opaque;
|
182 | 204 | }
|
183 | 205 |
|
@@ -253,6 +275,16 @@ public int numBytes() {
|
253 | 275 | public Opaque toImmutableOpaque() {
|
254 | 276 | return Opaque.forBytes(_opaque);
|
255 | 277 | }
|
| 278 | + |
| 279 | + @Override |
| 280 | + public byte byteAt(int position) { |
| 281 | + return _opaque[position]; |
| 282 | + } |
| 283 | + |
| 284 | + @Override |
| 285 | + public long longAt(int byteOffset) { |
| 286 | + return Bytes.getLong(_opaque, byteOffset); |
| 287 | + } |
256 | 288 | }
|
257 | 289 |
|
258 | 290 | final class OpaqueImmutableImpl extends OpaqueImpl {
|
@@ -360,13 +392,29 @@ public boolean equals(Object o) {
|
360 | 392 | }
|
361 | 393 | return true;
|
362 | 394 | } else {
|
363 |
| - return toImmutableOpaque().equals(o); |
| 395 | + Opaque other = (Opaque) o; |
| 396 | + for (int i = index, n = index + length, oi = 0; i < n; i++, oi++) { |
| 397 | + if (buf.get(i) != other.byteAt(oi)) { |
| 398 | + return false; |
| 399 | + } |
| 400 | + } |
| 401 | + return true; |
364 | 402 | }
|
365 | 403 | }
|
366 | 404 |
|
367 | 405 | @Override
|
368 | 406 | public String toString() {
|
369 | 407 | return super.toString() + "[" + toBase64() + "]";
|
370 | 408 | }
|
| 409 | + |
| 410 | + @Override |
| 411 | + public byte byteAt(int position) { |
| 412 | + return buf.get(position); |
| 413 | + } |
| 414 | + |
| 415 | + @Override |
| 416 | + public long longAt(int byteOffset) { |
| 417 | + return buf.getLong(byteOffset); |
| 418 | + } |
371 | 419 | }
|
372 | 420 | }
|
0 commit comments