JDK-8219608 : (bf) Add ByteBuffer.slice(int index, int length)
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.nio
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 13
  • Submitted: 2019-02-22
  • Updated: 2019-03-04
  • Resolved: 2019-02-27
Related Reports
CSR :  
Description
Summary
-------

Add a slice method to Buffer and its type specific subclasses to create a subsequence given an absolute position and size.

Problem
-------

The `java.nio.Buffer` and `java.nio.$Type$Buffer` classes, where $Type$ is in {Byte, Char, Double, Float, Int, Long, Short}, currently define a `slice()` method to create a sub-sequence of the buffer delimited by the current position and limit. There is however no method to create such a view defined by an absolute position and size. This is asymmetric with the `put()` and `get()` methods which both have variants which use the absolute position.

Solution
--------

Add a `slice(int,int)` which which creates a sub-sequence of a specified size at a specified absolute offset. The only API changes are to the `java.nio.*Buffer` classes.

`java.nio.Buffer`

Modify "additional operations" section of class-level javadoc:

```
@@ -134,8 +134,9 @@
  *   it already contains: It leaves the limit unchanged and sets the position
  *   to zero.  </p></li>
  *
- *   <li><p> {@link #slice} creates a subsequence of a buffer: It leaves the
- *   limit and the position unchanged. </p></li>
+ *   <li><p> The {@link #slice} and {@link #slice(int,int) slice(index,length)}
+ *   methods create a subsequence of a buffer: They leave the limit and the
+ *   position unchanged. </p></li>
  *
  *   <li><p> {@link #duplicate} creates a shallow copy of a buffer: It leaves
  *   the limit and the position unchanged. </p></li>
@
```
Method specification:

```
/**
     * Creates a new buffer whose content is a shared subsequence of
     * this buffer's content.
     *
     * <p> The content of the new buffer will start at position {@code index}
     * in this buffer, and will contain {@code length} elements. Changes to
     * this buffer's content will be visible in the new buffer, and vice versa;
     * the two buffers' position, limit, and mark values will be independent.
     *
     * <p> The new buffer's position will be zero, its capacity and its limit
     * will be {@code length}, its mark will be undefined. The new buffer will
     * be direct if, and only if, this buffer is direct, and it will be
     * read-only if, and only if, this buffer is read-only.  </p>
     *
     * @param   index
     *          The position in this buffer at which the content of the new
     *          buffer will start; must be non-negative and no larger than
     *          {@link #limit() limit()}
     *
     * @param   length
     *          The number of elements the new buffer will contain; must be
     *          non-negative and no larger than {@code limit() - index}
     *
     * @return  The new buffer
     *
     * @throws  IndexOutOfBoundsException
     *          If {@code index} is negative or greater than {@code limit()},
     *          {@code length} is negative, or {@code length > limit() - index}
     *
     * @since 13
     */
    public abstract Buffer slice(int index, int length);
```

`java.nio.$Type$Buffer`

For `java.nio.$TypeBuffer$`, $Type$ is in {Byte, Char, Double, Float, Int, Short} and, respectively, $type$ is in {byte, char, double, float, int, short}.
```
    /**
     * Creates a new $type$ buffer whose content is a shared subsequence of
     * this buffer's content.
     *
     * <p> The content of the new buffer will start at position {@code index}
     * in this buffer, and will contain {@code length} elements. Changes to
     * this buffer's content will be visible in the new buffer, and vice versa;
     * the two buffers' position, limit, and mark values will be independent.
     *
     * <p> The new buffer's position will be zero, its capacity and its limit
     * will be {@code length}, its mark will be undefined, and its byte order
     * will be
#if[byte]
     * {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
#else[byte]
     * identical to that of this buffer.
#end[byte]
     * The new buffer will be direct if, and only if, this buffer is direct,
     * and it will be read-only if, and only if, this buffer is read-only. </p>
     *
     * @param   index
     *          The position in this buffer at which the content of the new
     *          buffer will start; must be non-negative and no larger than
     *          {@link #limit() limit()}
     *
     * @param   length
     *          The number of elements the new buffer will contain; must be
     *          non-negative and no larger than {@code limit() - index}
     *
     * @return  The new buffer
     *
     * @throws  IndexOutOfBoundsException
     *          If {@code index} is negative or greater than {@code limit()},
     *          {@code length} is negative, or {@code length > limit() - index}
     *
     * @since 13
     */
    @Override
    public abstract $Type$Buffer slice(int index, int length);
```
Comments
[~bpb] Thanks for clarification
04-03-2019

[~kganapureddy] The situation index == limit(), length == 0 is supposed to be acceptable, i.e., a zero length slice.
04-03-2019

[~bpb] I see a typo in the IndexOutofBoundException description , where it says "If {@code index} is negative or greater than {@code limit()}, " I believe it should be "If {@code index} is negative or not smaller than {@code limit()}, the current description does not hold good if the index == limit. Please clarify.
04-03-2019

Moving to Approved.
27-02-2019