< prev index next > src/java.base/share/classes/java/lang/foreign/MemorySegment.java
Print this page
*/
package java.lang.foreign;
import java.io.UncheckedIOException;
- import java.lang.foreign.Linker.Option;
- import java.lang.invoke.MethodHandle;
- import java.lang.invoke.MethodHandles;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
! import java.nio.channels.FileChannel.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.Spliterator;
*/
package java.lang.foreign;
import java.io.UncheckedIOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
! import java.nio.channels.FileChannel.MapMode;
+ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.Spliterator;
import java.util.stream.Stream;
import jdk.internal.foreign.AbstractMemorySegmentImpl;
import jdk.internal.foreign.HeapMemorySegmentImpl;
import jdk.internal.foreign.MemorySessionImpl;
import jdk.internal.foreign.NativeMemorySegmentImpl;
import jdk.internal.foreign.Utils;
- import jdk.internal.foreign.abi.SharedUtils;
- import jdk.internal.foreign.layout.ValueLayouts;
- import jdk.internal.javac.PreviewFeature;
import jdk.internal.javac.Restricted;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.vm.annotation.ForceInline;
/**
import java.util.stream.Stream;
import jdk.internal.foreign.AbstractMemorySegmentImpl;
import jdk.internal.foreign.HeapMemorySegmentImpl;
import jdk.internal.foreign.MemorySessionImpl;
import jdk.internal.foreign.NativeMemorySegmentImpl;
+ import jdk.internal.foreign.StringSupport;
import jdk.internal.foreign.Utils;
import jdk.internal.javac.Restricted;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.vm.annotation.ForceInline;
/**
* {@snippet lang=java :
* MemorySegment segment = ...
* int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
* }
*
! * For more complex access operations (e.g. structured memory access), clients can obtain a
! * {@linkplain MethodHandles#memorySegmentViewVarHandle(ValueLayout) var handle}
! * that accepts a segment and a {@code long} offset. More complex var handles
! * can be obtained by adapting a segment var handle view using the var handle combinator functions defined in the
! * {@link java.lang.invoke.MethodHandles} class:
*
! * {@snippet lang=java :
* MemorySegment segment = ...
! * VarHandle intHandle = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT);
! * MethodHandle multiplyExact = MethodHandles.lookup()
! * .findStatic(Math.class, "multiplyExact",
! * MethodType.methodType(long.class, long.class, long.class));
! * intHandle = MethodHandles.filterCoordinates(intHandle, 1,
- * MethodHandles.insertArguments(multiplyExact, 0, ValueLayout.JAVA_INT.byteSize()));
- * int value = (int) intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12
* }
*
! * Alternatively, complex var handles can can be obtained
! * from {@linkplain MemoryLayout#varHandle(MemoryLayout.PathElement...) memory layouts}
! * by providing a so called <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>:
*
* {@snippet lang=java :
* MemorySegment segment = ...
! * VarHandle intHandle = ValueLayout.JAVA_INT.arrayElementVarHandle();
! * int value = (int) intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12
* }
*
* <h2 id="slicing">Slicing memory segments</h2>
*
* Memory segments support {@linkplain MemorySegment#asSlice(long, long) slicing}. Slicing a memory segment
* returns a new memory segment that is backed by the same region of memory as the original. The address of the sliced
* {@snippet lang=java :
* MemorySegment segment = ...
* int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
* }
*
! * More complex access operations can be implemented using var handles. The {@link ValueLayout#varHandle()}
! * method can be used to obtain a var handle that can be used to get/set values represented by the given value layout on a memory segment.
! * A var handle obtained from a layout supports several additional <a href=MemoryLayout.html#access-mode-restrictions>
! * access modes</a>. More importantly, var handles can be <em>combined</em> with method handles to express complex access
! * operations. For instance, a var handle that can be used to access an element of an {@code int} array at a given logical
+ * index can be created as follows:
*
! * {@snippet lang=java:
* MemorySegment segment = ...
! * VarHandle intHandle = ValueLayout.JAVA_INT.varHandle(); // (MemorySegment, long)
! * MethodHandle scale = ValueLayout.JAVA_INT.scaleHandle(); // <base offset> + <index> * JAVA_INT.byteSize()
! *
! * intHandle = MethodHandles.filterCoordinates(intHandle, 1, scale);
! * int value = (int) intHandle.get(segment, 0L, 3L); // get int element at offset 0 + 3 * 4 = 12
* }
*
! * To make the process of creating these var handles easier, the method
! * {@link MemoryLayout#varHandle(MemoryLayout.PathElement...)} can be used, by providing it a so called
! * <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>. A layout path, consisting of several <em>layout
+ * path elements</em>, selects a value layout to be accessed, which can be nested inside another memory layout. For example,
+ * we can express the access to an element of an {@code int} array using layout paths like so:
*
* {@snippet lang=java :
* MemorySegment segment = ...
! * MemoryLayout segmentLayout = MemoryLayout.structLayout(
! * ValueLayout.JAVA_INT.withName("size"),
+ * MemoryLayout.sequenceLayout(4, ValueLayout.JAVA_INT).withName("data") // array of 4 elements
+ * );
+ * VarHandle intHandle = segmentLayout.varHandle(MemoryLayout.PathElemenet.groupElement("data"),
+ * MemoryLayout.PathElement.sequenceElement());
+ * int value = (int) intHandle.get(segment, 0L, 3L); // get int element at offset 0 + offsetof(data) + 3 * 4 = 12
* }
+ * Where {@code offsetof(data)} is the offset of the {@code data} element layout of the {@code segmentLayout} layout
+ *
+ * Both the var handle returned by {@link ValueLayout#varHandle()} and
+ * {@link MemoryLayout#varHandle(MemoryLayout.PathElement...)}, as well as the method handle returned by
+ * {@link MemoryLayout#byteOffsetHandle(MemoryLayout.PathElement...)} and {@link MemoryLayout#sliceHandle(MemoryLayout.PathElement...)}
+ * feature a <em>base offset</em> parameter. This parameter represents a base offset for the offset computation. This
+ * parameter allows a client to combine these handles further with additional offset computations. This is demonstrated
+ * in the first of the two examples above, where {@code intHandle} is combined with a
+ * {@linkplain MemoryLayout#scaleHandle() scale handle} obtained from {@code ValueLayout.JAVA_INT}.
*
* <h2 id="slicing">Slicing memory segments</h2>
*
* Memory segments support {@linkplain MemorySegment#asSlice(long, long) slicing}. Slicing a memory segment
* returns a new memory segment that is backed by the same region of memory as the original. The address of the sliced
* <li>The size of the segment is zero. any attempt to access these segments will fail with {@link IndexOutOfBoundsException}.
* This is a crucial safety feature: as these segments are associated with a region
* of memory whose size is not known, any access operations involving these segments cannot be validated.
* In effect, a zero-length memory segment <em>wraps</em> an address, and it cannot be used without explicit intent
* (see below);</li>
! * <li>The segment is associated with a fresh scope that is always alive. Thus, while zero-length
* memory segments cannot be accessed directly, they can be passed, opaquely, to other pointer-accepting foreign functions.</li>
* </ul>
* <p>
* To demonstrate how clients can work with zero-length memory segments, consider the case of a client that wants
* to read a pointer from some memory segment. This can be done via the
* <li>The size of the segment is zero. any attempt to access these segments will fail with {@link IndexOutOfBoundsException}.
* This is a crucial safety feature: as these segments are associated with a region
* of memory whose size is not known, any access operations involving these segments cannot be validated.
* In effect, a zero-length memory segment <em>wraps</em> an address, and it cannot be used without explicit intent
* (see below);</li>
! * <li>The segment is associated with a scope that is always alive. Thus, while zero-length
* memory segments cannot be accessed directly, they can be passed, opaquely, to other pointer-accepting foreign functions.</li>
* </ul>
* <p>
* To demonstrate how clients can work with zero-length memory segments, consider the case of a client that wants
* to read a pointer from some memory segment. This can be done via the
* the memory segment.
*
* @implSpec
* Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
*
! * @since 19
*/
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
/**
* {@return the address of this memory segment}
*
* the memory segment.
*
* @implSpec
* Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
*
! * @since 22
*/
public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
/**
* {@return the address of this memory segment}
*
/**
* Returns a new memory segment that has the same address and scope as this segment, but with the provided size.
* <p>
* This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
* Restricted methods are unsafe, and, if used incorrectly, their use might crash
! * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
- * restricted methods, and use safe and supported functionalities, where possible.
*
* @param newSize the size of the returned segment.
* @return a new memory segment that has the same address and scope as this segment, but the new
* provided size.
* @throws IllegalArgumentException if {@code newSize < 0}.
/**
* Returns a new memory segment that has the same address and scope as this segment, but with the provided size.
* <p>
* This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
* Restricted methods are unsafe, and, if used incorrectly, their use might crash
! * the JVM or, worse, silently result in memory corruption.
*
* @param newSize the size of the returned segment.
* @return a new memory segment that has the same address and scope as this segment, but the new
* provided size.
* @throws IllegalArgumentException if {@code newSize < 0}.
* invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
* {@snippet lang=java :
* MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
* .reinterpret(byteSize());
* }
! * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive,
* and is accessible from any thread. The size of the segment accepted by the cleanup action is {@link #byteSize()}.
* <p>
* This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
* Restricted methods are unsafe, and, if used incorrectly, their use might crash
! * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
- * restricted methods, and use safe and supported functionalities, where possible.
*
* @apiNote The cleanup action (if present) should take care not to leak the received segment to external
* clients which might access the segment after its backing region of memory is no longer available. Furthermore,
* if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
* must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.
* invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
* {@snippet lang=java :
* MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
* .reinterpret(byteSize());
* }
! * That is, the cleanup action receives a segment that is associated with a scope that is always alive,
* and is accessible from any thread. The size of the segment accepted by the cleanup action is {@link #byteSize()}.
* <p>
* This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
* Restricted methods are unsafe, and, if used incorrectly, their use might crash
! * the JVM or, worse, silently result in memory corruption.
*
* @apiNote The cleanup action (if present) should take care not to leak the received segment to external
* clients which might access the segment after its backing region of memory is no longer available. Furthermore,
* if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
* must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.
* invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
* {@snippet lang=java :
* MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
* .reinterpret(newSize);
* }
! * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive,
* and is accessible from any thread. The size of the segment accepted by the cleanup action is {@code newSize}.
* <p>
* This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
* Restricted methods are unsafe, and, if used incorrectly, their use might crash
! * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
- * restricted methods, and use safe and supported functionalities, where possible.
*
* @apiNote The cleanup action (if present) should take care not to leak the received segment to external
* clients which might access the segment after its backing region of memory is no longer available. Furthermore,
* if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
* must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.
* invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
* {@snippet lang=java :
* MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
* .reinterpret(newSize);
* }
! * That is, the cleanup action receives a segment that is associated with a scope that is always alive,
* and is accessible from any thread. The size of the segment accepted by the cleanup action is {@code newSize}.
* <p>
* This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
* Restricted methods are unsafe, and, if used incorrectly, their use might crash
! * the JVM or, worse, silently result in memory corruption.
*
* @apiNote The cleanup action (if present) should take care not to leak the received segment to external
* clients which might access the segment after its backing region of memory is no longer available. Furthermore,
* if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
* must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.
* @param other the segment to test for an overlap with this segment.
* @return a slice of this segment (where overlapping occurs).
*/
Optional<MemorySegment> asOverlappingSlice(MemorySegment other);
- /**
- * Returns the offset, in bytes, of the provided segment, relative to this
- * segment.
- *
- * <p>The offset is relative to the address of this segment and can be
- * a negative or positive value. For instance, if both segments are native
- * segments, or heap segments backed by the same array, the resulting offset
- * can be computed as follows:
- *
- * {@snippet lang=java :
- * other.address() - address()
- * }
- *
- * If the segments share the same address, {@code 0} is returned. If
- * {@code other} is a slice of this segment, the offset is always
- * {@code 0 <= x < this.byteSize()}.
- *
- * @param other the segment to retrieve an offset to.
- * @throws UnsupportedOperationException if the two segments cannot be compared, e.g. because they are of
- * different kinds, or because they are backed by different Java arrays.
- * @return the relative offset, in bytes, of the provided segment.
- */
- long segmentOffset(MemorySegment other);
-
/**
* Fills the contents of this memory segment with the given value.
* <p>
* More specifically, the given value is written into each address of this
* segment. Equivalent to (but likely more efficient than) the following code:
*
* {@snippet lang=java :
* for (long offset = 0; offset < segment.byteSize(); offset++) {
! * byteHandle.set(ValueLayout.JAVA_BYTE, offset, value);
* }
* }
*
* But without any regard or guarantees on the ordering of particular memory
* elements being set.
* @param other the segment to test for an overlap with this segment.
* @return a slice of this segment (where overlapping occurs).
*/
Optional<MemorySegment> asOverlappingSlice(MemorySegment other);
/**
* Fills the contents of this memory segment with the given value.
* <p>
* More specifically, the given value is written into each address of this
* segment. Equivalent to (but likely more efficient than) the following code:
*
* {@snippet lang=java :
* for (long offset = 0; offset < segment.byteSize(); offset++) {
! * segment.set(ValueLayout.JAVA_BYTE, offset, value);
* }
* }
*
* But without any regard or guarantees on the ordering of particular memory
* elements being set.
* e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer.MAX_VALUE}.
*/
double[] toArray(ValueLayout.OfDouble elementLayout);
/**
! * Reads a UTF-8 encoded, null-terminated string from this segment at the given offset.
* <p>
! * This method always replaces malformed-input and unmappable-character
! * sequences with this charset's default replacement string. The {@link
! * java.nio.charset.CharsetDecoder} class should be used when more control
! * over the decoding process is required.
* @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
* @return a Java string constructed from the bytes read from the given starting address up to (but not including)
* the first {@code '\0'} terminator character (assuming one is found).
! * @throws IllegalArgumentException if the size of the UTF-8 string is greater than the largest string supported by the platform.
! * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code offset > byteSize() - S}, where {@code S} is the size of the UTF-8
! * string (including the terminator character).
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
*/
! default String getUtf8String(long offset) {
! return SharedUtils.toJavaStringInternal(this, offset);
}
/**
! * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence using UTF-8 encoding.
* <p>
* This method always replaces malformed-input and unmappable-character
* sequences with this charset's default replacement string. The {@link
* java.nio.charset.CharsetDecoder} class should be used when more control
* over the decoding process is required.
* <p>
! * If the given string contains any {@code '\0'} characters, they will be
! * copied as well. This means that, depending on the method used to read
! * the string, such as {@link MemorySegment#getUtf8String(long)}, the string
! * will appear truncated when read again.
* @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
* the final address of this write operation can be expressed as {@code address() + offset}.
* @param str the Java string to be written into this segment.
! * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code offset > byteSize() - str.getBytes().length() + 1}.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
*/
! default void setUtf8String(long offset, String str) {
! Utils.toCString(str.getBytes(StandardCharsets.UTF_8), SegmentAllocator.prefixAllocator(asSlice(offset)));
}
/**
* Creates a memory segment that is backed by the same region of memory that backs the given {@link Buffer} instance.
* The segment starts relative to the buffer's position (inclusive) and ends relative to the buffer's limit (exclusive).
* <p>
* e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer.MAX_VALUE}.
*/
double[] toArray(ValueLayout.OfDouble elementLayout);
/**
! * Reads a null-terminated string from this segment at the given offset, using the
+ * {@linkplain StandardCharsets#UTF_8 UTF-8} charset.
* <p>
! * Calling this method is equivalent to the following code:
! * {@snippet lang = java:
! * getString(offset, StandardCharsets.UTF_8);
! *}
+ *
* @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
* @return a Java string constructed from the bytes read from the given starting address up to (but not including)
* the first {@code '\0'} terminator character (assuming one is found).
! * @throws IllegalArgumentException if the size of the string is greater than the largest string supported by the platform.
! * @throws IndexOutOfBoundsException if {@code offset < 0}.
! * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + 1)}, where {@code B} is the size,
+ * in bytes, of the string encoded using UTF-8 charset {@code str.getBytes(StandardCharsets.UTF_8).length}).
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
*/
! default String getString(long offset) {
! return getString(offset, sun.nio.cs.UTF_8.INSTANCE);
}
/**
! * Reads a null-terminated string from this segment at the given offset, using the provided charset.
* <p>
* This method always replaces malformed-input and unmappable-character
* sequences with this charset's default replacement string. The {@link
* java.nio.charset.CharsetDecoder} class should be used when more control
* over the decoding process is required.
+ *
+ * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
+ * @param charset the charset used to {@linkplain Charset#newDecoder() decode} the string bytes.
+ * @return a Java string constructed from the bytes read from the given starting address up to (but not including)
+ * the first {@code '\0'} terminator character (assuming one is found).
+ * @throws IllegalArgumentException if the size of the string is greater than the largest string supported by the platform.
+ * @throws IndexOutOfBoundsException if {@code offset < 0}.
+ * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + N)}, where:
+ * <ul>
+ * <li>{@code B} is the size, in bytes, of the string encoded using the provided charset
+ * (e.g. {@code str.getBytes(charset).length});</li>
+ * <li>{@code N} is the size (in bytes) of the terminator char according to the provided charset. For instance,
+ * this is 1 for {@link StandardCharsets#US_ASCII} and 2 for {@link StandardCharsets#UTF_16}.</li>
+ * </ul>
+ * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
+ * {@linkplain Scope#isAlive() alive}.
+ * @throws WrongThreadException if this method is called from a thread {@code T},
+ * such that {@code isAccessibleBy(T) == false}.
+ * @throws UnsupportedOperationException if {@code charset} is not a {@linkplain StandardCharsets standard charset}.
+ */
+ default String getString(long offset, Charset charset) {
+ Objects.requireNonNull(charset);
+ return StringSupport.read(this, offset, charset);
+ }
+
+ /**
+ * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence
+ * using the {@linkplain StandardCharsets#UTF_8 UTF-8} charset.
* <p>
! * Calling this method is equivalent to the following code:
! * {@snippet lang = java:
! * setString(offset, str, StandardCharsets.UTF_8);
! *}
* @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
* the final address of this write operation can be expressed as {@code address() + offset}.
* @param str the Java string to be written into this segment.
! * @throws IndexOutOfBoundsException if {@code offset < 0}.
+ * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + 1)}, where {@code B} is the size,
+ * in bytes, of the string encoded using UTF-8 charset {@code str.getBytes(StandardCharsets.UTF_8).length}).
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
*/
! default void setString(long offset, String str) {
! Objects.requireNonNull(str);
+ setString(offset, str, sun.nio.cs.UTF_8.INSTANCE);
}
+ /**
+ * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence
+ * using the provided charset.
+ * <p>
+ * This method always replaces malformed-input and unmappable-character
+ * sequences with this charset's default replacement string. The {@link
+ * java.nio.charset.CharsetDecoder} class should be used when more control
+ * over the decoding process is required.
+ * <p>
+ * If the given string contains any {@code '\0'} characters, they will be
+ * copied as well. This means that, depending on the method used to read
+ * the string, such as {@link MemorySegment#getString(long)}, the string
+ * will appear truncated when read again.
+ *
+ * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
+ * the final address of this write operation can be expressed as {@code address() + offset}.
+ * @param str the Java string to be written into this segment.
+ * @param charset the charset used to {@linkplain Charset#newEncoder() encode} the string bytes.
+ * @throws IndexOutOfBoundsException if {@code offset < 0}.
+ * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + N)}, where:
+ * <ul>
+ * <li>{@code B} is the size, in bytes, of the string encoded using the provided charset
+ * (e.g. {@code str.getBytes(charset).length});</li>
+ * <li>{@code N} is the size (in bytes) of the terminator char according to the provided charset. For instance,
+ * this is 1 for {@link StandardCharsets#US_ASCII} and 2 for {@link StandardCharsets#UTF_16}.</li>
+ * </ul>
+ * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
+ * {@linkplain Scope#isAlive() alive}.
+ * @throws WrongThreadException if this method is called from a thread {@code T},
+ * such that {@code isAccessibleBy(T) == false}.
+ * @throws UnsupportedOperationException if {@code charset} is not a {@linkplain StandardCharsets standard charset}.
+ */
+ default void setString(long offset, String str, Charset charset) {
+ Objects.requireNonNull(charset);
+ Objects.requireNonNull(str);
+ StringSupport.write(this, offset, charset, str);
+ }
/**
* Creates a memory segment that is backed by the same region of memory that backs the given {@link Buffer} instance.
* The segment starts relative to the buffer's position (inclusive) and ends relative to the buffer's limit (exclusive).
* <p>
* such that {@code srcSegment.isAccessibleBy(T) == false}.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code dstSegment.isAccessibleBy(T) == false}.
! * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - bytes} or if
! * {@code dstOffset > dstSegment.byteSize() - bytes}, or if either {@code srcOffset}, {@code dstOffset}
* or {@code bytes} are {@code < 0}.
* @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
static void copy(MemorySegment srcSegment, long srcOffset,
* such that {@code srcSegment.isAccessibleBy(T) == false}.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code dstSegment.isAccessibleBy(T) == false}.
! * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - bytes}.
! * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - bytes}.
+ * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset}
* or {@code bytes} are {@code < 0}.
* @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
static void copy(MemorySegment srcSegment, long srcOffset,
* @param dstElementLayout the element layout associated with the destination segment.
* @param dstOffset the starting offset, in bytes, of the destination segment.
* @param elementCount the number of elements to be copied.
* @throws IllegalArgumentException if the element layouts have different sizes, if the source (resp. destination) segment/offset are
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the source
! * (resp. destination) element layout, or if the source (resp. destination) element layout alignment is greater than its size.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
! * such that {@code srcSegment().isAccessibleBy(T) == false}.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
! * such that {@code dstSegment().isAccessibleBy(T) == false}.
* @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
! * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} or {@code elementCount * dtsLayout.byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - (elementCount * dstLayout.byteSize())}.
* @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset} or {@code elementCount} are {@code < 0}.
*/
@ForceInline
static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset,
* @param dstElementLayout the element layout associated with the destination segment.
* @param dstOffset the starting offset, in bytes, of the destination segment.
* @param elementCount the number of elements to be copied.
* @throws IllegalArgumentException if the element layouts have different sizes, if the source (resp. destination) segment/offset are
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the source
! * (resp. destination) element layout.
+ * @throws IllegalArgumentException if {@code srcElementLayout.byteAlignment() > srcElementLayout.byteSize()}.
+ * @throws IllegalArgumentException if {@code dstElementLayout.byteAlignment() > dstElementLayout.byteSize()}.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
! * such that {@code srcSegment.isAccessibleBy(T) == false}.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
! * such that {@code dstSegment.isAccessibleBy(T) == false}.
* @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
! * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} overflows.
+ * @throws IndexOutOfBoundsException if {@code elementCount * dtsLayout.byteSize()} overflows.
+ * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - (elementCount * srcLayout.byteSize())}.
* @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - (elementCount * dstLayout.byteSize())}.
* @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset} or {@code elementCount} are {@code < 0}.
*/
@ForceInline
static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset,
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default byte get(ValueLayout.OfByte layout, long offset) {
! return (byte) ((ValueLayouts.OfByteImpl) layout).accessHandle().get(this, offset);
}
/**
* Writes a byte into this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default byte get(ValueLayout.OfByte layout, long offset) {
! return (byte) layout.varHandle().get(this, offset);
}
/**
* Writes a byte into this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfByte layout, long offset, byte value) {
! ((ValueLayouts.OfByteImpl) layout).accessHandle().set(this, offset, value);
}
/**
* Reads a boolean from this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfByte layout, long offset, byte value) {
! layout.varHandle().set(this, offset, value);
}
/**
* Reads a boolean from this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default boolean get(ValueLayout.OfBoolean layout, long offset) {
! return (boolean) ((ValueLayouts.OfBooleanImpl) layout).accessHandle().get(this, offset);
}
/**
* Writes a boolean into this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default boolean get(ValueLayout.OfBoolean layout, long offset) {
! return (boolean) layout.varHandle().get(this, offset);
}
/**
* Writes a boolean into this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfBoolean layout, long offset, boolean value) {
! ((ValueLayouts.OfBooleanImpl) layout).accessHandle().set(this, offset, value);
}
/**
* Reads a char from this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfBoolean layout, long offset, boolean value) {
! layout.varHandle().set(this, offset, value);
}
/**
* Reads a char from this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default char get(ValueLayout.OfChar layout, long offset) {
! return (char) ((ValueLayouts.OfCharImpl) layout).accessHandle().get(this, offset);
}
/**
* Writes a char into this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default char get(ValueLayout.OfChar layout, long offset) {
! return (char) layout.varHandle().get(this, offset);
}
/**
* Writes a char into this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfChar layout, long offset, char value) {
! ((ValueLayouts.OfCharImpl) layout).accessHandle().set(this, offset, value);
}
/**
* Reads a short from this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfChar layout, long offset, char value) {
! layout.varHandle().set(this, offset, value);
}
/**
* Reads a short from this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default short get(ValueLayout.OfShort layout, long offset) {
! return (short) ((ValueLayouts.OfShortImpl) layout).accessHandle().get(this, offset);
}
/**
* Writes a short into this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default short get(ValueLayout.OfShort layout, long offset) {
! return (short) layout.varHandle().get(this, offset);
}
/**
* Writes a short into this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfShort layout, long offset, short value) {
! ((ValueLayouts.OfShortImpl) layout).accessHandle().set(this, offset, value);
}
/**
* Reads an int from this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfShort layout, long offset, short value) {
! layout.varHandle().set(this, offset, value);
}
/**
* Reads an int from this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default int get(ValueLayout.OfInt layout, long offset) {
! return (int) ((ValueLayouts.OfIntImpl) layout).accessHandle().get(this, offset);
}
/**
* Writes an int into this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default int get(ValueLayout.OfInt layout, long offset) {
! return (int) layout.varHandle().get(this, offset);
}
/**
* Writes an int into this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfInt layout, long offset, int value) {
! ((ValueLayouts.OfIntImpl) layout).accessHandle().set(this, offset, value);
}
/**
* Reads a float from this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfInt layout, long offset, int value) {
! layout.varHandle().set(this, offset, value);
}
/**
* Reads a float from this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default float get(ValueLayout.OfFloat layout, long offset) {
! return (float)((ValueLayouts.OfFloatImpl) layout).accessHandle().get(this, offset);
}
/**
* Writes a float into this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default float get(ValueLayout.OfFloat layout, long offset) {
! return (float)layout.varHandle().get(this, offset);
}
/**
* Writes a float into this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfFloat layout, long offset, float value) {
! ((ValueLayouts.OfFloatImpl) layout).accessHandle().set(this, offset, value);
}
/**
* Reads a long from this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfFloat layout, long offset, float value) {
! layout.varHandle().set(this, offset, value);
}
/**
* Reads a long from this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default long get(ValueLayout.OfLong layout, long offset) {
! return (long) ((ValueLayouts.OfLongImpl) layout).accessHandle().get(this, offset);
}
/**
* Writes a long into this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default long get(ValueLayout.OfLong layout, long offset) {
! return (long) layout.varHandle().get(this, offset);
}
/**
* Writes a long into this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfLong layout, long offset, long value) {
! ((ValueLayouts.OfLongImpl) layout).accessHandle().set(this, offset, value);
}
/**
* Reads a double from this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfLong layout, long offset, long value) {
! layout.varHandle().set(this, offset, value);
}
/**
* Reads a double from this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default double get(ValueLayout.OfDouble layout, long offset) {
! return (double) ((ValueLayouts.OfDoubleImpl) layout).accessHandle().get(this, offset);
}
/**
* Writes a double into this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default double get(ValueLayout.OfDouble layout, long offset) {
! return (double) layout.varHandle().get(this, offset);
}
/**
* Writes a double into this segment at the given offset, with the given layout.
*
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfDouble layout, long offset, double value) {
! ((ValueLayouts.OfDoubleImpl) layout).accessHandle().set(this, offset, value);
}
/**
* Reads an address from this segment at the given offset, with the given layout. The read address is wrapped in
! * a native segment, associated with a fresh scope that is always alive. Under normal conditions,
* the size of the returned segment is {@code 0}. However, if the provided address layout has a
* {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
* is set to {@code T.byteSize()}.
* @param layout the layout of the region of memory to be read.
* @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void set(ValueLayout.OfDouble layout, long offset, double value) {
! layout.varHandle().set(this, offset, value);
}
/**
* Reads an address from this segment at the given offset, with the given layout. The read address is wrapped in
! * a native segment, associated with a scope that is always alive. Under normal conditions,
* the size of the returned segment is {@code 0}. However, if the provided address layout has a
* {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
* is set to {@code T.byteSize()}.
* @param layout the layout of the region of memory to be read.
* @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default MemorySegment get(AddressLayout layout, long offset) {
! return (MemorySegment) ((ValueLayouts.OfAddressImpl) layout).accessHandle().get(this, offset);
}
/**
* Writes an address into this segment at the given offset, with the given layout.
*
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
*/
@ForceInline
default MemorySegment get(AddressLayout layout, long offset) {
! return (MemorySegment) layout.varHandle().get(this, offset);
}
/**
* Writes an address into this segment at the given offset, with the given layout.
*
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
* @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
*/
@ForceInline
default void set(AddressLayout layout, long offset, MemorySegment value) {
! ((ValueLayouts.OfAddressImpl) layout).accessHandle().set(this, offset, value);
}
/**
* Reads a byte from this segment at the given index, scaled by the given layout size.
*
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
* @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
*/
@ForceInline
default void set(AddressLayout layout, long offset, MemorySegment value) {
! layout.varHandle().set(this, offset, value);
}
/**
* Reads a byte from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default byte getAtIndex(ValueLayout.OfByte layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (byte) ((ValueLayouts.OfByteImpl) layout).accessHandle().get(this, index * layout.byteSize());
}
/**
* Reads a boolean from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default byte getAtIndex(ValueLayout.OfByte layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (byte) layout.varHandle().get(this, index * layout.byteSize());
}
/**
* Reads a boolean from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default boolean getAtIndex(ValueLayout.OfBoolean layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (boolean) ((ValueLayouts.OfBooleanImpl) layout).accessHandle().get(this, index * layout.byteSize());
}
/**
* Reads a char from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default boolean getAtIndex(ValueLayout.OfBoolean layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (boolean) layout.varHandle().get(this, index * layout.byteSize());
}
/**
* Reads a char from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default char getAtIndex(ValueLayout.OfChar layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (char) ((ValueLayouts.OfCharImpl) layout).accessHandle().get(this, index * layout.byteSize());
}
/**
* Writes a char into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default char getAtIndex(ValueLayout.OfChar layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (char) layout.varHandle().get(this, index * layout.byteSize());
}
/**
* Writes a char into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfChar layout, long index, char value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! ((ValueLayouts.OfCharImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads a short from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfChar layout, long index, char value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! layout.varHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads a short from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default short getAtIndex(ValueLayout.OfShort layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (short) ((ValueLayouts.OfShortImpl) layout).accessHandle().get(this, index * layout.byteSize());
}
/**
* Writes a byte into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default short getAtIndex(ValueLayout.OfShort layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (short) layout.varHandle().get(this, index * layout.byteSize());
}
/**
* Writes a byte into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfByte layout, long index, byte value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! ((ValueLayouts.OfByteImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
}
/**
* Writes a boolean into this segment at the given index, scaled by the given layout size.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfByte layout, long index, byte value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! layout.varHandle().set(this, index * layout.byteSize(), value);
}
/**
* Writes a boolean into this segment at the given index, scaled by the given layout size.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! ((ValueLayouts.OfBooleanImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
}
/**
* Writes a short into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! layout.varHandle().set(this, index * layout.byteSize(), value);
}
/**
* Writes a short into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfShort layout, long index, short value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! ((ValueLayouts.OfShortImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads an int from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfShort layout, long index, short value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! layout.varHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads an int from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default int getAtIndex(ValueLayout.OfInt layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (int) ((ValueLayouts.OfIntImpl) layout).accessHandle().get(this, index * layout.byteSize());
}
/**
* Writes an int into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default int getAtIndex(ValueLayout.OfInt layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (int) layout.varHandle().get(this, index * layout.byteSize());
}
/**
* Writes an int into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfInt layout, long index, int value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! ((ValueLayouts.OfIntImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads a float from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfInt layout, long index, int value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! layout.varHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads a float from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default float getAtIndex(ValueLayout.OfFloat layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (float) ((ValueLayouts.OfFloatImpl) layout).accessHandle().get(this, index * layout.byteSize());
}
/**
* Writes a float into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default float getAtIndex(ValueLayout.OfFloat layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (float) layout.varHandle().get(this, index * layout.byteSize());
}
/**
* Writes a float into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! ((ValueLayouts.OfFloatImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads a long from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! layout.varHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads a long from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default long getAtIndex(ValueLayout.OfLong layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (long) ((ValueLayouts.OfLongImpl) layout).accessHandle().get(this, index * layout.byteSize());
}
/**
* Writes a long into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default long getAtIndex(ValueLayout.OfLong layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (long) layout.varHandle().get(this, index * layout.byteSize());
}
/**
* Writes a long into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfLong layout, long index, long value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! ((ValueLayouts.OfLongImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads a double from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfLong layout, long index, long value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! layout.varHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads a double from this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default double getAtIndex(ValueLayout.OfDouble layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (double) ((ValueLayouts.OfDoubleImpl) layout).accessHandle().get(this, index * layout.byteSize());
}
/**
* Writes a double into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default double getAtIndex(ValueLayout.OfDouble layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (double) layout.varHandle().get(this, index * layout.byteSize());
}
/**
* Writes a double into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! ((ValueLayouts.OfDoubleImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads an address from this segment at the given at the given index, scaled by the given layout size. The read address is wrapped in
! * a native segment, associated with a fresh scope that is always alive. Under normal conditions,
* the size of the returned segment is {@code 0}. However, if the provided address layout has a
* {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
* is set to {@code T.byteSize()}.
* @param layout the layout of the region of memory to be read.
* @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
*/
@ForceInline
default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! layout.varHandle().set(this, index * layout.byteSize(), value);
}
/**
* Reads an address from this segment at the given at the given index, scaled by the given layout size. The read address is wrapped in
! * a native segment, associated with a scope that is always alive. Under normal conditions,
* the size of the returned segment is {@code 0}. However, if the provided address layout has a
* {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
* is set to {@code T.byteSize()}.
* @param layout the layout of the region of memory to be read.
* @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout}
* {@code T}, and the address of the returned segment
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default MemorySegment getAtIndex(AddressLayout layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (MemorySegment) ((ValueLayouts.OfAddressImpl) layout).accessHandle().get(this, index * layout.byteSize());
}
/**
* Writes an address into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout}
* {@code T}, and the address of the returned segment
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
*/
@ForceInline
default MemorySegment getAtIndex(AddressLayout layout, long index) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! return (MemorySegment) layout.varHandle().get(this, index * layout.byteSize());
}
/**
* Writes an address into this segment at the given index, scaled by the given layout size.
*
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
! * or if the layout alignment is greater than its size.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
* @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
*/
@ForceInline
default void setAtIndex(AddressLayout layout, long index, MemorySegment value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! ((ValueLayouts.OfAddressImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
}
/**
* Compares the specified object with this memory segment for equality. Returns {@code true} if and only if the specified
* object is also a memory segment, and if the two segments refer to the same location, in some region of memory.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
* such that {@code isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if the access operation is
! * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
! * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
* @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
*/
@ForceInline
default void setAtIndex(AddressLayout layout, long index, MemorySegment value) {
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
! layout.varHandle().set(this, index * layout.byteSize(), value);
}
/**
* Compares the specified object with this memory segment for equality. Returns {@code true} if and only if the specified
* object is also a memory segment, and if the two segments refer to the same location, in some region of memory.
* @param dstIndex the starting index of the destination array.
* @param elementCount the number of array elements to be copied.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
! * such that {@code srcSegment().isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported.
* @throws IllegalArgumentException if the destination array component type does not match {@code srcLayout.carrier()}.
* @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
* with the alignment constraint</a> in the source element layout.
* @throws IllegalArgumentException if {@code srcLayout.byteAlignment() > srcLayout.byteSize()}.
* @param dstIndex the starting index of the destination array.
* @param elementCount the number of array elements to be copied.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
! * such that {@code srcSegment.isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported.
* @throws IllegalArgumentException if the destination array component type does not match {@code srcLayout.carrier()}.
* @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
* with the alignment constraint</a> in the source element layout.
* @throws IllegalArgumentException if {@code srcLayout.byteAlignment() > srcLayout.byteSize()}.
* @param dstOffset the starting offset, in bytes, of the destination segment.
* @param elementCount the number of array elements to be copied.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
! * such that {@code dstSegment().isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported.
* @throws IllegalArgumentException if the source array component type does not match {@code srcLayout.carrier()}.
* @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
* with the alignment constraint</a> in the source element layout.
* @throws IllegalArgumentException if {@code dstLayout.byteAlignment() > dstLayout.byteSize()}.
* @param dstOffset the starting offset, in bytes, of the destination segment.
* @param elementCount the number of array elements to be copied.
* @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
* {@linkplain Scope#isAlive() alive}.
* @throws WrongThreadException if this method is called from a thread {@code T},
! * such that {@code dstSegment.isAccessibleBy(T) == false}.
* @throws IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported.
* @throws IllegalArgumentException if the source array component type does not match {@code srcLayout.carrier()}.
* @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
* with the alignment constraint</a> in the source element layout.
* @throws IllegalArgumentException if {@code dstLayout.byteAlignment() > dstLayout.byteSize()}.
* cannot be accessed if its associated scope is not {@linkplain #isAlive() alive}. A new scope is typically
* obtained indirectly, by creating a new {@linkplain Arena arena}.
* <p>
* Scope instances can be compared for equality. That is, two scopes
* are considered {@linkplain #equals(Object)} if they denote the same lifetime.
*/
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
sealed interface Scope permits MemorySessionImpl {
/**
* {@return {@code true}, if the regions of memory backing the memory segments associated with this scope are
* still valid}
*/
* cannot be accessed if its associated scope is not {@linkplain #isAlive() alive}. A new scope is typically
* obtained indirectly, by creating a new {@linkplain Arena arena}.
* <p>
* Scope instances can be compared for equality. That is, two scopes
* are considered {@linkplain #equals(Object)} if they denote the same lifetime.
+ * <p>
+ * If two memory segments are obtained from the same {@linkplain #ofBuffer(Buffer) buffer}
+ * or {@linkplain #ofArray(int[]) array}, the scopes associated with said segments are considered
+ * {@linkplain #equals(Object) equal}, as the two segments have the same lifetime:
+ * {@snippet lang=java :
+ * byte[] arr = new byte[10];
+ * MemorySegment segment1 = MemorySegment.ofArray(arr);
+ * MemorySegment segment2 = MemorySegment.ofArray(arr);
+ * assert segment1.scope().equals(segment2.scope());
+ * }
+ * <p>
+ * If two distinct memory segments are <a href="#wrapping-addresses">zero-length memory segments</a>, their scopes
+ * are always considered {@linkplain #equals(Object) equal}:
+ * {@snippet lang=java :
+ * MemorySegment segment1 = MemorySegment.ofAddress(42L);
+ * MemorySegment segment2 = MemorySegment.ofAddress(1000L);
+ * assert segment1.scope().equals(segment2.scope());
+ * }
+ * The scope of a zero-length memory segment can always be overridden using the
+ * {@link MemorySegment#reinterpret(Arena, Consumer)} method.
*/
sealed interface Scope permits MemorySessionImpl {
/**
* {@return {@code true}, if the regions of memory backing the memory segments associated with this scope are
* still valid}
*/
< prev index next >