• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.nio;
28 
29 import java.util.Spliterator;
30 
31 /**
32  * A container for data of a specific primitive type.
33  *
34  * <p> A buffer is a linear, finite sequence of elements of a specific
35  * primitive type.  Aside from its content, the essential properties of a
36  * buffer are its capacity, limit, and position: </p>
37  *
38  * <blockquote>
39  *
40  * <p> A buffer's <i>capacity</i> is the number of elements it contains.  The
41  * capacity of a buffer is never negative and never changes.  </p>
42  *
43  * <p> A buffer's <i>limit</i> is the index of the first element that should
44  * not be read or written.  A buffer's limit is never negative and is never
45  * greater than its capacity.  </p>
46  *
47  * <p> A buffer's <i>position</i> is the index of the next element to be
48  * read or written.  A buffer's position is never negative and is never
49  * greater than its limit.  </p>
50  *
51  * </blockquote>
52  *
53  * <p> There is one subclass of this class for each non-boolean primitive type.
54  *
55  *
56  * <h2> Transferring data </h2>
57  *
58  * <p> Each subclass of this class defines two categories of <i>get</i> and
59  * <i>put</i> operations: </p>
60  *
61  * <blockquote>
62  *
63  * <p> <i>Relative</i> operations read or write one or more elements starting
64  * at the current position and then increment the position by the number of
65  * elements transferred.  If the requested transfer exceeds the limit then a
66  * relative <i>get</i> operation throws a {@link BufferUnderflowException}
67  * and a relative <i>put</i> operation throws a {@link
68  * BufferOverflowException}; in either case, no data is transferred.  </p>
69  *
70  * <p> <i>Absolute</i> operations take an explicit element index and do not
71  * affect the position.  Absolute <i>get</i> and <i>put</i> operations throw
72  * an {@link IndexOutOfBoundsException} if the index argument exceeds the
73  * limit.  </p>
74  *
75  * </blockquote>
76  *
77  * <p> Data may also, of course, be transferred in to or out of a buffer by the
78  * I/O operations of an appropriate channel, which are always relative to the
79  * current position.
80  *
81  *
82  * <h2> Marking and resetting </h2>
83  *
84  * <p> A buffer's <i>mark</i> is the index to which its position will be reset
85  * when the {@link #reset reset} method is invoked.  The mark is not always
86  * defined, but when it is defined it is never negative and is never greater
87  * than the position.  If the mark is defined then it is discarded when the
88  * position or the limit is adjusted to a value smaller than the mark.  If the
89  * mark is not defined then invoking the {@link #reset reset} method causes an
90  * {@link InvalidMarkException} to be thrown.
91  *
92  *
93  * <h2> Invariants </h2>
94  *
95  * <p> The following invariant holds for the mark, position, limit, and
96  * capacity values:
97  *
98  * <blockquote>
99  * <tt>0</tt> <tt>&lt;=</tt>
100  * <i>mark</i> <tt>&lt;=</tt>
101  * <i>position</i> <tt>&lt;=</tt>
102  * <i>limit</i> <tt>&lt;=</tt>
103  * <i>capacity</i>
104  * </blockquote>
105  *
106  * <p> A newly-created buffer always has a position of zero and a mark that is
107  * undefined.  The initial limit may be zero, or it may be some other value
108  * that depends upon the type of the buffer and the manner in which it is
109  * constructed.  Each element of a newly-allocated buffer is initialized
110  * to zero.
111  *
112  *
113  * <h2> Clearing, flipping, and rewinding </h2>
114  *
115  * <p> In addition to methods for accessing the position, limit, and capacity
116  * values and for marking and resetting, this class also defines the following
117  * operations upon buffers:
118  *
119  * <ul>
120  *
121  * <li><p> {@link #clear} makes a buffer ready for a new sequence of
122  * channel-read or relative <i>put</i> operations: It sets the limit to the
123  * capacity and the position to zero.  </p></li>
124  *
125  * <li><p> {@link #flip} makes a buffer ready for a new sequence of
126  * channel-write or relative <i>get</i> operations: It sets the limit to the
127  * current position and then sets the position to zero.  </p></li>
128  *
129  * <li><p> {@link #rewind} makes a buffer ready for re-reading the data that
130  * it already contains: It leaves the limit unchanged and sets the position
131  * to zero.  </p></li>
132  *
133  * </ul>
134  *
135  *
136  * <h2> Read-only buffers </h2>
137  *
138  * <p> Every buffer is readable, but not every buffer is writable.  The
139  * mutation methods of each buffer class are specified as <i>optional
140  * operations</i> that will throw a {@link ReadOnlyBufferException} when
141  * invoked upon a read-only buffer.  A read-only buffer does not allow its
142  * content to be changed, but its mark, position, and limit values are mutable.
143  * Whether or not a buffer is read-only may be determined by invoking its
144  * {@link #isReadOnly isReadOnly} method.
145  *
146  *
147  * <h2> Thread safety </h2>
148  *
149  * <p> Buffers are not safe for use by multiple concurrent threads.  If a
150  * buffer is to be used by more than one thread then access to the buffer
151  * should be controlled by appropriate synchronization.
152  *
153  *
154  * <h2> Invocation chaining </h2>
155  *
156  * <p> Methods in this class that do not otherwise have a value to return are
157  * specified to return the buffer upon which they are invoked.  This allows
158  * method invocations to be chained; for example, the sequence of statements
159  *
160  * <blockquote><pre>
161  * b.flip();
162  * b.position(23);
163  * b.limit(42);</pre></blockquote>
164  *
165  * can be replaced by the single, more compact statement
166  *
167  * <blockquote><pre>
168  * b.flip().position(23).limit(42);</pre></blockquote>
169  *
170  * @author Mark Reinhold
171  * @author JSR-51 Expert Group
172  * @since 1.4
173  */
174 
175 public abstract class Buffer {
176 
177     /**
178      * The characteristics of Spliterators that traverse and split elements
179      * maintained in Buffers.
180      */
181     static final int SPLITERATOR_CHARACTERISTICS =
182         Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
183 
184     // Invariants: mark <= position <= limit <= capacity
185     private int mark = -1;
186     int position = 0;
187     private int limit;
188     private int capacity;
189 
190     // Used only by direct buffers
191     // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
192     long address;
193 
194     /**
195      * The log base 2 of the element size of this buffer.  Each typed subclass
196      * (ByteBuffer, CharBuffer, etc.) is responsible for initializing this
197      * value.  The value is used by JNI code in frameworks/base/ to avoid the
198      * need for costly 'instanceof' tests.
199      */
200     final int _elementSizeShift;
201 
202     // Creates a new buffer with the given mark, position, limit, and capacity,
203     // after checking invariants.
204     //
Buffer(int mark, int pos, int lim, int cap, int elementSizeShift)205     Buffer(int mark, int pos, int lim, int cap, int elementSizeShift) {       // package-private
206         if (cap < 0)
207             throw new IllegalArgumentException("Negative capacity: " + cap);
208         this.capacity = cap;
209         limit(lim);
210         position(pos);
211         if (mark >= 0) {
212             if (mark > pos)
213                 throw new IllegalArgumentException("mark > position: ("
214                         + mark + " > " + pos + ")");
215             this.mark = mark;
216         }
217         _elementSizeShift = elementSizeShift;
218     }
219 
220     /**
221      * Returns this buffer's capacity.
222      *
223      * @return The capacity of this buffer
224      */
capacity()225     public final int capacity() {
226         return capacity;
227     }
228 
229     /**
230      * Returns this buffer's position.
231      *
232      * @return The position of this buffer
233      */
position()234     public final int position() {
235         return position;
236     }
237 
238     /**
239      * Sets this buffer's position.  If the mark is defined and larger than the
240      * new position then it is discarded.
241      *
242      * @param newPosition The new position value; must be non-negative
243      *                    and no larger than the current limit
244      * @return This buffer
245      * @throws IllegalArgumentException If the preconditions on <tt>newPosition</tt> do not hold
246      */
position(int newPosition)247     public final Buffer position(int newPosition) {
248         if ((newPosition > limit) || (newPosition < 0))
249             throw new IllegalArgumentException("Bad position " + newPosition + "/" + limit);
250         position = newPosition;
251         if (mark > position) mark = -1;
252         return this;
253     }
254 
255     /**
256      * Returns this buffer's limit.
257      *
258      * @return The limit of this buffer
259      */
limit()260     public final int limit() {
261         return limit;
262     }
263 
264     /**
265      * Sets this buffer's limit.  If the position is larger than the new limit
266      * then it is set to the new limit.  If the mark is defined and larger than
267      * the new limit then it is discarded.
268      *
269      * @param newLimit The new limit value; must be non-negative
270      *                 and no larger than this buffer's capacity
271      * @return This buffer
272      * @throws IllegalArgumentException If the preconditions on <tt>newLimit</tt> do not hold
273      */
limit(int newLimit)274     public final Buffer limit(int newLimit) {
275         if ((newLimit > capacity) || (newLimit < 0))
276             throw new IllegalArgumentException();
277         limit = newLimit;
278         if (position > limit) position = limit;
279         if (mark > limit) mark = -1;
280         return this;
281     }
282 
283     /**
284      * Sets this buffer's mark at its position.
285      *
286      * @return This buffer
287      */
mark()288     public final Buffer mark() {
289         mark = position;
290         return this;
291     }
292 
293     /**
294      * Resets this buffer's position to the previously-marked position.
295      *
296      * <p> Invoking this method neither changes nor discards the mark's
297      * value. </p>
298      *
299      * @return This buffer
300      * @throws InvalidMarkException If the mark has not been set
301      */
reset()302     public final Buffer reset() {
303         int m = mark;
304         if (m < 0)
305             throw new InvalidMarkException();
306         position = m;
307         return this;
308     }
309 
310     /**
311      * Clears this buffer.  The position is set to zero, the limit is set to
312      * the capacity, and the mark is discarded.
313      *
314      * <p> Invoke this method before using a sequence of channel-read or
315      * <i>put</i> operations to fill this buffer.  For example:
316      *
317      * <blockquote><pre>
318      * buf.clear();     // Prepare buffer for reading
319      * in.read(buf);    // Read data</pre></blockquote>
320      *
321      * <p> This method does not actually erase the data in the buffer, but it
322      * is named as if it did because it will most often be used in situations
323      * in which that might as well be the case. </p>
324      *
325      * @return This buffer
326      */
clear()327     public final Buffer clear() {
328         position = 0;
329         limit = capacity;
330         mark = -1;
331         return this;
332     }
333 
334     /**
335      * Flips this buffer.  The limit is set to the current position and then
336      * the position is set to zero.  If the mark is defined then it is
337      * discarded.
338      *
339      * <p> After a sequence of channel-read or <i>put</i> operations, invoke
340      * this method to prepare for a sequence of channel-write or relative
341      * <i>get</i> operations.  For example:
342      *
343      * <blockquote><pre>
344      * buf.put(magic);    // Prepend header
345      * in.read(buf);      // Read data into rest of buffer
346      * buf.flip();        // Flip buffer
347      * out.write(buf);    // Write header + data to channel</pre></blockquote>
348      *
349      * <p> This method is often used in conjunction with the {@link
350      * java.nio.ByteBuffer#compact compact} method when transferring data from
351      * one place to another.  </p>
352      *
353      * @return This buffer
354      */
flip()355     public final Buffer flip() {
356         limit = position;
357         position = 0;
358         mark = -1;
359         return this;
360     }
361 
362     /**
363      * Rewinds this buffer.  The position is set to zero and the mark is
364      * discarded.
365      *
366      * <p> Invoke this method before a sequence of channel-write or <i>get</i>
367      * operations, assuming that the limit has already been set
368      * appropriately.  For example:
369      *
370      * <blockquote><pre>
371      * out.write(buf);    // Write remaining data
372      * buf.rewind();      // Rewind buffer
373      * buf.get(array);    // Copy data into array</pre></blockquote>
374      *
375      * @return This buffer
376      */
rewind()377     public final Buffer rewind() {
378         position = 0;
379         mark = -1;
380         return this;
381     }
382 
383     /**
384      * Returns the number of elements between the current position and the
385      * limit.
386      *
387      * @return The number of elements remaining in this buffer
388      */
remaining()389     public final int remaining() {
390         return limit - position;
391     }
392 
393     /**
394      * Tells whether there are any elements between the current position and
395      * the limit.
396      *
397      * @return <tt>true</tt> if, and only if, there is at least one element
398      * remaining in this buffer
399      */
hasRemaining()400     public final boolean hasRemaining() {
401         return position < limit;
402     }
403 
404     /**
405      * Tells whether or not this buffer is read-only.
406      *
407      * @return <tt>true</tt> if, and only if, this buffer is read-only
408      */
isReadOnly()409     public abstract boolean isReadOnly();
410 
411     /**
412      * Tells whether or not this buffer is backed by an accessible
413      * array.
414      *
415      * <p> If this method returns <tt>true</tt> then the {@link #array() array}
416      * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
417      * </p>
418      *
419      * @return <tt>true</tt> if, and only if, this buffer
420      * is backed by an array and is not read-only
421      * @since 1.6
422      */
hasArray()423     public abstract boolean hasArray();
424 
425     /**
426      * Returns the array that backs this
427      * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
428      *
429      * <p> This method is intended to allow array-backed buffers to be
430      * passed to native code more efficiently. Concrete subclasses
431      * provide more strongly-typed return values for this method.
432      *
433      * <p> Modifications to this buffer's content will cause the returned
434      * array's content to be modified, and vice versa.
435      *
436      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
437      * method in order to ensure that this buffer has an accessible backing
438      * array.  </p>
439      *
440      * @return The array that backs this buffer
441      * @throws ReadOnlyBufferException       If this buffer is backed by an array but is read-only
442      * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
443      * @since 1.6
444      */
array()445     public abstract Object array();
446 
447     /**
448      * Returns the offset within this buffer's backing array of the first
449      * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
450      *
451      * <p> If this buffer is backed by an array then buffer position <i>p</i>
452      * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
453      *
454      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
455      * method in order to ensure that this buffer has an accessible backing
456      * array.  </p>
457      *
458      * @return The offset within this buffer's array
459      * of the first element of the buffer
460      * @throws ReadOnlyBufferException       If this buffer is backed by an array but is read-only
461      * @throws UnsupportedOperationException If this buffer is not backed by an accessible array
462      * @since 1.6
463      */
arrayOffset()464     public abstract int arrayOffset();
465 
466     /**
467      * Tells whether or not this buffer is
468      * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
469      *
470      * @return <tt>true</tt> if, and only if, this buffer is direct
471      * @since 1.6
472      */
isDirect()473     public abstract boolean isDirect();
474 
475 
476     // -- Package-private methods for bounds checking, etc. --
477 
478     /**
479      * Checks the current position against the limit, throwing a {@link
480      * BufferUnderflowException} if it is not smaller than the limit, and then
481      * increments the position.
482      *
483      * @return The current position value, before it is incremented
484      */
nextGetIndex()485     final int nextGetIndex() {                          // package-private
486         if (position >= limit)
487             throw new BufferUnderflowException();
488         return position++;
489     }
490 
nextGetIndex(int nb)491     final int nextGetIndex(int nb) {                    // package-private
492         if (limit - position < nb)
493             throw new BufferUnderflowException();
494         int p = position;
495         position += nb;
496         return p;
497     }
498 
499     /**
500      * Checks the current position against the limit, throwing a {@link
501      * BufferOverflowException} if it is not smaller than the limit, and then
502      * increments the position.
503      *
504      * @return The current position value, before it is incremented
505      */
nextPutIndex()506     final int nextPutIndex() {                          // package-private
507         if (position >= limit)
508             throw new BufferOverflowException();
509         return position++;
510     }
511 
nextPutIndex(int nb)512     final int nextPutIndex(int nb) {                    // package-private
513         if (limit - position < nb)
514             throw new BufferOverflowException();
515         int p = position;
516         position += nb;
517         return p;
518     }
519 
520     /**
521      * Checks the given index against the limit, throwing an {@link
522      * IndexOutOfBoundsException} if it is not smaller than the limit
523      * or is smaller than zero.
524      */
checkIndex(int i)525     final int checkIndex(int i) {                       // package-private
526         if ((i < 0) || (i >= limit))
527             // Android-changed: Add bounds details to exception.
528             throw new IndexOutOfBoundsException(
529                     "index=" + i + " out of bounds (limit=" + limit + ")");
530         return i;
531     }
532 
checkIndex(int i, int nb)533     final int checkIndex(int i, int nb) {               // package-private
534         if ((i < 0) || (nb > limit - i))
535             // Android-changed: Add bounds details to exception.
536             throw new IndexOutOfBoundsException(
537                     "index=" + i + " out of bounds (limit=" + limit + ", nb=" + nb + ")");
538         return i;
539     }
540 
markValue()541     final int markValue() {                             // package-private
542         return mark;
543     }
544 
truncate()545     final void truncate() {                             // package-private
546         mark = -1;
547         position = 0;
548         limit = 0;
549         capacity = 0;
550     }
551 
discardMark()552     final void discardMark() {                          // package-private
553         mark = -1;
554     }
555 
checkBounds(int off, int len, int size)556     static void checkBounds(int off, int len, int size) { // package-private
557         if ((off | len | (off + len) | (size - (off + len))) < 0)
558             // Android-changed: Add bounds details to exception.
559             throw new IndexOutOfBoundsException(
560                     "off=" + off + ", len=" + len + " out of bounds (size=" + size + ")");
561     }
562 
563     /**
564      * For testing only. This field is accessed directly via JNI from frameworks code.
565      *
566      * @hide
567      */
getElementSizeShift()568     public int getElementSizeShift() {
569         return _elementSizeShift;
570     }
571 
572 }
573