0001: /*
0002: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0004: *
0005: * This program is free software; you can redistribute it and/or
0006: * modify it under the terms of the GNU General Public License version
0007: * 2 only, as published by the Free Software Foundation.
0008: *
0009: * This program is distributed in the hope that it will be useful, but
0010: * WITHOUT ANY WARRANTY; without even the implied warranty of
0011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0012: * General Public License version 2 for more details (a copy is
0013: * included at /legal/license.txt).
0014: *
0015: * You should have received a copy of the GNU General Public License
0016: * version 2 along with this work; if not, write to the Free Software
0017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0018: * 02110-1301 USA
0019: *
0020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0021: * Clara, CA 95054 or visit www.sun.com if you need additional
0022: * information or have any questions.
0023: */
0024:
0025: package java.nio;
0026:
0027: import com.sun.jsr239.BufferManager;
0028:
0029: /**
0030: * A byte buffer.
0031: *
0032: * <p> This class is provided as part of the JSR 239 NIO Buffer
0033: * building block. It is a subset of the
0034: * <code>java.nio.ByteBuffer</code> class in Java(TM) Standard Edition
0035: * version 1.4.2. Differences are noted in <b><i>bold italic</i></b>.
0036: * The class documentation may make reference to classes that are not
0037: * present in the building block.
0038: *
0039: * <p><b><i> I/O channels, marking and resetting, and read-only buffers
0040: * are not supported. Allocation of non-direct byte buffers,
0041: * compaction, and duplication are not supported. The
0042: * <code>char</code>, <code>long</code>, and <code>double</code>
0043: * datatypes are not supported. The following methods are omitted:
0044: *
0045: * <ul>
0046: * <li><code>ByteBuffer allocate(int capacity)</code></li>
0047: * <li><code>ByteBuffer compact()</code></li>
0048: * <li><code>ByteBuffer duplicate()</code></li>
0049: * <li><code>Buffer mark()</code></li>
0050: * <li><code>Buffer reset()</code></li>
0051: * <li><code>boolean isReadOnly()</code></li>
0052: * <li><code>ByteBuffer asReadOnlyBuffer()</code></li>
0053: * <li><code>CharBuffer asCharBuffer()</code></li>
0054: * <li><code>LongBuffer asLongBuffer()</code></li>
0055: * <li><code>DoubleBuffer asDoubleBuffer()</code></li>
0056: * <li><code>char getChar()</code></li>
0057: * <li><code>char getChar(int index)</code></li>
0058: * <li><code>long getLong()</code></li>
0059: * <li><code>long getLong(int index)</code></li>
0060: * <li><code>double getDouble()</code></li>
0061: * <li><code>double getDouble(int index)</code></li>
0062: * <li><code>ByteBuffer putChar(char value)</code></li>
0063: * <li><code>ByteBuffer putChar(int index, char value)</code></li>
0064: * <li><code>ByteBuffer putLong(int index, long value)</code></li>
0065: * <li><code>ByteBuffer putLong(long value)</code></li>
0066: * <li><code>ByteBuffer putDouble(double value)</code></li>
0067: * <li><code>ByteBuffer putDouble(int index, double value)</code></li>
0068: * </ul>
0069: * </i></b>
0070: *
0071: * <p> This class defines six categories of operations upon
0072: * byte buffers:
0073: *
0074: * <ul>
0075: *
0076: * <li><p> Absolute and relative <A
0077: * HREF="ByteBuffer.html#get()"><CODE></code><i>get</i><code></CODE></A>
0078: * and <A
0079: * HREF="ByteBuffer.html#put(byte)"><CODE></code><i>put</i><code></CODE></A>
0080: * methods that read and write single bytes; </p></li>
0081: *
0082: * <li><p> Relative <A
0083: * HREF="ByteBuffer.html#get(byte[])"><CODE></code><i>bulk
0084: * get</i><code></CODE></A> methods that transfer contiguous
0085: * sequences of bytes from this buffer into an array; </p></li>
0086: *
0087: * <li><p> Relative <A
0088: * HREF="ByteBuffer.html#put(byte[])"><CODE></code><i>bulk
0089: * put</i><code></CODE></A> methods that transfer contiguous
0090: * sequences of bytes from a byte array or some other byte buffer
0091: * into this buffer; </p></li>
0092: *
0093: * <li><p> Absolute and relative <i>get</i> and <i>put</i> methods
0094: * that read and write values of other primitive types, translating
0095: * them to and from sequences of bytes in a particular byte order;
0096: * <b><i>JSR 239 does not support certain multi-byte </i>get<i> and
0097: * </i>put<i> methods.</i></b> </p></li>
0098: *
0099: * <li><p> Methods for creating <i><a href="#views">view
0100: * buffers</a></i>, which allow a byte buffer to be viewed as a
0101: * buffer containing values of some other primitive type; and
0102: * </p></li>
0103: *
0104: * <li><p> Methods for compacting, duplicating, and <A
0105: * HREF="ByteBuffer.html#slice()"><CODE></code>slicing<code></CODE></A>
0106: * a byte buffer. <b><i>JSR 239 does not support compacting and
0107: * duplicating buffers.</i></b> </p></li>
0108: *
0109: * </ul>
0110: *
0111: * <p> Byte buffers can be created either by <A
0112: * HREF="ByteBuffer.html#allocateDirect(int)"><CODE></code><i>allocation</i><code></CODE></A>,
0113: * which allocates space for the buffer's content, or by <A
0114: * HREF="ByteBuffer.html#wrap(byte[])"><CODE></code><i>wrapping</i><code></CODE></A>
0115: * an existing byte array into a buffer.
0116: *
0117: * <a name="direct">
0118: * <h4> Direct <i>vs.</i> non-direct buffers </h4>
0119: *
0120: * <p> A byte buffer is either <i>direct</i> or <i>non-direct</i>.
0121: * Given a direct byte buffer, the Java virtual machine will make a
0122: * best effort to perform native I/O operations directly upon it.
0123: * That is, it will attempt to avoid copying the buffer's content to
0124: * (or from) an intermediate buffer before (or after) each invocation
0125: * of one of the underlying operating system's native I/O operations.
0126: *
0127: * <p> A direct byte buffer may be created by invoking the <A
0128: * HREF="ByteBuffer.html#allocateDirect(int)"><CODE>allocateDirect</CODE></A>
0129: * factory method of this class. The buffers returned by this method
0130: * typically have somewhat higher allocation and deallocation costs
0131: * than non-direct buffers. The contents of direct buffers may reside
0132: * outside of the normal garbage-collected heap, and so their impact
0133: * upon the memory footprint of an application might not be obvious.
0134: * It is therefore recommended that direct buffers be allocated
0135: * primarily for large, long-lived buffers that are subject to the
0136: * underlying system's native I/O operations. In general it is best
0137: * to allocate direct buffers only when they yield a measureable gain
0138: * in program performance. <b><i>Certain JSR 239 methods require the
0139: * use of direct buffers.</i></b>
0140: *
0141: * <b><i>JSR 239 does not support the techniques described in the
0142: * remainder of this paragraph.</i></b>
0143: * <p> A direct byte buffer may also be created by mapping a region of
0144: * a file directly into memory. An implementation of the Java
0145: * platform may optionally support the creation of direct byte buffers
0146: * from native code via JNI. If an instance of one of these kinds of
0147: * buffers refers to an inaccessible region of memory then an attempt
0148: * to access that region will not change the buffer's content and will
0149: * cause an unspecified exception to be thrown either at the time of
0150: * the access or at some later time.
0151: *
0152: * <p> Whether a byte buffer is direct or non-direct may be determined
0153: * by invoking its <A
0154: * HREF="ByteBuffer.html#isDirect()"><CODE>isDirect</CODE></A>
0155: * method. This method is provided so that explicit buffer management
0156: * can be done in performance-critical code.
0157: *
0158: * <a name="bin">
0159: * <h4> Access to binary data </h4>
0160: *
0161: * <p> This class defines methods for reading and writing values of
0162: * all other primitive types, except <tt>boolean</tt>,
0163: * <b><i><code>char</code>, <code>long</code>, and
0164: * <code>double</code></i></b>. Primitive values are translated to
0165: * (or from) sequences of bytes according to the buffer's current byte
0166: * order, which may be retrieved and modified via the
0167: * <CODE>order</CODE> methods. Specific byte orders are represented
0168: * by instances of the <CODE>ByteOrder</CODE> class. The initial
0169: * order of a byte buffer is always <CODE>BIG_ENDIAN</CODE>. <b><i>JSR
0170: * 239 does not support the <code>ByteOrder</code> class or the
0171: * <code>order</code> methods. The inital order of a byte buffer is
0172: * the platform byte order.</i></b>
0173: *
0174: * <p> For access to heterogenous binary data, that is, sequences of
0175: * values of different types, this class defines a family of absolute
0176: * and relative <i>get</i> and <i>put</i> methods for each type. For
0177: * 32-bit floating-point values, for example, this class defines:
0178: *
0179: * <blockquote><pre>
0180: *
0181: * float <A HREF="ByteBuffer.html#getFloat()"><CODE>getFloat()</CODE></A>
0182: * float <A HREF="ByteBuffer.html#getFloat(int)"><CODE>getFloat(int index)</CODE></A>
0183: * void <A HREF="ByteBuffer.html#putFloat(float)"><CODE>putFloat(float f)</CODE></A>
0184: * void <A HREF="ByteBuffer.html#putFloat(int, float)"><CODE>putFloat(int index, float f)</CODE></A></pre></blockquote>
0185: *
0186: * <p> Corresponding methods are defined for the types <tt>char</tt>,
0187: * <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and <tt>double</tt>.
0188: * <b><i>JSR 239 does not define the <code>char</code>,
0189: * <code>long</code>, or <code>double</code> methods.</b></i> The
0190: * index parameters of the absolute <i>get</i> and <i>put</i> methods
0191: * are in terms of bytes rather than of the type being read or
0192: * written.
0193: *
0194: * <a name="views">
0195: *
0196: * <p> For access to homogeneous binary data, that is, sequences of
0197: * values of the same type, this class defines methods that can create
0198: * <i>views</i> of a given byte buffer. A <i>view buffer</i> is
0199: * simply another buffer whose content is backed by the byte buffer.
0200: * Changes to the byte buffer's content will be visible in the view
0201: * buffer, and vice versa; the two buffers' position, limit, and mark
0202: * values are independent. The <A
0203: * HREF="ByteBuffer.html#asFloatBuffer()"><CODE>asFloatBuffer</CODE></A>
0204: * method, for example, creates an instance of the <A
0205: * HREF="FloatBuffer.html" title="class in
0206: * java.nio"><CODE>FloatBuffer</CODE></A> class that is backed by the
0207: * byte buffer upon which the method is invoked. Corresponding
0208: * view-creation methods are defined for the types <tt>char</tt>,
0209: * <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and
0210: * <tt>double</tt>. <b><i>JSR 239 does not define views of type
0211: * <code>char</code>, <code>long</code>, or
0212: * <code>double</code>.</i></b>
0213: *
0214: * <p> View buffers have three important advantages over the families of
0215: * type-specific <i>get</i> and <i>put</i> methods described above:
0216: *
0217: * <ul>
0218: *
0219: * <li><p> A view buffer is indexed not in terms of bytes but rather
0220: * in terms of the type-specific size of its values; </p></li>
0221: *
0222: * <li><p> A view buffer provides relative bulk <i>get</i> and
0223: * <i>put</i> methods that can transfer contiguous sequences of
0224: * values between a buffer and an array or some other buffer of the
0225: * same type; and </p></li>
0226: *
0227: * <li><p> A view buffer is potentially much more efficient because
0228: * it will be direct if, and only if, its backing byte buffer is
0229: * direct. </p></li>
0230: *
0231: * </ul>
0232: *
0233: * <p> The byte order of a view buffer is fixed to be that of its byte
0234: * buffer at the time that the view is created. </p>
0235: *
0236: * <h4> Invocation chaining </h4>
0237: *
0238: * <p> Methods in this class that do not otherwise have a value to
0239: * return are specified to return the buffer upon which they are
0240: * invoked. This allows method invocations to be chained.
0241: *
0242: * <p> The sequence of statements
0243: *
0244: * <blockquote><pre>
0245: * bb.putInt(0xCAFEBABE);
0246: * bb.putShort(3);
0247: * bb.putShort(45);
0248: * </pre></blockquote>
0249: * can, for example, be replaced by the single statement
0250: *
0251: * <blockquote><pre>
0252: * bb.putInt(0xCAFEBABE).putShort(3).putShort(45);
0253: * </pre></blockquote>
0254: */
0255: public abstract class ByteBuffer extends Buffer implements Comparable {
0256:
0257: byte[] array;
0258: int arrayOffset;
0259:
0260: boolean isDirect;
0261:
0262: boolean disposed = false;
0263:
0264: /**
0265: * Buffers created by <code>allocateDirect</code> have an
0266: * accosiated buffer allocated in the native Heap. A user may
0267: * create a slice <code>Buffer</code> from a direct "parent"
0268: * <code>Buffer</code> (<code>Buffer.slice()</code>). The "slice" and
0269: * "parent" <code>Buffer</code> share the same native buffer. Native
0270: * buffer is released when the parent <code>Buffer</code> is collected.
0271: * <code>directParent</code> is a reference from slice object to the
0272: * parent. It guarantees that parent object is collected (and shared
0273: * buffer is released) only after all its slice objects are collected.
0274: */
0275: Buffer directParent;
0276:
0277: /**
0278: * Constructs a new <code>ByteBuffer</code>.
0279: */
0280: ByteBuffer() {
0281: }
0282:
0283: /**
0284: * Allocates a new direct byte buffer.
0285: *
0286: * <p> The new buffer's position will be zero, its limit will be
0287: * its capacity, and its mark will be undefined. Whether or not it
0288: * has a backing array is unspecified. <b><i>For JSR 239, the mark
0289: * is undefined, and no backing array will be present.</i></b>.
0290: *
0291: * @param capacity The new buffer's capacity, in bytes.
0292: *
0293: * @return The new byte buffer.
0294: *
0295: * @throws IllegalArgumentException If the <code>capacity</code> is
0296: * a negative integer.
0297: */
0298: public static ByteBuffer allocateDirect(int capacity) {
0299: if (capacity < 0) {
0300: throw new IllegalArgumentException();
0301: }
0302: int nativeAddress = ByteBufferImpl._allocNative(capacity);
0303:
0304: ByteBuffer buf = new ByteBufferImpl(capacity, null,
0305: nativeAddress, null /*directParent is null if direct buffer is a parent itself*/);
0306:
0307: // Record the address of this buffer along with a weak
0308: // reference; if the weak reference becomes null,
0309: // we will free the native heap memory.
0310: BufferManager.newBuffer(buf, nativeAddress);
0311:
0312: return buf;
0313: }
0314:
0315: /**
0316: * Wraps a byte array into a buffer.
0317: *
0318: * <p> The new buffer will be backed by the the given byte array;
0319: * that is, modifications to the buffer will cause the array to be
0320: * modified and vice versa. The new buffer's capacity will be
0321: * <tt>array.length</tt>, its position will be <tt>offset</tt>,
0322: * its limit will be <tt>offset + length</tt>, and its mark will
0323: * be undefined. Its <A
0324: * HREF="ByteBuffer.html#array()"><CODE></code>backing
0325: * array<code></CODE></A> will be the given array, and its <A
0326: * HREF="ByteBuffer.html#arrayOffset()"><CODE></code>array
0327: * offset<code></CODE></A> will be zero. </p>
0328: *
0329: * @param array The array that will back the new buffer
0330: * @param offset The offset of the subarray to be used; must be
0331: * non-negative and no larger than <tt>array.length</tt>. The new
0332: * buffer's position will be set to this value.
0333: * @param length The length of the subarray to be used; must be
0334: * non-negative and no larger than <tt>array.length - offset</tt>.
0335: * The new buffer's limit will be set to <tt>offset + length</tt>.
0336: *
0337: * @return The new byte buffer.
0338: *
0339: * @throws IndexOutOfBoundsException If the preconditions on the
0340: * <tt>offset</tt> and <tt>length</tt> parameters do not hold.
0341: */
0342: public static ByteBuffer wrap(byte[] array, int offset, int length) {
0343: if (offset < 0 || offset > array.length || length < 0
0344: || length > array.length - offset) {
0345: throw new IndexOutOfBoundsException();
0346: }
0347:
0348: ByteBufferImpl bbi = new ByteBufferImpl(array.length, array, 0,
0349: null /*directParent is null for all nondirect buffers*/);
0350: bbi.position(offset);
0351: bbi.limit(offset + length);
0352: return bbi;
0353: }
0354:
0355: /**
0356: * Wraps a byte array into a buffer.
0357: *
0358: * <p> The new buffer will be backed by the the given byte array;
0359: * that is, modifications to the buffer will cause the array to be
0360: * modified and vice versa. The new buffer's capacity and limit
0361: * will be <tt>array.length</tt>, its position will be zero, and
0362: * its mark will be undefined. Its <A
0363: * HREF="ByteBuffer.html#array()"><CODE></code>backing
0364: * array<code></CODE></A> will be the given array, and its <A
0365: * HREF="ByteBuffer.html#arrayOffset()"><CODE></code>array
0366: * offset<code></CODE></A> will be zero. </p>
0367: *
0368: * @param array The array that will back this buffer.
0369: *
0370: * @return The new byte buffer.
0371: */
0372: public static ByteBuffer wrap(byte[] array) {
0373: return wrap(array, 0, array.length);
0374: }
0375:
0376: /**
0377: * Creates a new byte buffer whose content is a shared
0378: * subsequence of this buffer's content.
0379: *
0380: * <p> The content of the new buffer will start at this buffer's
0381: * current position. Changes to this buffer's content will be
0382: * visible in the new buffer, and vice versa; the two buffers'
0383: * position, limit, and mark values will be independent. <b><i>JSR
0384: * 239 does not support the mark.</i></b>
0385: *
0386: * <p> The new buffer's position will be zero, its capacity and
0387: * its limit will be the number of bytes remaining in this
0388: * buffer, and its mark will be undefined. The new buffer will be
0389: * direct if, and only if, this buffer is direct, and it will be
0390: * read-only if, and only if, this buffer is read-only. <b><i>JSR
0391: * 239 does not support the mark or read-only buffers.</i></b>
0392: * </p>
0393: *
0394: * @return The new byte buffer.
0395: */
0396: public abstract ByteBuffer slice();
0397:
0398: /**
0399: * Relative <i>get</i> method. Reads the byte at this
0400: * buffer's current position, and then increments the
0401: * position. </p>
0402: *
0403: * @return The byte at the buffer's current position.
0404: *
0405: * @throws BufferUnderflowException If the buffer's current
0406: * position is not smaller than its limit.
0407: */
0408: public abstract byte get();
0409:
0410: /**
0411: * Relative <i>put</i> method <i>(optional
0412: * operation)</i>.
0413: *
0414: * <p> Writes the given byte into this buffer at the current
0415: * position, and then increments the position. </p>
0416: *
0417: * @param b The byte to be written.
0418: *
0419: * @return This buffer.
0420: *
0421: * @throws BufferOverflowException If this buffer's current
0422: * position is not smaller than its limit.
0423: *
0424: * @throws ReadOnlyBufferException If this buffer is
0425: * read-only. <b><i>JSR 239 does not support read-only buffer or
0426: * the <code>ReadOnlyBufferException</code> class.</i></b>
0427: */
0428: public abstract ByteBuffer put(byte b);
0429:
0430: /**
0431: * Absolute <i>get</i> method. Reads the byte at the given
0432: * index. </p>
0433: *
0434: * @param index The index from which the byte will be read.
0435: *
0436: * @return The byte at the given index.
0437: *
0438: * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
0439: * or not smaller than the buffer's limit.
0440: */
0441: public abstract byte get(int index);
0442:
0443: /**
0444: * Absolute <i>put</i> method <i>(optional operation)</i>.
0445: *
0446: * <p> Writes the given byte into this buffer at the given
0447: * index. </p>
0448: *
0449: * @param index The index at which the byte will be written.
0450: *
0451: * @param b The byte value to be written.
0452: *
0453: * @return This buffer.
0454: *
0455: * @throws IndexOutOfBoundsException If <tt>index</tt> is negative
0456: * or not smaller than the buffer's limit.
0457: *
0458: * @throws ReadOnlyBufferException If this buffer is
0459: * read-only. <b><i>JSR 239 does not support read-only buffer or
0460: * the <code>ReadOnlyBufferException</code> class.</i></b>
0461: */
0462: public abstract ByteBuffer put(int index, byte b);
0463:
0464: /**
0465: * Relative bulk <i>get</i> method.
0466: *
0467: * <p> This method transfers bytes from this buffer into the
0468: * given destination array. If there are fewer bytes
0469: * remaining in the buffer than are required to satisfy the
0470: * request, that is, if
0471: * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>,
0472: * then no bytes are transferred and a {@link
0473: * BufferUnderflowException} is thrown.
0474: *
0475: * <p> Otherwise, this method copies <tt>length</tt> bytes
0476: * from this buffer into the given array, starting at the current
0477: * position of this buffer and at the given offset in the array.
0478: * The position of this buffer is then incremented by
0479: * <tt>length</tt>.
0480: *
0481: * <p> In other words, an invocation of this method of the form
0482: * <tt>src.get(dst, off, len)</tt> has exactly the same
0483: * effect as the loop
0484: *
0485: * <pre>
0486: * for (int i = off; i < off + len; i++)
0487: * dst[i] = src.get(); </pre>
0488: *
0489: * except that it first checks that there are sufficient
0490: * bytes in this buffer and it is potentially much more
0491: * efficient. </p>
0492: *
0493: * @param dst The array into which bytes are to be written.
0494: *
0495: * @param offset The offset within the array of the first
0496: * byte to be written; must be non-negative and no larger
0497: * than <tt>dst.length</tt>.
0498: *
0499: * @param length The maximum number of bytes to be written
0500: * to the given array; must be non-negative and no larger than
0501: * <tt>dst.length - offset</tt>.
0502: *
0503: * @return This buffer.
0504: *
0505: * @throws BufferUnderflowException If there are fewer than
0506: * <tt>length</tt> bytes remaining in this buffer.
0507: *
0508: * @throws IndexOutOfBoundsException If the preconditions on the
0509: * <tt>offset</tt> and <tt>length</tt> parameters do not hold.
0510: */
0511: public ByteBuffer get(byte[] dst, int offset, int length) {
0512: if (offset < 0 || offset > dst.length || length < 0
0513: || length > dst.length - offset) {
0514: throw new IndexOutOfBoundsException();
0515: }
0516: if (limit - position < length) {
0517: throw new BufferUnderflowException();
0518: }
0519: if (isDirect) {
0520: ByteBufferImpl._getBytes(arrayOffset + position, dst,
0521: offset, length);
0522: } else {
0523: System.arraycopy(array, arrayOffset + position, dst,
0524: offset, length);
0525: }
0526: position += length;
0527: return this ;
0528: }
0529:
0530: /**
0531: * Relative bulk <i>get</i> method.
0532: *
0533: * <p> This method transfers bytes from this buffer into the
0534: * given destination array. An invocation of this method of the
0535: * form <tt>src.get(a)</tt> behaves in exactly the same way as the
0536: * invocation
0537: *
0538: * <pre>
0539: * src.get(a, 0, a.length) </pre>
0540: *
0541: * @return This buffer.
0542: *
0543: * @throws BufferUnderflowException If there are fewer than
0544: * <tt>dst.length</tt> bytes remaining in this buffer.
0545: */
0546: public ByteBuffer get(byte[] dst) {
0547: return get(dst, 0, dst.length);
0548: }
0549:
0550: /**
0551: * Relative bulk <i>put</i> method <i>(optional
0552: * operation)</i>.
0553: *
0554: * <p> This method transfers the bytes remaining in the
0555: * given source buffer into this buffer. If there are more
0556: * bytes remaining in the source buffer than in this buffer,
0557: * that is, if
0558: * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>,
0559: * then no bytes are transferred and a {@link
0560: * BufferOverflowException} is thrown.
0561: *
0562: * <p> Otherwise, this method copies
0563: * <i>n</i> = <tt>src.remaining()</tt> bytes from
0564: * the given buffer into this buffer, starting at each buffer's
0565: * current position. The positions of both buffers are then
0566: * incremented by <i>n</i>.
0567: *
0568: * <p> In other words, an invocation of this method of the form
0569: * <tt>dst.put(src)</tt> has exactly the same effect as the loop
0570: *
0571: * <pre>
0572: * while (src.hasRemaining())
0573: * dst.put(src.get()); </pre>
0574: *
0575: * except that it first checks that there is sufficient space in
0576: * this buffer and it is potentially much more efficient. </p>
0577: *
0578: * @param src The source buffer from which bytes are to be
0579: * read; must not be this buffer.
0580: *
0581: * @return This buffer.
0582: *
0583: * @throws BufferOverflowException If there is insufficient space
0584: * in this buffer for the remaining bytes in the source
0585: * buffer.
0586: *
0587: * @throws IllegalArgumentException If the source buffer is this buffer.
0588: *
0589: * @throws ReadOnlyBufferException If this buffer is
0590: * read-only. <b><i>JSR 239 does not support read-only buffer or
0591: * the <code>ReadOnlyBufferException</code> class.</i></b>
0592: */
0593: public ByteBuffer put(ByteBuffer src) {
0594: if (src == this ) {
0595: throw new IllegalArgumentException();
0596: }
0597:
0598: ByteBufferImpl srci = (ByteBufferImpl) src;
0599:
0600: int length = srci.limit - srci.position;
0601: if (length > this .limit - this .position) {
0602: throw new BufferOverflowException();
0603: }
0604: if (isDirect && srci.isDirect) {
0605: ByteBufferImpl._copyBytes(srci.arrayOffset + srci.position,
0606: this .arrayOffset + this .position, length);
0607: } else if (isDirect && !srci.isDirect) {
0608: ByteBufferImpl._putBytes(this .arrayOffset + this .position,
0609: srci.array, srci.arrayOffset + srci.position,
0610: length);
0611: } else if (!isDirect && srci.isDirect) {
0612: ByteBufferImpl._getBytes(srci.arrayOffset + srci.position,
0613: this .array, this .arrayOffset + this .position,
0614: length);
0615: } else if (!isDirect && !srci.isDirect) {
0616: System.arraycopy(srci.array, srci.arrayOffset
0617: + srci.position, this .array, this .arrayOffset
0618: + this .position, length);
0619: }
0620:
0621: srci.position += length;
0622: this .position += length;
0623: return this ;
0624: }
0625:
0626: /**
0627: * Relative bulk <i>put</i> method <i>(optional
0628: * operation)</i>.
0629: *
0630: * <p> This method transfers bytes into this buffer from the
0631: * given source array. If there are more bytes to be copied
0632: * from the array than remain in this buffer, that is, if
0633: * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>,
0634: * then no bytes are transferred and a {@link
0635: * BufferOverflowException} is thrown.
0636: *
0637: * <p> Otherwise, this method copies <tt>length</tt> bytes
0638: * from the given array into this buffer, starting at the given
0639: * offset in the array and at the current position of this buffer.
0640: * The position of this buffer is then incremented by
0641: * <tt>length</tt>.
0642: *
0643: * <p> In other words, an invocation of this method of the form
0644: * <tt>dst.put(src, off, len)</tt> has exactly the same
0645: * effect as the loop
0646: *
0647: * <pre>
0648: * for (int i = off; i < off + len; i++)
0649: * dst.put(a[i]); </pre>
0650: *
0651: * except that it first checks that there is sufficient space in
0652: * this buffer and it is potentially much more efficient. </p>
0653: *
0654: * @param src The array from which bytes are to be read.
0655: *
0656: * @param offset The offset within the array of the first
0657: * byte to be read; must be non-negative and no larger than
0658: * <tt>array.length</tt>.
0659: *
0660: * @param length The number of bytes to be read from the
0661: * given array; must be non-negative and no larger than
0662: * <tt>array.length - offset</tt>.
0663: *
0664: * @return This buffer.
0665: *
0666: * @throws BufferOverflowException If there is insufficient space
0667: * in this buffer.
0668: *
0669: * @throws IndexOutOfBoundsException If the preconditions on the
0670: * <tt>offset</tt> and <tt>length</tt> parameters do not hold.
0671: *
0672: * @throws ReadOnlyBufferException If this buffer is
0673: * read-only. <b><i>JSR 239 does not support read-only buffer or
0674: * the <code>ReadOnlyBufferException</code> class.</i></b>
0675: */
0676: public ByteBuffer put(byte[] src, int offset, int length) {
0677: // need revisit -- overlapping backing store?
0678: if (offset < 0 || offset > src.length || length < 0
0679: || length > src.length - offset) {
0680: throw new IndexOutOfBoundsException();
0681: }
0682: if (length > limit - position) {
0683: throw new BufferOverflowException();
0684: }
0685: if (isDirect) {
0686: ByteBufferImpl._putBytes(arrayOffset + position, src,
0687: offset, length);
0688: } else {
0689: System.arraycopy(src, offset, array,
0690: arrayOffset + position, length);
0691: }
0692: position += length;
0693: return this ;
0694: }
0695:
0696: /**
0697: * Relative bulk <i>put</i> method <i>(optional operation)</i>.
0698: *
0699: * <p> This method transfers the entire content of the given
0700: * source byte array into this buffer. An invocation of
0701: * this method of the form <tt>dst.put(a)</tt> behaves in exactly
0702: * the same way as the invocation
0703: *
0704: * <pre>
0705: * dst.put(a, 0, a.length) </pre>
0706: *
0707: * @return This buffer.
0708: *
0709: * @throws BufferOverflowException If there is insufficient space
0710: * in this buffer.
0711: *
0712: * @throws ReadOnlyBufferException If this buffer is
0713: * read-only. <b><i>JSR 239 does not support read-only buffer or
0714: * the <code>ReadOnlyBufferException</code> class.</i></b>
0715: */
0716: public final ByteBuffer put(byte[] src) {
0717: return put(src, 0, src.length);
0718: }
0719:
0720: /**
0721: * Tells whether or not this buffer is backed by an accessible
0722: * byte array.
0723: *
0724: * <p> If this method returns <tt>true</tt> then the {@link
0725: * #array() array} and {@link #arrayOffset() arrayOffset} methods
0726: * may safely be invoked. </p>
0727: *
0728: * @return <tt>true</tt> if, and only if, this buffer is backed by
0729: * an array and is not read-only. <b><i>JSR 239 does not support
0730: * read-only buffers.</i></b>
0731: */
0732: public final boolean hasArray() {
0733: return !isDirect;
0734: }
0735:
0736: /**
0737: * Returns the byte array that backs this
0738: * buffer <i>(optional operation)</i>.
0739: *
0740: * <p> Modifications to this buffer's content will cause the returned
0741: * array's content to be modified, and vice versa.
0742: *
0743: * <p> Invoke the {@link #hasArray hasArray} method before
0744: * invoking this method in order to ensure that this buffer has an
0745: * accessible backing array. </p>
0746: *
0747: * @return The array that backs this buffer.
0748: *
0749: * @throws ReadOnlyBufferException If this buffer is
0750: * read-only. <b><i>JSR 239 does not support read-only buffer or
0751: * the <code>ReadOnlyBufferException</code> class.</i></b>
0752: *
0753: * @throws UnsupportedOperationException If this buffer is not
0754: * backed by an accessible array.
0755: */
0756: public final byte[] array() {
0757: if (isDirect) {
0758: throw new UnsupportedOperationException();
0759: }
0760: return array;
0761: }
0762:
0763: /**
0764: * Returns the offset within this buffer's backing array of the
0765: * first element of the buffer <i>(optional
0766: * operation)</i>.
0767: *
0768: * <p> If this buffer is backed by an array then buffer position
0769: * <i>p</i> corresponds to array index
0770: * <i>p</i> + <tt>arrayOffset()</tt>.
0771: *
0772: * <p> Invoke the {@link #hasArray hasArray} method before
0773: * invoking this method in order to ensure that this buffer has an
0774: * accessible backing array. </p>
0775: *
0776: * @return The offset within this buffer's array of the first
0777: * element of the buffer.
0778: *
0779: * @throws ReadOnlyBufferException If this buffer is
0780: * read-only. <b><i>JSR 239 does not support read-only buffer or
0781: * the <code>ReadOnlyBufferException</code> class.</i></b>
0782: *
0783: * @throws UnsupportedOperationException If this buffer is not
0784: * backed by an accessible array.
0785: */
0786: public final int arrayOffset() {
0787: if (isDirect) {
0788: throw new UnsupportedOperationException();
0789: }
0790: return arrayOffset;
0791: }
0792:
0793: /**
0794: * Tells whether or not this byte buffer is direct. </p>
0795: *
0796: * @return <tt>true</tt> if, and only if, this buffer is direct.
0797: */
0798: public abstract boolean isDirect();
0799:
0800: /**
0801: * Returns a string summarizing the state of this buffer.
0802: *
0803: * @return A summary string
0804: */
0805: public String toString() {
0806: return "java.nio.ByteBuffer[" + "pos=" + position() + "lim="
0807: + limit() + "cap=" + capacity() + "]";
0808: }
0809:
0810: /**
0811: * Returns the current hash code of this buffer.
0812: *
0813: * <p> The hash code of a byte buffer depends only upon its remaining
0814: * elements; that is, upon the elements from <tt>position()</tt> up to, and
0815: * including, the element at <tt>limit()</tt> - <tt>1</tt>.
0816: *
0817: * <p> Because buffer hash codes are content-dependent, it is inadvisable
0818: * to use buffers as keys in hash maps or similar data structures unless it
0819: * is known that their contents will not change. </p>
0820: *
0821: * @return The current hash code of this buffer.
0822: */
0823: public int hashCode() {
0824: int h = 1;
0825: int p = position();
0826: for (int i = limit() - 1; i >= p; i--)
0827: h = 31 * h + (int) get(i);
0828: return h;
0829: }
0830:
0831: /**
0832: * Tells whether or not this buffer is equal to another object.
0833: *
0834: * <p> Two byte buffers are equal if, and only if,
0835: *
0836: * <p><ol>
0837: *
0838: * <li><p> They have the same element type, </p></li>
0839: *
0840: * <li><p> They have the same number of remaining elements, and
0841: * </p></li>
0842: *
0843: * <li><p> The two sequences of remaining elements, considered
0844: * independently of their starting positions, are pointwise equal.
0845: * </p></li>
0846: *
0847: * </ol>
0848: *
0849: * <p> A byte buffer is not equal to any other type of object. </p>
0850: *
0851: * @param ob The object to which this buffer is to be compared.
0852: *
0853: * @return <tt>true</tt> if, and only if, this buffer is equal to the
0854: * given object.
0855: */
0856: public boolean equals(Object ob) {
0857: if (!(ob instanceof ByteBuffer))
0858: return false;
0859: ByteBuffer that = (ByteBuffer) ob;
0860: if (this .remaining() != that.remaining())
0861: return false;
0862: int p = this .position();
0863: for (int i = this .limit() - 1, j = that.limit() - 1; i >= p; i--, j--) {
0864: byte v1 = this .get(i);
0865: byte v2 = that.get(j);
0866: if (v1 != v2) {
0867: if ((v1 != v1) && (v2 != v2)) // For float and double
0868: continue;
0869: return false;
0870: }
0871: }
0872: return true;
0873: }
0874:
0875: /**
0876: * Compares this buffer to another.
0877: *
0878: * <p> Two byte buffers are compared by comparing their sequences of
0879: * remaining elements lexicographically, without regard to the starting
0880: * position of each sequence within its corresponding buffer.
0881: *
0882: * <p> A byte buffer is not comparable to any other type of object.
0883: *
0884: * @return A negative integer, zero, or a positive integer as this buffer
0885: * is less than, equal to, or greater than the given buffer.
0886: * @throws ClassCastException If the argument is not a byte buffer.
0887: */
0888: public int compareTo(Object ob) {
0889: ByteBuffer that = (ByteBuffer) ob;
0890: int n = this .position()
0891: + Math.min(this .remaining(), that.remaining());
0892: for (int i = this .position(), j = that.position(); i < n; i++, j++) {
0893: byte v1 = this .get(i);
0894: byte v2 = that.get(j);
0895: if (v1 == v2)
0896: continue;
0897: if ((v1 != v1) && (v2 != v2)) // For float and double
0898: continue;
0899: if (v1 < v2)
0900: return -1;
0901: return +1;
0902: }
0903: return this .remaining() - that.remaining();
0904: }
0905:
0906: /**
0907: * Relative <i>get</i> method for reading a short value.
0908: *
0909: * <p> Reads the next two bytes at this buffer's current position,
0910: * composing them into a short value according to the current byte order,
0911: * and then increments the position by two. </p>
0912: *
0913: * @return The short value at the buffer's current position
0914: *
0915: * @throws BufferUnderflowException
0916: * If there are fewer than two bytes
0917: * remaining in this buffer
0918: */
0919: public abstract short getShort();
0920:
0921: /**
0922: * Relative <i>put</i> method for writing a short
0923: * value <i>(optional operation)</i>.
0924: *
0925: * <p> Writes two bytes containing the given short value, in the
0926: * current byte order, into this buffer at the current position, and then
0927: * increments the position by two. </p>
0928: *
0929: * @param value
0930: * The short value to be written
0931: *
0932: * @return This buffer
0933: *
0934: * @throws BufferOverflowException
0935: * If there are fewer than two bytes
0936: * remaining in this buffer
0937: *
0938: * @throws ReadOnlyBufferException
0939: * If this buffer is read-only
0940: */
0941: public abstract ByteBuffer putShort(short value);
0942:
0943: /**
0944: * Absolute <i>get</i> method for reading a short value.
0945: *
0946: * <p> Reads two bytes at the given index, composing them into a
0947: * short value according to the current byte order. </p>
0948: *
0949: * @param index
0950: * The index from which the bytes will be read
0951: *
0952: * @return The short value at the given index
0953: *
0954: * @throws IndexOutOfBoundsException
0955: * If <tt>index</tt> is negative
0956: * or not smaller than the buffer's limit,
0957: * minus one
0958: */
0959: public abstract short getShort(int index);
0960:
0961: /**
0962: * Absolute <i>put</i> method for writing a short
0963: * value <i>(optional operation)</i>.
0964: *
0965: * <p> Writes two bytes containing the given short value, in the
0966: * current byte order, into this buffer at the given index. </p>
0967: *
0968: * @param index
0969: * The index at which the bytes will be written
0970: *
0971: * @param value
0972: * The short value to be written
0973: *
0974: * @return This buffer
0975: *
0976: * @throws IndexOutOfBoundsException
0977: * If <tt>index</tt> is negative
0978: * or not smaller than the buffer's limit,
0979: * minus one
0980: *
0981: * @throws ReadOnlyBufferException
0982: * If this buffer is read-only
0983: */
0984: public abstract ByteBuffer putShort(int index, short value);
0985:
0986: /**
0987: * Creates a view of this byte buffer as a short buffer.
0988: *
0989: * <p> The content of the new buffer will start at this buffer's
0990: * current position. Changes to this buffer's content will be
0991: * visible in the new buffer, and vice versa; the two buffers'
0992: * position, limit, and mark values will be independent. <b><i>JSR
0993: * 239 does not support the mark.</i></b>
0994: *
0995: * <p> The new buffer's position will be zero, its capacity and
0996: * its limit will be the number of bytes remaining in this buffer
0997: * divided by two, and its mark will be undefined. The new buffer
0998: * will be direct if, and only if, this buffer is direct, and it
0999: * will be read-only if, and only if, this buffer is read-only.
1000: * <b><i>JSR 239 does not support the mark or read-only
1001: * buffers.</i></b>
1002: *
1003: * @return A new short buffer.
1004: */
1005: public abstract ShortBuffer asShortBuffer();
1006:
1007: /**
1008: * Relative <i>get</i> method for reading an int value.
1009: *
1010: * <p> Reads the next four bytes at this buffer's current position,
1011: * composing them into an int value according to the current byte order,
1012: * and then increments the position by four. </p>
1013: *
1014: * @return The int value at the buffer's current position
1015: *
1016: * @throws BufferUnderflowException
1017: * If there are fewer than four bytes
1018: * remaining in this buffer
1019: */
1020: public abstract int getInt();
1021:
1022: /**
1023: * Relative <i>put</i> method for writing an int
1024: * value <i>(optional operation)</i>.
1025: *
1026: * <p> Writes four bytes containing the given int value, in the
1027: * current byte order, into this buffer at the current position, and then
1028: * increments the position by four. </p>
1029: *
1030: * @param value
1031: * The int value to be written
1032: *
1033: * @return This buffer
1034: *
1035: * @throws BufferOverflowException
1036: * If there are fewer than four bytes
1037: * remaining in this buffer
1038: *
1039: * @throws ReadOnlyBufferException
1040: * If this buffer is read-only
1041: */
1042: public abstract ByteBuffer putInt(int value);
1043:
1044: /**
1045: * Absolute <i>get</i> method for reading an int value.
1046: *
1047: * <p> Reads four bytes at the given index, composing them into a
1048: * int value according to the current byte order. </p>
1049: *
1050: * @param index
1051: * The index from which the bytes will be read
1052: *
1053: * @return The int value at the given index
1054: *
1055: * @throws IndexOutOfBoundsException
1056: * If <tt>index</tt> is negative
1057: * or not smaller than the buffer's limit,
1058: * minus three
1059: */
1060: public abstract int getInt(int index);
1061:
1062: /**
1063: * Absolute <i>put</i> method for writing an int
1064: * value <i>(optional operation)</i>.
1065: *
1066: * <p> Writes four bytes containing the given int value, in the
1067: * current byte order, into this buffer at the given index. </p>
1068: *
1069: * @param index
1070: * The index at which the bytes will be written
1071: *
1072: * @param value
1073: * The int value to be written
1074: *
1075: * @return This buffer
1076: *
1077: * @throws IndexOutOfBoundsException
1078: * If <tt>index</tt> is negative
1079: * or not smaller than the buffer's limit,
1080: * minus three
1081: *
1082: * @throws ReadOnlyBufferException
1083: * If this buffer is read-only
1084: */
1085: public abstract ByteBuffer putInt(int index, int value);
1086:
1087: /**
1088: * Creates a view of this byte buffer as an int buffer.
1089: *
1090: * <p> The content of the new buffer will start at this buffer's
1091: * current position. Changes to this buffer's content will be
1092: * visible in the new buffer, and vice versa; the two buffers'
1093: * position, limit, and mark values will be independent. <b><i>JSR
1094: * 239 does not support the mark.</i></b>
1095: *
1096: * <p> The new buffer's position will be zero, its capacity and
1097: * its limit will be the number of bytes remaining in this buffer
1098: * divided by four, and its mark will be undefined. The new buffer
1099: * will be direct if, and only if, this buffer is direct, and it
1100: * will be read-only if, and only if, this buffer is read-only.
1101: * <b><i>JSR 239 does not support the mark or read-only
1102: * buffers.</i></b>
1103: *
1104: * @return A new int buffer.
1105: */
1106: public abstract IntBuffer asIntBuffer();
1107:
1108: /**
1109: * Relative <i>get</i> method for reading a float value.
1110: *
1111: * <p> Reads the next four bytes at this buffer's current position,
1112: * composing them into a float value according to the current byte order,
1113: * and then increments the position by four. </p>
1114: *
1115: * @return The float value at the buffer's current position
1116: *
1117: * @throws BufferUnderflowException
1118: * If there are fewer than four bytes
1119: * remaining in this buffer
1120: */
1121: public abstract float getFloat();
1122:
1123: /**
1124: * Relative <i>put</i> method for writing a float
1125: * value <i>(optional operation)</i>.
1126: *
1127: * <p> Writes four bytes containing the given float value, in the
1128: * current byte order, into this buffer at the current position, and then
1129: * increments the position by four. </p>
1130: *
1131: * @param value
1132: * The float value to be written
1133: *
1134: * @return This buffer
1135: *
1136: * @throws BufferOverflowException
1137: * If there are fewer than four bytes
1138: * remaining in this buffer
1139: *
1140: * @throws ReadOnlyBufferException
1141: * If this buffer is read-only
1142: */
1143: public abstract ByteBuffer putFloat(float value);
1144:
1145: /**
1146: * Absolute <i>get</i> method for reading a float value.
1147: *
1148: * <p> Reads four bytes at the given index, composing them into a
1149: * float value according to the current byte order. </p>
1150: *
1151: * @param index
1152: * The index from which the bytes will be read
1153: *
1154: * @return The float value at the given index
1155: *
1156: * @throws IndexOutOfBoundsException
1157: * If <tt>index</tt> is negative
1158: * or not smaller than the buffer's limit,
1159: * minus three
1160: */
1161: public abstract float getFloat(int index);
1162:
1163: /**
1164: * Absolute <i>put</i> method for writing a float
1165: * value <i>(optional operation)</i>.
1166: *
1167: * <p> Writes four bytes containing the given float value, in the
1168: * current byte order, into this buffer at the given index. </p>
1169: *
1170: * @param index
1171: * The index at which the bytes will be written
1172: *
1173: * @param value
1174: * The float value to be written
1175: *
1176: * @return This buffer
1177: *
1178: * @throws IndexOutOfBoundsException
1179: * If <tt>index</tt> is negative
1180: * or not smaller than the buffer's limit,
1181: * minus three
1182: *
1183: * @throws ReadOnlyBufferException
1184: * If this buffer is read-only
1185: */
1186: public abstract ByteBuffer putFloat(int index, float value);
1187:
1188: /**
1189: * Creates a view of this byte buffer as a float buffer.
1190: *
1191: * <p> The content of the new buffer will start at this buffer's
1192: * current position. Changes to this buffer's content will be
1193: * visible in the new buffer, and vice versa; the two buffers'
1194: * position, limit, and mark values will be independent. <b><i>JSR
1195: * 239 does not support the mark.</i></b>
1196: *
1197: * <p> The new buffer's position will be zero, its capacity and
1198: * its limit will be the number of bytes remaining in this buffer
1199: * divided by four, and its mark will be undefined. The new buffer
1200: * will be direct if, and only if, this buffer is direct, and it
1201: * will be read-only if, and only if, this buffer is read-only.
1202: * <b><i>JSR 239 does not support the mark or read-only
1203: * buffers.</i></b>
1204: *
1205: * @return A new float buffer.
1206: */
1207: public abstract FloatBuffer asFloatBuffer();
1208: }
|