/*
* Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package java.nio;
/**
* <p> A container for data of a specific primitive type.
*
* <p> This class is provided as part of the JSR 239 NIO Buffer
* building block. It is a subset of the <code>java.nio.Buffer</code>
* class in Java(TM) Standard Edition version 1.4.2. Differences are
* noted in <b><i>bold italic</i></b>.
*
* <p><b><i> I/O channels, marking and resetting, and read-only
* buffers are not supported. The <code>char</code>,
* <code>long</code>, and <code>double</code> datatypes are not
* supported. The following methods are omitted:
*
* <ul>
* <li><code>Buffer mark()</code></li>
* <li><code>Buffer reset()</code></li>
* <li><code>boolean isReadOnly()</code></li>
* </ul>
* </i></b>
*
* To mimimize documentation differences from the full NIO package,
* the omitted features continue to be mentioned in the
* documentation. In each case, a note is added explaining that the
* feature is not present.
*
* <p> A buffer is a linear, finite sequence of elements of a
* specific primitive type. Aside from its content, the essential
* properties of a buffer are its capacity, limit, and position: </p>
*
* <blockquote>
*
* <p> A buffer's <i>capacity</i> is the number of elements it contains. The
* capacity of a buffer is never negative and never changes. </p>
*
* <p> A buffer's <i>limit</i> is the index of the first element that should
* not be read or written. A buffer's limit is never negative and is never
* greater than its capacity. </p>
*
* <p> A buffer's <i>position</i> is the index of the next element to be
* read or written. A buffer's position is never negative and is never
* greater than its limit. </p>
*
* </blockquote>
*
* <p> There is one subclass of this class for each non-boolean
* primitive type. <b><i>The <code>char</code>, <code>long</code>,
* and <code>double</code> buffer subclasses are not supported in JSR
* 239.</i></b>
*
* <h4> Transferring data </h4>
*
* <p> Each subclass of this class defines two categories of <i>get</i> and
* <i>put</i> operations: </p>
*
* <blockquote>
*
* <p> <i>Relative</i> operations read or write one or more elements
* starting at the current position and then increment the position
* by the number of elements transferred. If the requested transfer
* exceeds the limit then a relative <i>get</i> operation throws a
* <A HREF="BufferUnderflowException.html"
* title="class in
* java.nio"><CODE>BufferUnderflowException</CODE></A>
* and a relative <i>put</i> operation throws a <A
* HREF="BufferOverflowException.html" title="class
* in java.nio"><CODE>BufferOverflowException</CODE></A>; in either
* case, no data is transferred. </p>
*
* <p> <i>Absolute</i> operations take an explicit element index and
* do not affect the position. Absolute <i>get</i> and <i>put</i>
* operations throw an <CODE>IndexOutOfBoundsException</CODE> if the
* index argument exceeds the limit. </p>
*
* </blockquote>
*
* <p> Data may also, of course, be transferred in to or out of a
* buffer by the I/O operations of an appropriate channel, which are
* always relative to the current position. <b><i>Channels are not
* supported in JSR 239.</i></b>.
*
* <h4> Marking and resetting </h4>
*
* <p> <b><i>Marking and resetting are not supported in JSR
* 239.</i></b>
*
* <p> A buffer's <i>mark</i> is the index to which its position will
* be reset when the <CODE>reset</CODE>
* method is invoked. The mark is not always defined, but when it is
* defined it is never negative and is never greater than the
* position. If the mark is defined then it is discarded when the
* position or the limit is adjusted to a value smaller than the mark.
* If the mark is not defined then invoking the <CODE>reset</CODE>
* method causes an <CODE>InvalidMarkException</CODE> to
* be thrown.
*
* <h4> Invariants </h4>
*
* <p> The following invariant holds for the mark, position, limit, and
* capacity values:
*
* <blockquote>
* <tt>0</tt> <tt><=</tt>
* <i>mark</i> <tt><=</tt>
* <i>position</i> <tt><=</tt>
*
* <i>limit</i> <tt><=</tt>
* <i>capacity</i>
* </blockquote>
*
* <p> A newly-created buffer always has a position of zero and a mark that is
* undefined. The initial limit may be zero, or it may be some other value
* that depends upon the type of the buffer and the manner in which it is
* constructed. The initial content of a buffer is, in general,
* undefined.
*
*
* <h4> Clearing, flipping, and rewinding </h4>
*
* <p> In addition to methods for accessing the position, limit, and capacity
* values and for marking and resetting, this class also defines the following
* operations upon buffers:
*
* <ul>
*
* <li><p> <A
* HREF="Buffer.html#clear()"><CODE>clear()</CODE></A>
* makes a buffer ready for a new sequence of channel-read or
* relative <i>put</i> operations: It sets the limit to the capacity
* and the position to zero. </p></li>
*
* <li><p> <A
* HREF="Buffer.html#flip()"><CODE>flip()</CODE></A>
* makes a buffer ready for a new sequence of channel-write or
* relative <i>get</i> operations: It sets the limit to the current
* position and then sets the position to zero. </p></li>
*
* <li><p> <A
* HREF="Buffer.html#rewind()"><CODE>rewind()</CODE></A>
* makes a buffer ready for re-reading the data that it already
* contains: It leaves the limit unchanged and sets the position to
* zero. </p></li>
*
* </ul>
*
* <h4> Read-only buffers </h4>
*
* <p><b><i>JSR 239 does not support read-only buffers</i></b>.
*
* <p> Every buffer is readable, but not every buffer is writable.
* The mutation methods of each buffer class are specified as
* <i>optional operations</i> that will throw a
* <CODE>ReadOnlyBufferException</CODE> when invoked upon a read-only
* buffer. A read-only buffer does not allow its content to be
* changed, but its mark, position, and limit values are mutable.
* Whether or not a buffer is read-only may be determined by invoking
* its <CODE>isReadOnly</CODE> method.
*
* <h4> Thread safety </h4>
*
* <p> Buffers are not safe for use by multiple concurrent threads.
* If a buffer is to be used by more than one thread then access to
* the buffer should be controlled by appropriate synchronization.
*
* <h4> Invocation chaining </h4>
*
* <p> Methods in this class that do not otherwise have a value to
* return are specified to return the buffer upon which they are
* invoked. This allows method invocations to be chained; for
* example, the sequence of statements
*
* <blockquote><pre>
* b.flip();
* b.position(23);
* b.limit(42);
* </pre></blockquote>
*
* can be replaced by the single, more compact statement
*
* <blockquote><pre>
* b.flip().position(23).limit(42);
* </pre></blockquote>
*/
public abstract class Buffer {
int capacity;
int limit;
int position;
Buffer() {}
/**
* Returns this buffer's capacity.
*
* @return The capacity of this buffer.
*/
public final int capacity() {
return capacity;
}
/**
* Returns this buffer's position.
*
* @return The position of this buffer.
*/
public final int position() {
return position;
}
/**
* Sets this buffer's position. If the mark is defined and larger
* than the new position then it is discarded. <b><i>JSR 239 does
* not support marking and resetting.</i></b>
*
* @param newPosition The new position value; must be non-negative
* and no larger than the current limit.
*
* @return This buffer.
*
* @throws IllegalArgumentException If the preconditions on
* <code>newPosition</code> do not hold.
*/
public final Buffer position(int newPosition) {
if (newPosition < 0 || newPosition > limit) {
throw new IllegalArgumentException();
}
this.position = newPosition;
return this;
}
/**
* Returns this buffer's limit.
*
* @return The limit of this buffer.
*/
public final int limit() {
return limit;
}
/**
* Sets this buffer's limit. If the position is larger than the
* new limit then it is set to the new limit. If the mark is
* defined and larger than the new limit then it is
* discarded. <b><i>JSR 239 does not support marking and
* resetting.</i></b>
*
* @param newLimit the new limit value.
*
* @return this buffer.
*
* @throws IllegalArgumentException if <code>newLimit</code> is
* negative or larger than this buffer's capacity.
*/
public final Buffer limit(int newLimit) {
if (newLimit < 0 || newLimit > capacity) {
throw new IllegalArgumentException();
}
if (position > newLimit) {
position = newLimit;
}
this.limit = newLimit;
return this;
}
/**
* Clears this buffer. The position is set to zero, the limit is
* set to the capacity, and the mark is discarded. <b><i>JSR 239 does
* not support marking and resetting.</i></b>
*
* <p> Invoke this method before using a sequence of channel-read
* or <i>put</i> operations to fill this buffer. For example:
*
* <blockquote><pre>
* buf.clear(); // Prepare buffer for reading
* in.read(buf); // Read data
* </pre></blockquote>
*
* <p> <b><i>JSR 239 does not support channels.</i></b>
*
* <p> This method does not actually erase the data in the buffer,
* but it is named as if it did because it will most often be used
* in situations in which that might as well be the case.
*
* @return This buffer.
*/
public final Buffer clear() {
this.position = 0;
this.limit = this.capacity;
return this;
}
/**
* Flips this buffer. The limit is set to the current position and
* then the position is set to zero. If the mark is defined then
* it is discarded. <b><i>JSR 239 does
* not support marking and resetting.</i></b>
*
* <p> After a sequence of channel-read or <i>put</i> operations, invoke
* this method to prepare for a sequence of channel-write or
* relative <i>get</i> operations. For example:
*
* <blockquote><pre>
* buf.put(magic); // Prepend header
* in.read(buf); // Read data into rest of buffer
* buf.flip(); // Flip buffer
* out.write(buf); // Write header + data to channel
* </pre></blockquote>
*
* <p> This method is often used in conjunction with the compact
* method when transferring data from one place to another.
*
* <p> <b><i>JSR 239 does not support channels.</i></b>
*
* @return This buffer.
*/
public final Buffer flip() {
this.limit = this.position;
this.position = 0;
return this;
}
/**
* Rewinds this buffer. The position is set to zero and the mark
* is discarded. <b><i>JSR 239 does
* not support marking and resetting.</i></b>
*
* <p> Invoke this method before a sequence of channel-write or
* <i>get</i> operations, assuming that the limit has already been set
* appropriately. For example:
*
* <blockquote><pre>
* out.write(buf); // Write remaining data
* buf.rewind(); // Rewind buffer
* buf.get(array); // Copy data into array
* </pre></blockquote>
*
* <p> <b><i>JSR 239 does not support channels.</i></b>
*/
public final Buffer rewind() {
this.position = 0;
return this;
}
/**
* Returns the number of elements between the current position and
* the limit.
*
* @return The number of elements remaining in this buffer.
*/
public final int remaining() {
return limit - position;
}
/**
* Tells whether there are any elements between the current
* position and the limit.
*
* @return <code>true</code> if, and only if, there is at least
* one element remaining in this buffer.
*/
public final boolean hasRemaining() {
return position < limit;
}
// Removed methods:
//
// abstract boolean isReadOnly();
//
// // Applications can maintain their own mark, use position(int)
// Buffer mark();
// Buffer reset();
}
|