jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template
changeset 36933 3e6453e2d833
parent 35302 e4d2275861c3
child 38321 ff5b89346438
equal deleted inserted replaced
36930:74e9f4b90006 36933:3e6453e2d833
     1 /*
     1 /*
     2  * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
   267     // reduce the number of virtual method invocations needed to access these
   267     // reduce the number of virtual method invocations needed to access these
   268     // values, which is especially costly when coding small buffers.
   268     // values, which is especially costly when coding small buffers.
   269     //
   269     //
   270     final $type$[] hb;                  // Non-null only for heap buffers
   270     final $type$[] hb;                  // Non-null only for heap buffers
   271     final int offset;
   271     final int offset;
   272     boolean isReadOnly;                 // Valid only for heap buffers
   272     boolean isReadOnly;
   273 
   273 
   274     // Creates a new buffer with the given mark, position, limit, capacity,
   274     // Creates a new buffer with the given mark, position, limit, capacity,
   275     // backing array, and array offset
   275     // backing array, and array offset
   276     //
   276     //
   277     $Type$Buffer(int mark, int pos, int lim, int cap,   // package-private
   277     $Type$Buffer(int mark, int pos, int lim, int cap,   // package-private
   528 #end[byte]
   528 #end[byte]
   529      * The new buffer will be direct if, and only if, this buffer is direct, and
   529      * The new buffer will be direct if, and only if, this buffer is direct, and
   530      * it will be read-only if, and only if, this buffer is read-only.  </p>
   530      * it will be read-only if, and only if, this buffer is read-only.  </p>
   531      *
   531      *
   532      * @return  The new $type$ buffer
   532      * @return  The new $type$ buffer
       
   533 #if[byte]
       
   534      *
       
   535      * @see #alignedSlice(int)
       
   536 #end[byte]
   533      */
   537      */
   534     public abstract $Type$Buffer slice();
   538     public abstract $Type$Buffer slice();
   535 
   539 
   536     /**
   540     /**
   537      * Creates a new $type$ buffer that shares this buffer's content.
   541      * Creates a new $type$ buffer that shares this buffer's content.
  1609         nativeByteOrder =
  1613         nativeByteOrder =
  1610             (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
  1614             (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
  1611         return this;
  1615         return this;
  1612     }
  1616     }
  1613 
  1617 
       
  1618     /**
       
  1619      * Returns the memory address, pointing to the byte at the given index,
       
  1620      * modulus the given unit size.
       
  1621      *
       
  1622      * <p> A return value greater than zero indicates the address of the byte at
       
  1623      * the index is misaligned for the unit size, and the value's quantity
       
  1624      * indicates how much the index should be rounded up or down to locate a
       
  1625      * byte at an aligned address.  Otherwise, a value of {@code 0} indicates
       
  1626      * that the address of the byte at the index is aligned for the unit size.
       
  1627      *
       
  1628      * @apiNote
       
  1629      * This method may be utilized to determine if unit size bytes from an
       
  1630      * index can be accessed atomically, if supported by the native platform.
       
  1631      *
       
  1632      * @implNote
       
  1633      * This implementation throws {@code UnsupportedOperationException} for
       
  1634      * non-direct buffers when the given unit size is greater then {@code 8}.
       
  1635      *
       
  1636      * @param  index
       
  1637      *         The index to query for alignment offset, must be non-negative, no
       
  1638      *         upper bounds check is performed
       
  1639      *
       
  1640      * @param  unitSize
       
  1641      *         The unit size in bytes, must be a power of {@code 2}
       
  1642      *
       
  1643      * @return  The indexed byte's memory address modulus the unit size
       
  1644      *
       
  1645      * @throws IllegalArgumentException
       
  1646      *         If the index is negative or the unit size is not a power of
       
  1647      *         {@code 2}
       
  1648      *
       
  1649      * @throws UnsupportedOperationException
       
  1650      *         If the native platform does not guarantee stable alignment offset
       
  1651      *         values for the given unit size when managing the memory regions
       
  1652      *         of buffers of the same kind as this buffer (direct or
       
  1653      *         non-direct).  For example, if garbage collection would result
       
  1654      *         in the moving of a memory region covered by a non-direct buffer
       
  1655      *         from one location to another and both locations have different
       
  1656      *         alignment characteristics.
       
  1657      *
       
  1658      * @see #alignedSlice(int)
       
  1659      * @since 9
       
  1660      */
       
  1661     public final int alignmentOffset(int index, int unitSize) {
       
  1662         if (index < 0)
       
  1663             throw new IllegalArgumentException("Index less than zero: " + index);
       
  1664         if (unitSize < 1 || (unitSize & (unitSize - 1)) != 0)
       
  1665             throw new IllegalArgumentException("Unit size not a power of two: " + unitSize);
       
  1666         if (unitSize > 8 && !isDirect())
       
  1667             throw new UnsupportedOperationException("Unit size unsupported for non-direct buffers: " + unitSize);
       
  1668 
       
  1669         return (int) ((address + index) % unitSize);
       
  1670     }
       
  1671 
       
  1672     /**
       
  1673      * Creates a new byte buffer whose content is a shared and aligned
       
  1674      * subsequence of this buffer's content.
       
  1675      *
       
  1676      * <p> The content of the new buffer will start at this buffer's current
       
  1677      * position rounded up to the index of the nearest aligned byte for the
       
  1678      * given unit size, and end at this buffer's limit rounded down to the index
       
  1679      * of the nearest aligned byte for the given unit size.
       
  1680      * If rounding results in out-of-bound values then the new buffer's capacity
       
  1681      * and limit will be zero.  If rounding is within bounds the following
       
  1682      * expressions will be true for a new buffer {@code nb} and unit size
       
  1683      * {@code unitSize}:
       
  1684      * <pre>{@code
       
  1685      * nb.alignmentOffset(0, unitSize) == 0
       
  1686      * nb.alignmentOffset(nb.limit(), unitSize) == 0
       
  1687      * }</pre>
       
  1688      *
       
  1689      * <p> Changes to this buffer's content will be visible in the new
       
  1690      * buffer, and vice versa; the two buffers' position, limit, and mark
       
  1691      * values will be independent.
       
  1692      *
       
  1693      * <p> The new buffer's position will be zero, its capacity and its limit
       
  1694      * will be the number of bytes remaining in this buffer or fewer subject to
       
  1695      * alignment, its mark will be undefined, and its byte order will be
       
  1696      * {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
       
  1697      *
       
  1698      * The new buffer will be direct if, and only if, this buffer is direct, and
       
  1699      * it will be read-only if, and only if, this buffer is read-only.  </p>
       
  1700      *
       
  1701      * @apiNote
       
  1702      * This method may be utilized to create a new buffer where unit size bytes
       
  1703      * from index, that is a multiple of the unit size, may be accessed
       
  1704      * atomically, if supported by the native platform.
       
  1705      *
       
  1706      * @implNote
       
  1707      * This implementation throws {@code UnsupportedOperationException} for
       
  1708      * non-direct buffers when the given unit size is greater then {@code 8}.
       
  1709      *
       
  1710      * @param  unitSize
       
  1711      *         The unit size in bytes, must be a power of {@code 2}
       
  1712      *
       
  1713      * @return  The new byte buffer
       
  1714      *
       
  1715      * @throws IllegalArgumentException
       
  1716      *         If the unit size not a power of {@code 2}
       
  1717      *
       
  1718      * @throws UnsupportedOperationException
       
  1719      *         If the native platform does not guarantee stable aligned slices
       
  1720      *         for the given unit size when managing the memory regions
       
  1721      *         of buffers of the same kind as this buffer (direct or
       
  1722      *         non-direct).  For example, if garbage collection would result
       
  1723      *         in the moving of a memory region covered by a non-direct buffer
       
  1724      *         from one location to another and both locations have different
       
  1725      *         alignment characteristics.
       
  1726      *
       
  1727      * @see #alignmentOffset(int, int)
       
  1728      * @see #slice()
       
  1729      * @since 9
       
  1730      */
       
  1731     public final ByteBuffer alignedSlice(int unitSize) {
       
  1732         int pos = position();
       
  1733         int lim = limit();
       
  1734 
       
  1735         int pos_mod = alignmentOffset(pos, unitSize);
       
  1736         int lim_mod = alignmentOffset(lim, unitSize);
       
  1737 
       
  1738         // Round up the position to align with unit size
       
  1739         int aligned_pos = (pos_mod > 0)
       
  1740             ? pos + (unitSize - pos_mod)
       
  1741             : pos;
       
  1742 
       
  1743         // Round down the limit to align with unit size
       
  1744         int aligned_lim = lim - lim_mod;
       
  1745 
       
  1746         if (aligned_pos > lim || aligned_lim < pos) {
       
  1747             aligned_pos = aligned_lim = pos;
       
  1748         }
       
  1749 
       
  1750         return slice(aligned_pos, aligned_lim);
       
  1751     }
       
  1752 
       
  1753     abstract ByteBuffer slice(int pos, int lim);
       
  1754 
  1614     // Unchecked accessors, for use by ByteBufferAs-X-Buffer classes
  1755     // Unchecked accessors, for use by ByteBufferAs-X-Buffer classes
  1615     //
  1756     //
  1616     abstract byte _get(int i);                          // package-private
  1757     abstract byte _get(int i);                          // package-private
  1617     abstract void _put(int i, byte b);                  // package-private
  1758     abstract void _put(int i, byte b);                  // package-private
  1618 
  1759