@@ -1296,12 +1296,7 @@ MemorySegment reinterpret(long newSize,
12961296 * over the decoding process is required.
12971297 * <p>
12981298 * Getting a string from a segment with a known byte offset and
1299- * known byte length can be done like so:
1300- * {@snippet lang=java :
1301- * byte[] bytes = new byte[length];
1302- * MemorySegment.copy(segment, JAVA_BYTE, offset, bytes, 0, length);
1303- * return new String(bytes, charset);
1304- * }
1299+ * known byte length can be done using {@link #getString(long, Charset, long)}.
13051300 *
13061301 * @param offset offset in bytes (relative to this segment address) at which this
13071302 * access operation will occur
@@ -1328,6 +1323,40 @@ MemorySegment reinterpret(long newSize,
13281323 */
13291324 String getString (long offset , Charset charset );
13301325
1326+ /**
1327+ * Reads a string from this segment at the given offset, using the provided length
1328+ * and charset.
1329+ * <p>
1330+ * This method always replaces malformed-input and unmappable-character
1331+ * sequences with this charset's default replacement string. The {@link
1332+ * java.nio.charset.CharsetDecoder} class should be used when more control
1333+ * over the decoding process is required.
1334+ * <p>
1335+ * If the string contains any {@code '\0'} characters, they will be read as well.
1336+ * This differs from {@link #getString(long, Charset)}, which will only read up
1337+ * to the first {@code '\0'}, resulting in truncation for string data that contains
1338+ * the {@code '\0'} character.
1339+ *
1340+ * @param offset offset in bytes (relative to this segment address) at which this
1341+ * access operation will occur
1342+ * @param charset the charset used to {@linkplain Charset#newDecoder() decode} the
1343+ * string bytes
1344+ * @param byteLength length, in bytes, of the region of memory to read and decode into
1345+ * a string
1346+ * @return a Java string constructed from the bytes read from the given starting
1347+ * address up to the given length
1348+ * @throws IllegalArgumentException if the size of the string is greater than the
1349+ * largest string supported by the platform
1350+ * @throws IndexOutOfBoundsException if {@code offset < 0}
1351+ * @throws IndexOutOfBoundsException if {@code offset > byteSize() - byteLength}
1352+ * @throws IllegalStateException if the {@linkplain #scope() scope} associated with
1353+ * this segment is not {@linkplain Scope#isAlive() alive}
1354+ * @throws WrongThreadException if this method is called from a thread {@code T},
1355+ * such that {@code isAccessibleBy(T) == false}
1356+ * @throws IllegalArgumentException if {@code byteLength < 0}
1357+ */
1358+ String getString (long offset , Charset charset , long byteLength );
1359+
13311360 /**
13321361 * Writes the given string into this segment at the given offset, converting it to
13331362 * a null-terminated byte sequence using the {@linkplain StandardCharsets#UTF_8 UTF-8}
@@ -1366,7 +1395,8 @@ MemorySegment reinterpret(long newSize,
13661395 * If the given string contains any {@code '\0'} characters, they will be
13671396 * copied as well. This means that, depending on the method used to read
13681397 * the string, such as {@link MemorySegment#getString(long)}, the string
1369- * will appear truncated when read again.
1398+ * will appear truncated when read again. The string can be read without
1399+ * truncation using {@link #getString(long, Charset, long)}.
13701400 *
13711401 * @param offset offset in bytes (relative to this segment address) at which this
13721402 * access operation will occur, the final address of this write
@@ -2606,6 +2636,50 @@ static void copy(Object srcArray, int srcIndex,
26062636 elementCount );
26072637 }
26082638
2639+ /**
2640+ * Copies the byte sequence of the given string encoded using the provided charset
2641+ * to the destination segment.
2642+ * <p>
2643+ * This method always replaces malformed-input and unmappable-character
2644+ * sequences with this charset's default replacement string. The {@link
2645+ * java.nio.charset.CharsetDecoder} class should be used when more control
2646+ * over the decoding process is required.
2647+ * <p>
2648+ * If the given string contains any {@code '\0'} characters, they will be
2649+ * copied as well. This means that, depending on the method used to read
2650+ * the string, such as {@link MemorySegment#getString(long)}, the string
2651+ * will appear truncated when read again. The string can be read without
2652+ * truncation using {@link #getString(long, Charset, long)}.
2653+ *
2654+ * @param src the Java string to be written into the destination segment
2655+ * @param dstEncoding the charset used to {@linkplain Charset#newEncoder() encode}
2656+ * the string bytes.
2657+ * @param srcIndex the starting character index of the source string
2658+ * @param dst the destination segment
2659+ * @param dstOffset the starting offset, in bytes, of the destination segment
2660+ * @param numChars the number of characters to be copied
2661+ * @throws IllegalStateException if the {@linkplain #scope() scope} associated with
2662+ * {@code dst} is not {@linkplain Scope#isAlive() alive}
2663+ * @throws WrongThreadException if this method is called from a thread {@code T},
2664+ * such that {@code dst.isAccessibleBy(T) == false}
2665+ * @throws IndexOutOfBoundsException if either {@code srcIndex}, {@code numChars}, or {@code dstOffset}
2666+ * are {@code < 0}
2667+ * @throws IndexOutOfBoundsException if {@code srcIndex > src.length() - numChars}
2668+ * @throws IllegalArgumentException if {@code dst} is {@linkplain #isReadOnly() read-only}
2669+ * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - B} where {@code B} is the size,
2670+ * in bytes, of the substring of {@code src} encoded using the given charset
2671+ * @return the number of copied bytes.
2672+ */
2673+ @ ForceInline
2674+ static long copy (String src , Charset dstEncoding , int srcIndex , MemorySegment dst , long dstOffset , int numChars ) {
2675+ Objects .requireNonNull (src );
2676+ Objects .requireNonNull (dstEncoding );
2677+ Objects .requireNonNull (dst );
2678+ Objects .checkFromIndexSize (srcIndex , numChars , src .length ());
2679+
2680+ return AbstractMemorySegmentImpl .copy (src , dstEncoding , srcIndex , dst , dstOffset , numChars );
2681+ }
2682+
26092683 /**
26102684 * Finds and returns the relative offset, in bytes, of the first mismatch between the
26112685 * source and the destination segments. More specifically, the bytes at offset
0 commit comments