/** * transfers appReadBuffer contents (decrypted data) into dst bytebuffer * @param dst ByteBuffer */ private int readFromAppBuffer(ByteBuffer dst) { appReadBuffer.flip(); int remaining = Math.min(appReadBuffer.remaining(), dst.remaining()); if (remaining > 0) { int limit = appReadBuffer.limit(); appReadBuffer.limit(appReadBuffer.position() + remaining); dst.put(appReadBuffer); appReadBuffer.limit(limit); } appReadBuffer.compact(); return remaining; }
private void ensureBufferSize(int bytes) { if (this.data.position() + bytes > this.data.limit()) { if (this.isResizeAllowed) { byte[] array = this.data.array(); byte[] newArray = new byte[array.length + bytes + (array.length >> 1)]; System.arraycopy(array, 0, newArray, 0, this.data.position()); int lastPos = this.data.position(); this.data = ByteBuffer.wrap(newArray); this.data.order(ByteOrder.LITTLE_ENDIAN); this.data.position(lastPos); this.data.limit(this.data.capacity()); } } }
private void expandBuffer(int remainingRequired) { int expandSize = Math.max((int) (buffer.limit() * REALLOCATION_FACTOR), buffer.position() + remainingRequired); ByteBuffer temp = ByteBuffer.allocate(expandSize); int limit = limit(); buffer.flip(); temp.put(buffer); buffer.limit(limit); // reset the old buffer's position so that the partial data in the new buffer cannot be mistakenly consumed // we should ideally only do this for the original buffer, but the additional complexity doesn't seem worth it buffer.position(initialPosition); buffer = temp; }
/** * Get the last {@code byte} from this {@literal Buffer}. * * @return The last {@code byte}. */ public byte last() { int pos = buffer.position(); int limit = buffer.limit(); buffer.position(limit - 1); // go to right before last position byte b = buffer.get(); // get the last byte buffer.position(pos); // go back to original pos return b; }
@Override public GenericRecord parse(ByteBuffer bytes) { try { bytes.get(); // ignore first \0 byte int id = bytes.getInt(); // extract schema registry id int length = bytes.limit() - 1 - 4; int offset = bytes.position() + bytes.arrayOffset(); Schema schema = registry.getByID(id); DatumReader<GenericRecord> reader = new GenericDatumReader<>(schema); return reader.read(null, DecoderFactory.get().binaryDecoder(bytes.array(), offset, length, null)); } catch (Exception e) { throw new ParseException(e, "Fail to decode avro message!"); } }
@SuppressWarnings("ByteBufferBackingArray") @NonNull public static byte[] toBytes(@NonNull ByteBuffer byteBuffer) { final byte[] result; SafeArray safeArray = getSafeArray(byteBuffer); if (safeArray != null && safeArray.offset == 0 && safeArray.limit == safeArray.data.length) { result = byteBuffer.array(); } else { ByteBuffer toCopy = byteBuffer.asReadOnlyBuffer(); result = new byte[toCopy.limit()]; toCopy.position(0); toCopy.get(result); } return result; }
@Nullable private static SafeArray getSafeArray(@NonNull ByteBuffer byteBuffer) { if (!byteBuffer.isReadOnly() && byteBuffer.hasArray()) { return new SafeArray(byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit()); } return null; }
private static <T> GenericIndexed<T> createGenericIndexedVersionOne(ByteBuffer byteBuffer, ObjectStrategy<T> strategy) { boolean allowReverseLookup = byteBuffer.get() == REVERSE_LOOKUP_ALLOWED; int size = byteBuffer.getInt(); ByteBuffer bufferToUse = byteBuffer.asReadOnlyBuffer(); bufferToUse.limit(bufferToUse.position() + size); byteBuffer.position(bufferToUse.limit()); return new GenericIndexed<>( bufferToUse, strategy, allowReverseLookup ); }
@Override public Object read(ByteBuffer buffer) { int size = buffer.getInt(); if (size < 0) return null; if (size > buffer.remaining()) throw new SchemaException("Error reading bytes of size " + size + ", only " + buffer.remaining() + " bytes available"); ByteBuffer val = buffer.slice(); val.limit(size); buffer.position(buffer.position() + size); return val; }
private @Nullable float[] parseMetadata(ByteBuffer data) { if (data.remaining() != 16) { return null; } scratch.reset(data.array(), data.limit()); scratch.setPosition(data.arrayOffset() + 4); // skip reserved bytes too. float[] result = new float[3]; for (int i = 0; i < 3; i++) { result[i] = Float.intBitsToFloat(scratch.readLittleEndianInt()); } return result; }
private static void assertDiscardToSpsMatchesExpected(String input, String expectedOutput) { byte[] bitstream = Util.getBytesFromHexString(input); byte[] expectedOutputBitstream = Util.getBytesFromHexString(expectedOutput); ByteBuffer buffer = ByteBuffer.wrap(bitstream); buffer.position(buffer.limit()); NalUnitUtil.discardToSps(buffer); assertThat(Arrays.copyOf(buffer.array(), buffer.position())).isEqualTo(expectedOutputBitstream); }