• 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  *
171  * @author Mark Reinhold
172  * @author JSR-51 Expert Group
173  * @since 1.4
174  */
175 
176 public abstract class Buffer {
177 
178     /**
179      * The characteristics of Spliterators that traverse and split elements
180      * maintained in Buffers.
181      */
182     static final int SPLITERATOR_CHARACTERISTICS =
183         Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
184 
185     // Invariants: mark <= position <= limit <= capacity
186     private int mark = -1;
187     // Android-changed: position field non-private for use by Android's nio implementation classes.
188     int position = 0;
189     private int limit;
190     private int capacity;
191 
192     // Used only by direct buffers
193     // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
194     long address;
195 
196     // Android-added: _elementSizeShift field for NIOAccess class and framework native code.
197     /**
198      * The log base 2 of the element size of this buffer.  Each typed subclass
199      * (ByteBuffer, CharBuffer, etc.) is responsible for initializing this
200      * value.  The value is used by JNI code in frameworks/base/ to avoid the
201      * need for costly 'instanceof' tests.
202      */
203     final int _elementSizeShift;
204 
205     // Creates a new buffer with the given mark, position, limit, and capacity,
206     // after checking invariants.
207     //
208     // Android-added: _elementSizeShift field for NIOAccess class and framework native code.
Buffer(int mark, int pos, int lim, int cap, int elementSizeShift)209     Buffer(int mark, int pos, int lim, int cap, int elementSizeShift) {       // package-private
210         if (cap < 0)
211             throw new IllegalArgumentException("Negative capacity: " + cap);
212         this.capacity = cap;
213         limit(lim);
214         position(pos);
215         if (mark >= 0) {
216             if (mark > pos)
217                 throw new IllegalArgumentException("mark > position: ("
218                                                    + mark + " > " + pos + ")");
219             this.mark = mark;
220         }
221         // Android-added: _elementSizeShift field for NIOAccess class and framework native code.
222         _elementSizeShift = elementSizeShift;
223     }
224 
225     /**
226      * Returns an {@code IllegalArgumentException} indicating that the source
227      * and target are the same {@code Buffer}.  Intended for use in
228      * {@code put(src)} when the parameter is the {@code Buffer} on which the
229      * method is being invoked.
230      *
231      * @return  IllegalArgumentException
232      *          With a message indicating equal source and target buffers
233      */
createSameBufferException()234     static IllegalArgumentException createSameBufferException() {
235         return new IllegalArgumentException("The source buffer is this buffer");
236     }
237 
238     /**
239      * Verify that the capacity is nonnegative.
240      *
241      * @param  capacity
242      *         The new buffer's capacity, in $type$s
243      *
244      * @throws IllegalArgumentException
245      *         If the {@code capacity} is a negative integer
246      */
createCapacityException(int capacity)247     static IllegalArgumentException createCapacityException(int capacity) {
248         assert capacity < 0 : "capacity expected to be negative";
249         return new IllegalArgumentException("capacity < 0: ("
250             + capacity + " < 0)");
251     }
252 
253     /**
254      * Returns this buffer's capacity.
255      *
256      * @return  The capacity of this buffer
257      */
258     public final int capacity() {
259         return capacity;
260     }
261 
262     /**
263      * Returns this buffer's position.
264      *
265      * @return  The position of this buffer
266      */
267     public final int position() {
268         return position;
269     }
270 
271     /**
272      * Sets this buffer's position.  If the mark is defined and larger than the
273      * new position then it is discarded.
274      *
275      * @param  newPosition
276      *         The new position value; must be non-negative
277      *         and no larger than the current limit
278      *
279      * @return  This buffer
280      *
281      * @throws  IllegalArgumentException
282      *          If the preconditions on <tt>newPosition</tt> do not hold
283      */
284     public Buffer position(int newPosition) {
285         if ((newPosition > limit) || (newPosition < 0))
286             // Android-changed: Improved error message.
287             throw new IllegalArgumentException("Bad position " + newPosition + "/" + limit);
288         position = newPosition;
289         if (mark > position) mark = -1;
290         return this;
291     }
292 
293     /**
294      * Verify that {@code 0 < newPosition <= limit}
295      *
296      * @param newPosition
297      *        The new position value
298      *
299      * @throws IllegalArgumentException
300      *         If the specified position is out of bounds.
301      */
createPositionException(int newPosition)302     private IllegalArgumentException createPositionException(int newPosition) {
303         String msg = null;
304 
305         if (newPosition > limit) {
306             msg = "newPosition > limit: (" + newPosition + " > " + limit + ")";
307         } else { // assume negative
308             assert newPosition < 0 : "newPosition expected to be negative";
309             msg = "newPosition < 0: (" + newPosition + " < 0)";
310         }
311 
312         return new IllegalArgumentException(msg);
313     }
314 
315     /**
316      * Returns this buffer's limit.
317      *
318      * @return  The limit of this buffer
319      */
320     public final int limit() {
321         return limit;
322     }
323 
324     /**
325      * Sets this buffer's limit.  If the position is larger than the new limit
326      * then it is set to the new limit.  If the mark is defined and larger than
327      * the new limit then it is discarded.
328      *
329      * @param  newLimit
330      *         The new limit value; must be non-negative
331      *         and no larger than this buffer's capacity
332      *
333      * @return  This buffer
334      *
335      * @throws  IllegalArgumentException
336      *          If the preconditions on <tt>newLimit</tt> do not hold
337      */
338     public Buffer limit(int newLimit) {
339         if (newLimit > capacity | newLimit < 0)
340             throw createLimitException(newLimit);
341         limit = newLimit;
342         if (position > limit) position = limit;
343         if (mark > limit) mark = -1;
344         return this;
345     }
346 
347     /**
348      * Verify that {@code 0 < newLimit <= capacity}
349      *
350      * @param newLimit
351      *        The new limit value
352      *
353      * @throws IllegalArgumentException
354      *         If the specified limit is out of bounds.
355      */
createLimitException(int newLimit)356     private IllegalArgumentException createLimitException(int newLimit) {
357         String msg = null;
358 
359         if (newLimit > capacity) {
360             msg = "newLimit > capacity: (" + newLimit + " > " + capacity + ")";
361         } else { // assume negative
362             assert newLimit < 0 : "newLimit expected to be negative";
363             msg = "newLimit < 0: (" + newLimit + " < 0)";
364         }
365 
366         return new IllegalArgumentException(msg);
367     }
368 
369     /**
370      * Sets this buffer's mark at its position.
371      *
372      * @return  This buffer
373      */
374     public Buffer mark() {
375         mark = position;
376         return this;
377     }
378 
379     /**
380      * Resets this buffer's position to the previously-marked position.
381      *
382      * <p> Invoking this method neither changes nor discards the mark's
383      * value. </p>
384      *
385      * @return  This buffer
386      *
387      * @throws  InvalidMarkException
388      *          If the mark has not been set
389      */
390     public Buffer reset() {
391         int m = mark;
392         if (m < 0)
393             throw new InvalidMarkException();
394         position = m;
395         return this;
396     }
397 
398     /**
399      * Clears this buffer.  The position is set to zero, the limit is set to
400      * the capacity, and the mark is discarded.
401      *
402      * <p> Invoke this method before using a sequence of channel-read or
403      * <i>put</i> operations to fill this buffer.  For example:
404      *
405      * <blockquote><pre>
406      * buf.clear();     // Prepare buffer for reading
407      * in.read(buf);    // Read data</pre></blockquote>
408      *
409      * <p> This method does not actually erase the data in the buffer, but it
410      * is named as if it did because it will most often be used in situations
411      * in which that might as well be the case. </p>
412      *
413      * @return  This buffer
414      */
415     public Buffer clear() {
416         position = 0;
417         limit = capacity;
418         mark = -1;
419         return this;
420     }
421 
422     /**
423      * Flips this buffer.  The limit is set to the current position and then
424      * the position is set to zero.  If the mark is defined then it is
425      * discarded.
426      *
427      * <p> After a sequence of channel-read or <i>put</i> operations, invoke
428      * this method to prepare for a sequence of channel-write or relative
429      * <i>get</i> operations.  For example:
430      *
431      * <blockquote><pre>
432      * buf.put(magic);    // Prepend header
433      * in.read(buf);      // Read data into rest of buffer
434      * buf.flip();        // Flip buffer
435      * out.write(buf);    // Write header + data to channel</pre></blockquote>
436      *
437      * <p> This method is often used in conjunction with the {@link
438      * java.nio.ByteBuffer#compact compact} method when transferring data from
439      * one place to another.  </p>
440      *
441      * @return  This buffer
442      */
443     public Buffer flip() {
444         limit = position;
445         position = 0;
446         mark = -1;
447         return this;
448     }
449 
450     /**
451      * Rewinds this buffer.  The position is set to zero and the mark is
452      * discarded.
453      *
454      * <p> Invoke this method before a sequence of channel-write or <i>get</i>
455      * operations, assuming that the limit has already been set
456      * appropriately.  For example:
457      *
458      * <blockquote><pre>
459      * out.write(buf);    // Write remaining data
460      * buf.rewind();      // Rewind buffer
461      * buf.get(array);    // Copy data into array</pre></blockquote>
462      *
463      * @return  This buffer
464      */
465     public Buffer rewind() {
466         position = 0;
467         mark = -1;
468         return this;
469     }
470 
471     /**
472      * Returns the number of elements between the current position and the
473      * limit.
474      *
475      * @return  The number of elements remaining in this buffer
476      */
477     public final int remaining() {
478         return limit - position;
479     }
480 
481     /**
482      * Tells whether there are any elements between the current position and
483      * the limit.
484      *
485      * @return  <tt>true</tt> if, and only if, there is at least one element
486      *          remaining in this buffer
487      */
488     public final boolean hasRemaining() {
489         return position < limit;
490     }
491 
492     /**
493      * Tells whether or not this buffer is read-only.
494      *
495      * @return  <tt>true</tt> if, and only if, this buffer is read-only
496      */
497     public abstract boolean isReadOnly();
498 
499     /**
500      * Tells whether or not this buffer is backed by an accessible
501      * array.
502      *
503      * <p> If this method returns <tt>true</tt> then the {@link #array() array}
504      * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
505      * </p>
506      *
507      * @return  <tt>true</tt> if, and only if, this buffer
508      *          is backed by an array and is not read-only
509      *
510      * @since 1.6
511      */
512     public abstract boolean hasArray();
513 
514     /**
515      * Returns the array that backs this
516      * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
517      *
518      * <p> This method is intended to allow array-backed buffers to be
519      * passed to native code more efficiently. Concrete subclasses
520      * provide more strongly-typed return values for this method.
521      *
522      * <p> Modifications to this buffer's content will cause the returned
523      * array's content to be modified, and vice versa.
524      *
525      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
526      * method in order to ensure that this buffer has an accessible backing
527      * array.  </p>
528      *
529      * @return  The array that backs this buffer
530      *
531      * @throws  ReadOnlyBufferException
532      *          If this buffer is backed by an array but is read-only
533      *
534      * @throws  UnsupportedOperationException
535      *          If this buffer is not backed by an accessible array
536      *
537      * @since 1.6
538      */
539     public abstract Object array();
540 
541     /**
542      * Returns the offset within this buffer's backing array of the first
543      * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
544      *
545      * <p> If this buffer is backed by an array then buffer position <i>p</i>
546      * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
547      *
548      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
549      * method in order to ensure that this buffer has an accessible backing
550      * array.  </p>
551      *
552      * @return  The offset within this buffer's array
553      *          of the first element of the buffer
554      *
555      * @throws  ReadOnlyBufferException
556      *          If this buffer is backed by an array but is read-only
557      *
558      * @throws  UnsupportedOperationException
559      *          If this buffer is not backed by an accessible array
560      *
561      * @since 1.6
562      */
563     public abstract int arrayOffset();
564 
565     /**
566      * Tells whether or not this buffer is
567      * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
568      *
569      * @return  <tt>true</tt> if, and only if, this buffer is direct
570      *
571      * @since 1.6
572      */
573     public abstract boolean isDirect();
574 
575     /**
576      * Creates a new buffer whose content is a shared subsequence of
577      * this buffer's content.
578      *
579      * <p> The content of the new buffer will start at this buffer's current
580      * position.  Changes to this buffer's content will be visible in the new
581      * buffer, and vice versa; the two buffers' position, limit, and mark
582      * values will be independent.
583      *
584      * <p> The new buffer's position will be zero, its capacity and its limit
585      * will be the number of elements remaining in this buffer, its mark will be
586      * undefined. The new buffer will be direct if, and only if, this buffer is
587      * direct, and it will be read-only if, and only if, this buffer is
588      * read-only.  </p>
589      *
590      * @return  The new buffer
591      *
592      * @since 9
593      */
594     public abstract Buffer slice();
595 
596     /**
597      * Creates a new buffer whose content is a shared subsequence of
598      * this buffer's content.
599      *
600      * <p> The content of the new buffer will start at position {@code index}
601      * in this buffer, and will contain {@code length} elements. Changes to
602      * this buffer's content will be visible in the new buffer, and vice versa;
603      * the two buffers' position, limit, and mark values will be independent.
604      *
605      * <p> The new buffer's position will be zero, its capacity and its limit
606      * will be {@code length}, its mark will be undefined. The new buffer will
607      * be direct if, and only if, this buffer is direct, and it will be
608      * read-only if, and only if, this buffer is read-only.  </p>
609      *
610      * @param   index
611      *          The position in this buffer at which the content of the new
612      *          buffer will start; must be non-negative and no larger than
613      *          {@link #limit() limit()}
614      *
615      * @param   length
616      *          The number of elements the new buffer will contain; must be
617      *          non-negative and no larger than {@code limit() - index}
618      *
619      * @return  The new buffer
620      *
621      * @throws  IndexOutOfBoundsException
622      *          If {@code index} is negative or greater than {@code limit()},
623      *          {@code length} is negative, or {@code length > limit() - index}
624      *
625      * @since 13
626      */
627     public abstract Buffer slice(int index, int length);
628 
629     /**
630      * Creates a new buffer that shares this buffer's content.
631      *
632      * <p> The content of the new buffer will be that of this buffer.  Changes
633      * to this buffer's content will be visible in the new buffer, and vice
634      * versa; the two buffers' position, limit, and mark values will be
635      * independent.
636      *
637      * <p> The new buffer's capacity, limit, position and mark values will be
638      * identical to those of this buffer. The new buffer will be direct if, and
639      * only if, this buffer is direct, and it will be read-only if, and only if,
640      * this buffer is read-only.  </p>
641      *
642      * @return  The new buffer
643      *
644      * @since 9
645      */
646     public abstract Buffer duplicate();
647 
648 
649     // -- Package-private methods for bounds checking, etc. --
650 
651     /**
652      *
653      * @return the base reference, paired with the address
654      * field, which in combination can be used for unsafe access into a heap
655      * buffer or direct byte buffer (and views of).
656      */
657     abstract Object base();
658 
659     /**
660      * Checks the current position against the limit, throwing a {@link
661      * BufferUnderflowException} if it is not smaller than the limit, and then
662      * increments the position.
663      *
664      * @return  The current position value, before it is incremented
665      */
666     final int nextGetIndex() {                          // package-private
667         if (position >= limit)
668             throw new BufferUnderflowException();
669         return position++;
670     }
671 
672     final int nextGetIndex(int nb) {                    // package-private
673         if (limit - position < nb)
674             throw new BufferUnderflowException();
675         int p = position;
676         position += nb;
677         return p;
678     }
679 
680     /**
681      * Checks the current position against the limit, throwing a {@link
682      * BufferOverflowException} if it is not smaller than the limit, and then
683      * increments the position.
684      *
685      * @return  The current position value, before it is incremented
686      */
687     final int nextPutIndex() {                          // package-private
688         if (position >= limit)
689             throw new BufferOverflowException();
690         return position++;
691     }
692 
693     final int nextPutIndex(int nb) {                    // package-private
694         if (limit - position < nb)
695             throw new BufferOverflowException();
696         int p = position;
697         position += nb;
698         return p;
699     }
700 
701     /**
702      * Checks the given index against the limit, throwing an {@link
703      * IndexOutOfBoundsException} if it is not smaller than the limit
704      * or is smaller than zero.
705      */
706     final int checkIndex(int i) {                       // package-private
707         if ((i < 0) || (i >= limit))
708             // Android-changed: Add bounds details to exception.
709             throw new IndexOutOfBoundsException(
710                     "index=" + i + " out of bounds (limit=" + limit + ")");
711         return i;
712     }
713 
714     final int checkIndex(int i, int nb) {               // package-private
715         if ((i < 0) || (nb > limit - i))
716             // Android-changed: Add bounds details to exception.
717             throw new IndexOutOfBoundsException(
718                     "index=" + i + " out of bounds (limit=" + limit + ", nb=" + nb + ")");
719         return i;
720     }
721 
722     final int markValue() {                             // package-private
723         return mark;
724     }
725 
726     final void truncate() {                             // package-private
727         mark = -1;
728         position = 0;
729         limit = 0;
730         capacity = 0;
731     }
732 
733     final void discardMark() {                          // package-private
734         mark = -1;
735     }
736 
737     static void checkBounds(int off, int len, int size) { // package-private
738         if ((off | len | (off + len) | (size - (off + len))) < 0)
739             // Android-changed: Add bounds details to exception.
740             throw new IndexOutOfBoundsException(
741                     "off=" + off + ", len=" + len + " out of bounds (size=" + size + ")");
742     }
743 
744     // Android-added: getElementSizeShift() method for testing.
745     /**
746      * For testing only. This field is accessed directly via JNI from frameworks code.
747      *
748      * @hide
749      */
750     public int getElementSizeShift() {
751         return _elementSizeShift;
752     }
753 
754 }
755