All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.openhft.chronicle.bytes.RandomDataInput Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2016-2022 chronicle.software
 *
 *     https://chronicle.software
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.openhft.chronicle.bytes;

import net.openhft.chronicle.bytes.internal.BytesInternal;
import net.openhft.chronicle.bytes.internal.Chars;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.UnsafeMemory;
import net.openhft.chronicle.core.annotation.NonNegative;
import net.openhft.chronicle.core.io.ClosedIllegalStateException;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.ThreadingIllegalStateException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import static net.openhft.chronicle.bytes.internal.ReferenceCountedUtil.throwExceptionIfReleased;
import static net.openhft.chronicle.core.util.Longs.requireNonNegative;
import static net.openhft.chronicle.core.util.ObjectUtils.requireNonNull;

/**
 * The {@code RandomDataInput} class provides a series of methods for reading data
 * from various types of inputs. It allows to read data from an input source
 * in a non-sequential manner, i.e., the data can be accessed at any offset.
 *
 * 

This class supports reading of primitive data types like {@code int}, * {@code long}, {@code double} etc., as well as more complex data structures * like {@code byte[]}, {@code String} and {@code ByteBuffer}. It also provides * methods for direct reading from memory and for reading with a load barrier. * *

Furthermore, the {@code RandomDataInput} class provides additional methods for * advanced operations like copying data to native memory, finding a specific byte, * calculating the hash code of a sequence of bytes, and more. * *

Methods in this class may throw {@code BufferUnderflowException} if the offset * specified is outside the limits of the byte sequence or {@code ClosedIllegalStateException} * if the byte sequence has been released. * *

Note: Implementations of this class are typically not thread-safe. If multiple * threads interact with a {@code RandomDataInput} instance concurrently, it must be synchronized * externally. */ public interface RandomDataInput extends RandomCommon { /** * Reads a volatile int value from the current reading position. * * @return the read int value. * @throws BufferUnderflowException If the reading position is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default int peekVolatileInt() throws BufferUnderflowException, ClosedIllegalStateException, ThreadingIllegalStateException { return readVolatileInt(readPosition()); } /** * Reads a boolean value from a specific offset. * * @param offset the location from where the boolean value is read. * @return the read boolean value. * @throws BufferUnderflowException If the offset is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default boolean readBoolean(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException { return BytesUtil.byteToBoolean(readByte(offset)); } /** * Reads a byte value from a specific offset. * * @param offset the location from where the byte value is read. * @return the read byte value. * @throws BufferUnderflowException If the offset is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ byte readByte(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException; /** * Reads an unsigned byte value from a specific offset. * The value is returned as an int in order to represent the unsigned byte as a positive value. * * @param offset the location from where the unsigned byte value is read. * @return the unsigned byte value interpreted as a positive int. * @throws BufferUnderflowException If the offset is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default int readUnsignedByte(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException { return readByte(offset) & 0xFF; } /** * Reads an unsigned byte value from a specific offset. * Returns -1 if the byte read is at the end of the byte source. * The value is returned as an int in order to represent the unsigned byte as a positive value. * * @param offset the location from where the unsigned byte value is read. * @return the unsigned byte value interpreted as a positive int or -1. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ int peekUnsignedByte(@NonNegative long offset) throws ClosedIllegalStateException, ThreadingIllegalStateException; /** * Reads a short value from a specific offset. * * @param offset the location from where the short value is read. * @return the read short value. * @throws BufferUnderflowException If the offset is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ short readShort(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException; /** * Reads an unsigned short value from a specific offset. * The value is returned as an int in order to represent the unsigned short as a positive value. * * @param offset the location from where the unsigned short value is read. * @return the unsigned short value interpreted as a positive int. * @throws BufferUnderflowException If the offset is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default int readUnsignedShort(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException { return readShort(offset) & 0xFFFF; } /** * Reads an unsigned 24-bit integer value from a specific offset. * The value is returned as an int, with the upper 8 bits zeroed. * * @param offset the location from where the unsigned 24-bit integer value is read. * @return the unsigned 24-bit integer value interpreted as a positive int. * @throws BufferUnderflowException If the offset is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default int readUnsignedInt24(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException { return readUnsignedShort(offset) | (readUnsignedByte(offset) << 16); } /** * Reads a 32-bit integer value from a specific offset. * * @param offset the location from where the 32-bit integer value is read. * @return the read int value. * @throws BufferUnderflowException If the offset is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ int readInt(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException; /** * Reads an unsigned 32-bit integer value from a specific offset. * The value is returned as a long in order to represent the unsigned int as a positive value. * * @param offset the location from where the unsigned 32-bit integer value is read. * @return the unsigned 32-bit integer value interpreted as a positive long. * @throws BufferUnderflowException If the offset is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default long readUnsignedInt(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException { return readInt(offset) & 0xFFFFFFFFL; } /** * Reads a 64-bit long value from a specific offset. * * @param offset the location from where the long value is read. * @return the read long value. * @throws BufferUnderflowException If the offset is outside the bounds of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ long readLong(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException; /** * Reads a 32-bit floating point value from a specified offset. * * @param offset the location from where the float value is read. * @return the read float value. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ float readFloat(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException; /** * Reads a 64-bit floating point value from a specified offset. * * @param offset the location from where the double value is read. * @return the read double value. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ double readDouble(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException; /** * Reads a byte value from a specified offset and converts it into a printable string. * * @param offset the location from where the byte value is read. * @return the byte value in a printable string form. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default String printable(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException { return Chars.charToString[readUnsignedByte(offset)]; } /** * Reads a volatile 8-bit byte value from a specified offset. This operation includes a memory * barrier that prevents reordering of instructions before and after it. * * @param offset the location from where the byte value is read. * @return the volatile byte value. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ byte readVolatileByte(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException, ThreadingIllegalStateException; /** * Reads a volatile 16-bit short value from a specified offset. This operation includes a memory * barrier that prevents reordering of instructions before and after it. * * @param offset the location from where the short value is read. * @return the volatile short value. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ short readVolatileShort(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException, ThreadingIllegalStateException; /** * Reads a volatile 32-bit integer value from a specified offset. This operation includes a memory * barrier that prevents reordering of instructions before and after it. * * @param offset the location from where the int value is read. * @return the volatile int value. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ int readVolatileInt(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException, ThreadingIllegalStateException; /** * Reads a volatile 32-bit floating point value from a specified offset. This operation includes a memory * barrier that prevents reordering of instructions before and after it. * * @param offset the location from where the float value is read. * @return the volatile float value. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default float readVolatileFloat(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException { return Float.intBitsToFloat(readVolatileInt(offset)); } /** * Reads a volatile 64-bit long value from a specified offset. This operation includes a memory * barrier that prevents reordering of instructions before and after it. * * @param offset the location from where the long value is read. * @return the volatile long value. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ long readVolatileLong(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException, ThreadingIllegalStateException; /** * Reads a volatile 64-bit double value from a specified offset. This operation includes a memory * barrier that prevents reordering of instructions before and after it. * * @param offset the location from where the double value is read. * @return the volatile double value. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default double readVolatileDouble(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException { return Double.longBitsToDouble(readVolatileLong(offset)); } /** * Parses a long value from a specified offset. * * @param offset the location from where the long value is read. * @return the parsed long value. * @throws BufferUnderflowException If the offset is beyond the limits of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default long parseLong(@NonNegative long offset) throws BufferUnderflowException, ClosedIllegalStateException { return BytesInternal.parseLong(this, offset); } /** * Expert-level method for transferring data from this byte source to native memory. * * @param position the starting point within the byte source from which data is copied. * @param address the destination address in native memory. * @param size the number of bytes to transfer. * @throws BufferUnderflowException If the specified position or size exceeds the byte source limits. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ void nativeRead(@NonNegative long position, long address, @NonNegative long size) throws BufferUnderflowException, ClosedIllegalStateException, ThreadingIllegalStateException; /** * Copies data from this byte source into a byte array. The data is read from {@link RandomCommon#readPosition()} * up to {@link RandomCommon#readLimit()}. * * @param bytes the target byte array to which the data is copied. * @return the number of bytes actually copied. * @throws BufferUnderflowException If the source's read position or limit is beyond the byte source limits. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default int copyTo(byte[] bytes) throws BufferUnderflowException, ClosedIllegalStateException { requireNonNull(bytes); throwExceptionIfReleased(this); int len = (int) Math.min(bytes.length, readRemaining()); long readPosition = readPosition(); int i = 0; for (; i < len - 7; i += 8) UnsafeMemory.unsafePutLong(bytes, i, readLong(readPosition + i)); for (; i < len; i++) bytes[i] = readByte(readPosition + i); return len; } /** * Copies data from this RandomDataInput to the specified ByteBuffer. The number of copied bytes is the * minimum of the remaining bytes to read in this RandomDataInput and the remaining capacity of the ByteBuffer. * The data copying starts from the current read position in this RandomDataInput and from the current * position in the ByteBuffer. The ByteBuffer's position, limit, or mark are not modified by this operation. * Returns the number of bytes copied. * * @param bb the target ByteBuffer to which the data is copied. * @return the number of bytes copied. * @throws BufferUnderflowException If the read operation encounters end of the byte source. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default int copyTo(@NotNull ByteBuffer bb) throws BufferUnderflowException, ClosedIllegalStateException { requireNonNull(bb); throwExceptionIfReleased(this); int pos = bb.position(); int len = (int) Math.min(bb.remaining(), readRemaining()); long readPosition = readPosition(); int i; for (i = 0; i < len - 7; i += 8) bb.putLong(pos + i, readLong(readPosition + i)); for (; i < len; i++) bb.put(pos + i, readByte(readPosition + i)); return len; } /** * Reads a long value from the specified offset. If less than 8 bytes are available to read, * this method pads the high bytes with zeros. If the offset is at or beyond the read limit, * this method returns 0L. * * @param offset the location from where the long value is read. * @return the long value, potentially zero-padded. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default long readIncompleteLong(@NonNegative long offset) throws ClosedIllegalStateException { long left = readLimit() - offset; long l; if (left >= 8) return readLong(offset); if (left == 4) return readInt(offset); l = 0; for (int i = 0, remaining = (int) left; i < remaining; i++) { l |= (long) readUnsignedByte(offset + i) << (i * 8); } return l; } /** * Returns the actual capacity that can be potentially read from this byte source. * * @return the actual readable capacity. */ @Override @NonNegative long realCapacity(); /** * Returns a new BytesStore that is a subsequence of this byte sequence, starting at the specified index and of the specified length. * * @param start the start index, inclusive. * @param length the length of the subsequence. * @return a new BytesStore instance containing the specified subsequence. * @throws BufferUnderflowException If the start index or length are outside the limits of this byte sequence. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ @SuppressWarnings("rawtypes") @NotNull default BytesStore subBytes(@NonNegative long start, @NonNegative long length) throws BufferUnderflowException, ClosedIllegalStateException { return BytesInternal.subBytes(this, start, length); } /** * Finds the first occurrence of the specified byte in this byte sequence. * * @param stopByte the byte to be searched for. * @return the index of the first occurrence of the byte, or -1 if the byte is not found. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default long findByte(byte stopByte) throws ClosedIllegalStateException { return BytesInternal.findByte(this, stopByte); } /** * Truncates {@code sb} (it must be a {@link StringBuilder} or {@link Bytes}) and reads a char * sequence from the given {@code offset}, encoded as Utf8, into it. Returns offset after * the read Utf8, if a normal char sequence was read, or {@code -1 - offset}, if {@code null} * was observed (in this case, {@code sb} is truncated too, but not updated then, by querying * {@code sb} only this case is indistinguishable from reading an empty char sequence). * * @param buffer type, must be {@code StringBuilder} or {@code Bytes} * @param offset the offset in this {@code RandomDataInput} to read char sequence from * @param sb the buffer to read char sequence into (truncated first) * @return offset after the normal read char sequence, or -1 - offset, if char sequence is * {@code null} * @throws IORuntimeException If the reading operation encounters an unexpected error. * @throws IllegalArgumentException If the buffer is not a {@code StringBuilder} or {@code Bytes}. * @throws BufferUnderflowException If the reading operation encounters the end of the byte source. * @throws ArithmeticException If the calculated length of the UTF-8 encoded string is invalid. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way * @see RandomDataOutput#writeUtf8(long, CharSequence) */ default long readUtf8(@NonNegative long offset, @NotNull T sb) throws IORuntimeException, IllegalArgumentException, BufferUnderflowException, ArithmeticException, ClosedIllegalStateException { AppendableUtil.setLength(sb, 0); // TODO insert some bounds check here long utfLen; if ((utfLen = readByte(offset++)) < 0) { utfLen &= 0x7FL; long b; int count = 7; while ((b = readByte(offset++)) < 0) { utfLen |= (b & 0x7FL) << count; count += 7; } if (b != 0) { if (count > 56) throw new IORuntimeException( "Cannot read more than 9 stop bits of positive value"); utfLen |= (b << count); } else { if (count > 63) throw new IORuntimeException( "Cannot read more than 10 stop bits of negative value"); utfLen = ~utfLen; } } if (utfLen == -1) return ~offset; int len = Maths.toUInt31(utfLen); BytesInternal.parseUtf8(this, offset, sb, true, len); return offset + utfLen; } /** * Truncates {@code sb} (it must be a {@link StringBuilder} or {@link Bytes}) and reads a char * sequence from the given {@code offset}, encoded as Utf8, into it. Returns offset after * the read Utf8, if a normal char sequence was read, or {@code -1 - offset}, if {@code null} * was observed (in this case, {@code sb} is truncated too, but not updated then, by querying * {@code sb} only this case is indistinguishable from reading an empty char sequence). If * length of Utf8 encoding of the char sequence exceeds {@code maxUtf8Len}, * {@code ClosedIllegalStateException} is thrown. * * @param buffer type, must be {@code StringBuilder} or {@code Bytes} * @param offset the offset in this {@code RandomDataInput} to read char sequence from * @param sb the buffer to read char sequence into (truncated first) * @param maxUtf8Len the maximum allowed length of the char sequence in Utf8 encoding * @return offset after the normal read char sequence, or -1 - offset, if char sequence is * {@code null} * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way * @see RandomDataOutput#writeUtf8Limited(long, CharSequence, int) */ default long readUtf8Limited(@NonNegative long offset, @NotNull final T sb, @NonNegative final int maxUtf8Len) throws IORuntimeException, IllegalArgumentException, BufferUnderflowException, ClosedIllegalStateException { AppendableUtil.setLength(sb, 0); // TODO insert some bounds check here long utfLen; if ((utfLen = readByte(offset++)) < 0) { utfLen &= 0x7FL; long b; int count = 7; while ((b = readByte(offset++)) < 0) { utfLen |= (b & 0x7FL) << count; count += 7; } if (b != 0) { if (count > 56) throw new IORuntimeException( "Cannot read more than 9 stop bits of positive value"); utfLen |= (b << count); } else { if (count > 63) throw new IORuntimeException( "Cannot read more than 10 stop bits of negative value"); utfLen = ~utfLen; } } if (utfLen == -1) return ~offset; if (utfLen > maxUtf8Len) throw new ClosedIllegalStateException("Attempted to read a char sequence of " + "utf8 size " + utfLen + ", when only " + maxUtf8Len + " allowed"); BytesInternal.parseUtf8(this, offset, sb, true, (int) utfLen); return offset + utfLen; } /** * Reads a char sequence from the given {@code offset}, encoded as Utf8. If length of Utf8 * encoding of the char sequence exceeds {@code maxUtf8Len}, {@code ClosedIllegalStateException} * is thrown. * * @param offset the offset in this {@code RandomDataInput} to read char sequence from * @param maxUtf8Len the maximum allowed length of the char sequence in Utf8 encoding * @return the char sequence was read * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way * @see RandomDataOutput#writeUtf8Limited(long, CharSequence, int) */ @Nullable default String readUtf8Limited(@NonNegative long offset, @NonNegative int maxUtf8Len) throws BufferUnderflowException, IORuntimeException, IllegalArgumentException, ClosedIllegalStateException { return BytesInternal.readUtf8(this, offset, maxUtf8Len); } /** * Compares the UTF-8 encoded char sequence, written in this {@code RandomDataInput} at the * given offset, with the given char sequence. Returns {@code true}, if they are equal. Both * char sequences (encoded in bytes and the given) may be {@code null}. * * @param offset the offset in this {@code RandomDataInput} where the char sequence to compare * is written * @param other the second char sequence to compare * @return {@code true} if two char sequences are equal * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way * @throws IORuntimeException If the contents are not a valid string. */ default boolean compareUtf8(@NonNegative long offset, @Nullable CharSequence other) throws IORuntimeException, BufferUnderflowException, ClosedIllegalStateException { return BytesInternal.compareUtf8(this, offset, other); } default byte[] toByteArray() throws ClosedIllegalStateException { return BytesInternal.toByteArray(this); } /** * Reads a sequence of bytes from the specified offset into a byte array. * * @param offsetInRDI the offset in the byte sequence from which to start reading. * @param bytes the byte array into which the data is read. * @param offset the start offset in the byte array at which the data is written. * @param length the maximum number of bytes to read. * @return the actual number of bytes read into the byte array. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default long read(@NonNegative long offsetInRDI, byte[] bytes, @NonNegative int offset, @NonNegative int length) throws ClosedIllegalStateException { requireNonNull(bytes); int len = Maths.toUInt31(Math.min(length, requireNonNegative(readLimit() - offsetInRDI))); for (int i = 0; i < len; i++) bytes[offset + i] = readByte(offsetInRDI + i); return len; } /** * Converts the byte sequence into a direct byte buffer. * * @return a direct ByteBuffer containing the data of this byte sequence. * @throws IllegalArgumentException If the byte sequence cannot be converted into a ByteBuffer. * @throws ArithmeticException If the calculated size of the ByteBuffer is invalid. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default ByteBuffer toTemporaryDirectByteBuffer() throws IllegalArgumentException, ArithmeticException, ClosedIllegalStateException { throwExceptionIfReleased(this); int len = Maths.toUInt31(readRemaining()); ByteBuffer bb = ByteBuffer.allocateDirect(len); bb.order(ByteOrder.nativeOrder()); copyTo(bb); bb.clear(); return bb; } /** * Computes a hash code for a sequence of bytes. * * @param offset the start offset of the sequence of bytes. * @param length the length of the sequence of bytes. * @return a hash code value for the specified sequence of bytes. * @throws BufferUnderflowException If the specified sequence of bytes extends beyond the limits of this byte sequence. * @throws ClosedIllegalStateException If the resource has been released or closed. * @throws ThreadingIllegalStateException If this resource was accessed by multiple threads in an unsafe way */ default int fastHash(@NonNegative long offset, @NonNegative int length) throws BufferUnderflowException, ClosedIllegalStateException { long hash = 0; int i = 0; if (length >= 4) { hash = readInt(offset + i); i += 4; } for (; i < length - 3; i += 4) { hash *= 0x6d0f27bd; hash += readInt(offset + i); } if (i < length - 1) { hash *= 0x6d0f27bdL; hash += readShort(offset + i); i += 2; } if (i < length) hash += readByte(offset + i); hash *= 0x855dd4db; return (int) (hash ^ (hash >> 32)); } /** * Checks if this byte sequence can be read directly from native memory. * * @return true if the byte sequence can be read directly, false otherwise. */ default boolean canReadDirect() { return canReadDirect(); } /** * Checks if the specified length of bytes can be read directly from native memory. * * @param length the number of bytes to check. * @return true if the byte sequence is backed by direct memory and the remaining bytes are more than or equal to the specified length, false otherwise. */ default boolean canReadDirect(@NonNegative long length) { return isDirectMemory() && readRemaining() >= length; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy