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