001: /*
002: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License version
007: * 2 only, as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License version 2 for more details (a copy is
013: * included at /legal/license.txt).
014: *
015: * You should have received a copy of the GNU General Public License
016: * version 2 along with this work; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018: * 02110-1301 USA
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021: * Clara, CA 95054 or visit www.sun.com if you need additional
022: * information or have any questions.
023: */
024:
025: package java.nio;
026:
027: /**
028: * <p> A container for data of a specific primitive type.
029: *
030: * <p> This class is provided as part of the JSR 239 NIO Buffer
031: * building block. It is a subset of the <code>java.nio.Buffer</code>
032: * class in Java(TM) Standard Edition version 1.4.2. Differences are
033: * noted in <b><i>bold italic</i></b>.
034: *
035: * <p><b><i> I/O channels, marking and resetting, and read-only
036: * buffers are not supported. The <code>char</code>,
037: * <code>long</code>, and <code>double</code> datatypes are not
038: * supported. The following methods are omitted:
039: *
040: * <ul>
041: * <li><code>Buffer mark()</code></li>
042: * <li><code>Buffer reset()</code></li>
043: * <li><code>boolean isReadOnly()</code></li>
044: * </ul>
045: * </i></b>
046: *
047: * To mimimize documentation differences from the full NIO package,
048: * the omitted features continue to be mentioned in the
049: * documentation. In each case, a note is added explaining that the
050: * feature is not present.
051: *
052: * <p> A buffer is a linear, finite sequence of elements of a
053: * specific primitive type. Aside from its content, the essential
054: * properties of a buffer are its capacity, limit, and position: </p>
055: *
056: * <blockquote>
057: *
058: * <p> A buffer's <i>capacity</i> is the number of elements it contains. The
059: * capacity of a buffer is never negative and never changes. </p>
060: *
061: * <p> A buffer's <i>limit</i> is the index of the first element that should
062: * not be read or written. A buffer's limit is never negative and is never
063: * greater than its capacity. </p>
064: *
065: * <p> A buffer's <i>position</i> is the index of the next element to be
066: * read or written. A buffer's position is never negative and is never
067: * greater than its limit. </p>
068: *
069: * </blockquote>
070: *
071: * <p> There is one subclass of this class for each non-boolean
072: * primitive type. <b><i>The <code>char</code>, <code>long</code>,
073: * and <code>double</code> buffer subclasses are not supported in JSR
074: * 239.</i></b>
075: *
076: * <h4> Transferring data </h4>
077: *
078: * <p> Each subclass of this class defines two categories of <i>get</i> and
079: * <i>put</i> operations: </p>
080: *
081: * <blockquote>
082: *
083: * <p> <i>Relative</i> operations read or write one or more elements
084: * starting at the current position and then increment the position
085: * by the number of elements transferred. If the requested transfer
086: * exceeds the limit then a relative <i>get</i> operation throws a
087: * <A HREF="BufferUnderflowException.html"
088: * title="class in
089: * java.nio"><CODE>BufferUnderflowException</CODE></A>
090: * and a relative <i>put</i> operation throws a <A
091: * HREF="BufferOverflowException.html" title="class
092: * in java.nio"><CODE>BufferOverflowException</CODE></A>; in either
093: * case, no data is transferred. </p>
094: *
095: * <p> <i>Absolute</i> operations take an explicit element index and
096: * do not affect the position. Absolute <i>get</i> and <i>put</i>
097: * operations throw an <CODE>IndexOutOfBoundsException</CODE> if the
098: * index argument exceeds the limit. </p>
099: *
100: * </blockquote>
101: *
102: * <p> Data may also, of course, be transferred in to or out of a
103: * buffer by the I/O operations of an appropriate channel, which are
104: * always relative to the current position. <b><i>Channels are not
105: * supported in JSR 239.</i></b>.
106: *
107: * <h4> Marking and resetting </h4>
108: *
109: * <p> <b><i>Marking and resetting are not supported in JSR
110: * 239.</i></b>
111: *
112: * <p> A buffer's <i>mark</i> is the index to which its position will
113: * be reset when the <CODE>reset</CODE>
114: * method is invoked. The mark is not always defined, but when it is
115: * defined it is never negative and is never greater than the
116: * position. If the mark is defined then it is discarded when the
117: * position or the limit is adjusted to a value smaller than the mark.
118: * If the mark is not defined then invoking the <CODE>reset</CODE>
119: * method causes an <CODE>InvalidMarkException</CODE> to
120: * be thrown.
121: *
122: * <h4> Invariants </h4>
123: *
124: * <p> The following invariant holds for the mark, position, limit, and
125: * capacity values:
126: *
127: * <blockquote>
128: * <tt>0</tt> <tt><=</tt>
129: * <i>mark</i> <tt><=</tt>
130: * <i>position</i> <tt><=</tt>
131: *
132: * <i>limit</i> <tt><=</tt>
133: * <i>capacity</i>
134: * </blockquote>
135: *
136: * <p> A newly-created buffer always has a position of zero and a mark that is
137: * undefined. The initial limit may be zero, or it may be some other value
138: * that depends upon the type of the buffer and the manner in which it is
139: * constructed. The initial content of a buffer is, in general,
140: * undefined.
141: *
142: *
143: * <h4> Clearing, flipping, and rewinding </h4>
144: *
145: * <p> In addition to methods for accessing the position, limit, and capacity
146: * values and for marking and resetting, this class also defines the following
147: * operations upon buffers:
148: *
149: * <ul>
150: *
151: * <li><p> <A
152: * HREF="Buffer.html#clear()"><CODE>clear()</CODE></A>
153: * makes a buffer ready for a new sequence of channel-read or
154: * relative <i>put</i> operations: It sets the limit to the capacity
155: * and the position to zero. </p></li>
156: *
157: * <li><p> <A
158: * HREF="Buffer.html#flip()"><CODE>flip()</CODE></A>
159: * makes a buffer ready for a new sequence of channel-write or
160: * relative <i>get</i> operations: It sets the limit to the current
161: * position and then sets the position to zero. </p></li>
162: *
163: * <li><p> <A
164: * HREF="Buffer.html#rewind()"><CODE>rewind()</CODE></A>
165: * makes a buffer ready for re-reading the data that it already
166: * contains: It leaves the limit unchanged and sets the position to
167: * zero. </p></li>
168: *
169: * </ul>
170: *
171: * <h4> Read-only buffers </h4>
172: *
173: * <p><b><i>JSR 239 does not support read-only buffers</i></b>.
174: *
175: * <p> Every buffer is readable, but not every buffer is writable.
176: * The mutation methods of each buffer class are specified as
177: * <i>optional operations</i> that will throw a
178: * <CODE>ReadOnlyBufferException</CODE> when invoked upon a read-only
179: * buffer. A read-only buffer does not allow its content to be
180: * changed, but its mark, position, and limit values are mutable.
181: * Whether or not a buffer is read-only may be determined by invoking
182: * its <CODE>isReadOnly</CODE> method.
183: *
184: * <h4> Thread safety </h4>
185: *
186: * <p> Buffers are not safe for use by multiple concurrent threads.
187: * If a buffer is to be used by more than one thread then access to
188: * the buffer should be controlled by appropriate synchronization.
189: *
190: * <h4> Invocation chaining </h4>
191: *
192: * <p> Methods in this class that do not otherwise have a value to
193: * return are specified to return the buffer upon which they are
194: * invoked. This allows method invocations to be chained; for
195: * example, the sequence of statements
196: *
197: * <blockquote><pre>
198: * b.flip();
199: * b.position(23);
200: * b.limit(42);
201: * </pre></blockquote>
202: *
203: * can be replaced by the single, more compact statement
204: *
205: * <blockquote><pre>
206: * b.flip().position(23).limit(42);
207: * </pre></blockquote>
208: */
209: public abstract class Buffer {
210:
211: int capacity;
212: int limit;
213: int position;
214:
215: Buffer() {
216: }
217:
218: /**
219: * Returns this buffer's capacity.
220: *
221: * @return The capacity of this buffer.
222: */
223: public final int capacity() {
224: return capacity;
225: }
226:
227: /**
228: * Returns this buffer's position.
229: *
230: * @return The position of this buffer.
231: */
232: public final int position() {
233: return position;
234: }
235:
236: /**
237: * Sets this buffer's position. If the mark is defined and larger
238: * than the new position then it is discarded. <b><i>JSR 239 does
239: * not support marking and resetting.</i></b>
240: *
241: * @param newPosition The new position value; must be non-negative
242: * and no larger than the current limit.
243: *
244: * @return This buffer.
245: *
246: * @throws IllegalArgumentException If the preconditions on
247: * <code>newPosition</code> do not hold.
248: */
249: public final Buffer position(int newPosition) {
250: if (newPosition < 0 || newPosition > limit) {
251: throw new IllegalArgumentException();
252: }
253: this .position = newPosition;
254: return this ;
255: }
256:
257: /**
258: * Returns this buffer's limit.
259: *
260: * @return The limit of this buffer.
261: */
262: public final int limit() {
263: return limit;
264: }
265:
266: /**
267: * Sets this buffer's limit. If the position is larger than the
268: * new limit then it is set to the new limit. If the mark is
269: * defined and larger than the new limit then it is
270: * discarded. <b><i>JSR 239 does not support marking and
271: * resetting.</i></b>
272: *
273: * @param newLimit the new limit value.
274: *
275: * @return this buffer.
276: *
277: * @throws IllegalArgumentException if <code>newLimit</code> is
278: * negative or larger than this buffer's capacity.
279: */
280: public final Buffer limit(int newLimit) {
281: if (newLimit < 0 || newLimit > capacity) {
282: throw new IllegalArgumentException();
283: }
284: if (position > newLimit) {
285: position = newLimit;
286: }
287: this .limit = newLimit;
288: return this ;
289: }
290:
291: /**
292: * Clears this buffer. The position is set to zero, the limit is
293: * set to the capacity, and the mark is discarded. <b><i>JSR 239 does
294: * not support marking and resetting.</i></b>
295: *
296: * <p> Invoke this method before using a sequence of channel-read
297: * or <i>put</i> operations to fill this buffer. For example:
298: *
299: * <blockquote><pre>
300: * buf.clear(); // Prepare buffer for reading
301: * in.read(buf); // Read data
302: * </pre></blockquote>
303: *
304: * <p> <b><i>JSR 239 does not support channels.</i></b>
305: *
306: * <p> This method does not actually erase the data in the buffer,
307: * but it is named as if it did because it will most often be used
308: * in situations in which that might as well be the case.
309: *
310: * @return This buffer.
311: */
312: public final Buffer clear() {
313: this .position = 0;
314: this .limit = this .capacity;
315: return this ;
316: }
317:
318: /**
319: * Flips this buffer. The limit is set to the current position and
320: * then the position is set to zero. If the mark is defined then
321: * it is discarded. <b><i>JSR 239 does
322: * not support marking and resetting.</i></b>
323: *
324: * <p> After a sequence of channel-read or <i>put</i> operations, invoke
325: * this method to prepare for a sequence of channel-write or
326: * relative <i>get</i> operations. For example:
327: *
328: * <blockquote><pre>
329: * buf.put(magic); // Prepend header
330: * in.read(buf); // Read data into rest of buffer
331: * buf.flip(); // Flip buffer
332: * out.write(buf); // Write header + data to channel
333: * </pre></blockquote>
334: *
335: * <p> This method is often used in conjunction with the compact
336: * method when transferring data from one place to another.
337: *
338: * <p> <b><i>JSR 239 does not support channels.</i></b>
339: *
340: * @return This buffer.
341: */
342: public final Buffer flip() {
343: this .limit = this .position;
344: this .position = 0;
345: return this ;
346: }
347:
348: /**
349: * Rewinds this buffer. The position is set to zero and the mark
350: * is discarded. <b><i>JSR 239 does
351: * not support marking and resetting.</i></b>
352: *
353: * <p> Invoke this method before a sequence of channel-write or
354: * <i>get</i> operations, assuming that the limit has already been set
355: * appropriately. For example:
356: *
357: * <blockquote><pre>
358: * out.write(buf); // Write remaining data
359: * buf.rewind(); // Rewind buffer
360: * buf.get(array); // Copy data into array
361: * </pre></blockquote>
362: *
363: * <p> <b><i>JSR 239 does not support channels.</i></b>
364: */
365: public final Buffer rewind() {
366: this .position = 0;
367: return this ;
368: }
369:
370: /**
371: * Returns the number of elements between the current position and
372: * the limit.
373: *
374: * @return The number of elements remaining in this buffer.
375: */
376: public final int remaining() {
377: return limit - position;
378: }
379:
380: /**
381: * Tells whether there are any elements between the current
382: * position and the limit.
383: *
384: * @return <code>true</code> if, and only if, there is at least
385: * one element remaining in this buffer.
386: */
387: public final boolean hasRemaining() {
388: return position < limit;
389: }
390:
391: // Removed methods:
392: //
393: // abstract boolean isReadOnly();
394: //
395: // // Applications can maintain their own mark, use position(int)
396: // Buffer mark();
397: // Buffer reset();
398: }
|