1 /*
2 * Copyright (c) 2000, 2013, 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
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 //
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 */
216 public final int capacity() {
217 return capacity;
218 }
219
223 * @return The position of this buffer
224 */
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 */
242 public Buffer position(int newPosition) {
243 if ((newPosition > limit) || (newPosition < 0))
244 throw new IllegalArgumentException();
245 position = newPosition;
246 if (mark > position) mark = -1;
247 return this;
248 }
249
250 /**
251 * Returns this buffer's limit.
252 *
253 * @return The limit of this buffer
254 */
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 */
273 public Buffer limit(int newLimit) {
274 if ((newLimit > capacity) || (newLimit < 0))
275 throw new IllegalArgumentException();
276 limit = newLimit;
277 if (position > limit) position = limit;
278 if (mark > limit) mark = -1;
279 return this;
280 }
281
282 /**
283 * Sets this buffer's mark at its position.
284 *
285 * @return This buffer
286 */
287 public 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 */
468 * @throws ReadOnlyBufferException
469 * If this buffer is backed by an array but is read-only
470 *
471 * @throws UnsupportedOperationException
472 * If this buffer is not backed by an accessible array
473 *
474 * @since 1.6
475 */
476 public abstract int arrayOffset();
477
478 /**
479 * Tells whether or not this buffer is
480 * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
481 *
482 * @return <tt>true</tt> if, and only if, this buffer is direct
483 *
484 * @since 1.6
485 */
486 public abstract boolean isDirect();
487
488
489 // -- Package-private methods for bounds checking, etc. --
490
491 /**
492 * Checks the current position against the limit, throwing a {@link
493 * BufferUnderflowException} if it is not smaller than the limit, and then
494 * increments the position.
495 *
496 * @return The current position value, before it is incremented
497 */
498 final int nextGetIndex() { // package-private
499 if (position >= limit)
500 throw new BufferUnderflowException();
501 return position++;
502 }
503
504 final int nextGetIndex(int nb) { // package-private
505 if (limit - position < nb)
506 throw new BufferUnderflowException();
507 int p = position;
508 position += nb;
550 final int markValue() { // package-private
551 return mark;
552 }
553
554 final void truncate() { // package-private
555 mark = -1;
556 position = 0;
557 limit = 0;
558 capacity = 0;
559 }
560
561 final void discardMark() { // package-private
562 mark = -1;
563 }
564
565 static void checkBounds(int off, int len, int size) { // package-private
566 if ((off | len | (off + len) | (size - (off + len))) < 0)
567 throw new IndexOutOfBoundsException();
568 }
569
570 }
|
1 /*
2 * Copyright (c) 2000, 2015, 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
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 //
197 Buffer(int mark, int pos, int lim, int cap) { // package-private
198 if (cap < 0) {
199 throw negativeCapacityException(cap);
200 }
201 this.capacity = cap;
202 limit(lim);
203 position(pos);
204 if (mark >= 0) {
205 if (mark > pos)
206 throw new IllegalArgumentException("mark > position: ("
207 + mark + " > " + pos + ")");
208 this.mark = mark;
209 }
210 }
211
212 /**
213 * Returns this buffer's capacity.
214 *
215 * @return The capacity of this buffer
216 */
217 public final int capacity() {
218 return capacity;
219 }
220
224 * @return The position of this buffer
225 */
226 public final int position() {
227 return position;
228 }
229
230 /**
231 * Sets this buffer's position. If the mark is defined and larger than the
232 * new position then it is discarded.
233 *
234 * @param newPosition
235 * The new position value; must be non-negative
236 * and no larger than the current limit
237 *
238 * @return This buffer
239 *
240 * @throws IllegalArgumentException
241 * If the preconditions on <tt>newPosition</tt> do not hold
242 */
243 public Buffer position(int newPosition) {
244 if ((newPosition > limit) || (newPosition < 0)) {
245 throw positionOutOfBoundsException(newPosition);
246 }
247 position = newPosition;
248 if (mark > position) mark = -1;
249 return this;
250 }
251
252 /**
253 * Verify that {@code 0 < newPosition <= limit}
254 *
255 * @param newPosition
256 * The new position value
257 *
258 * @throws IllegalArgumentException
259 * If the specified position is out of bounds.
260 */
261 private IllegalArgumentException positionOutOfBoundsException(int newPosition) {
262 String msg = null;
263
264 if (newPosition > limit) {
265 msg = "newPosition > limit: (" + newPosition + " > " + limit + ")";
266 } else { // assume negative
267 assert newPosition < 0 : "newPosition expected to be negative";
268 msg = "newPosition < 0: (" + newPosition + " < 0)";
269 }
270
271 return new IllegalArgumentException(msg);
272 }
273
274 /**
275 * Returns this buffer's limit.
276 *
277 * @return The limit of this buffer
278 */
279 public final int limit() {
280 return limit;
281 }
282
283 /**
284 * Sets this buffer's limit. If the position is larger than the new limit
285 * then it is set to the new limit. If the mark is defined and larger than
286 * the new limit then it is discarded.
287 *
288 * @param newLimit
289 * The new limit value; must be non-negative
290 * and no larger than this buffer's capacity
291 *
292 * @return This buffer
293 *
294 * @throws IllegalArgumentException
295 * If the preconditions on <tt>newLimit</tt> do not hold
296 */
297 public Buffer limit(int newLimit) {
298 if (newLimit > capacity || newLimit < 0) {
299 throw limitOutOfBoundsException(newLimit);
300 }
301 limit = newLimit;
302 if (position > limit) position = limit;
303 if (mark > limit) mark = -1;
304 return this;
305 }
306
307 /**
308 * Verify that {@code 0 < newLimit <= capacity}
309 *
310 * @param newLimit
311 * The new limit value
312 *
313 * @throws IllegalArgumentException
314 * If the specified limit is out of bounds.
315 */
316 private IllegalArgumentException limitOutOfBoundsException(int newLimit) {
317 String msg = null;
318
319 if (newLimit > capacity) {
320 msg = "newLimit > capacity: (" + newLimit + " > " + capacity + ")";
321 } else { // assume negative
322 assert newLimit < 0 : "newLimit expected to be negative";
323 msg = "newLimit < 0: (" + newLimit + " < 0)";
324 }
325
326 return new IllegalArgumentException(msg);
327 }
328
329 /**
330 * Sets this buffer's mark at its position.
331 *
332 * @return This buffer
333 */
334 public Buffer mark() {
335 mark = position;
336 return this;
337 }
338
339 /**
340 * Resets this buffer's position to the previously-marked position.
341 *
342 * <p> Invoking this method neither changes nor discards the mark's
343 * value. </p>
344 *
345 * @return This buffer
346 *
347 * @throws InvalidMarkException
348 * If the mark has not been set
349 */
515 * @throws ReadOnlyBufferException
516 * If this buffer is backed by an array but is read-only
517 *
518 * @throws UnsupportedOperationException
519 * If this buffer is not backed by an accessible array
520 *
521 * @since 1.6
522 */
523 public abstract int arrayOffset();
524
525 /**
526 * Tells whether or not this buffer is
527 * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
528 *
529 * @return <tt>true</tt> if, and only if, this buffer is direct
530 *
531 * @since 1.6
532 */
533 public abstract boolean isDirect();
534
535 // -- Package-private methods for bounds checking, etc. --
536
537 /**
538 * Checks the current position against the limit, throwing a {@link
539 * BufferUnderflowException} if it is not smaller than the limit, and then
540 * increments the position.
541 *
542 * @return The current position value, before it is incremented
543 */
544 final int nextGetIndex() { // package-private
545 if (position >= limit)
546 throw new BufferUnderflowException();
547 return position++;
548 }
549
550 final int nextGetIndex(int nb) { // package-private
551 if (limit - position < nb)
552 throw new BufferUnderflowException();
553 int p = position;
554 position += nb;
596 final int markValue() { // package-private
597 return mark;
598 }
599
600 final void truncate() { // package-private
601 mark = -1;
602 position = 0;
603 limit = 0;
604 capacity = 0;
605 }
606
607 final void discardMark() { // package-private
608 mark = -1;
609 }
610
611 static void checkBounds(int off, int len, int size) { // package-private
612 if ((off | len | (off + len) | (size - (off + len))) < 0)
613 throw new IndexOutOfBoundsException();
614 }
615
616 /**
617 * Verify that the parameter is not this {@code Buffer}. Intended for
618 * checking that in {@code put(src)} the parameter is not the {@code Buffer}
619 * on which the method is being invoked.
620 *
621 * @param src
622 * The buffer to compare with.
623 *
624 * @throws IllegalArgumentException
625 * If the source buffer is this buffer
626 */
627 void checkSourceBufferNotThisBuffer(Buffer src) { // package-private
628 if (src == this) {
629 throw new IllegalArgumentException("The source buffer is this buffer");
630 }
631 }
632
633 /**
634 * Verify that the capacity is nonnegative.
635 *
636 * @param capacity
637 * The new buffer's capacity, in $type$s
638 *
639 * @throws IllegalArgumentException
640 * If the <tt>capacity</tt> is a negative integer
641 */
642 static IllegalArgumentException negativeCapacityException(int capacity) { // package-private
643 assert capacity < 0 : "capacity expected to be negative";
644 return new IllegalArgumentException("capacity < 0: ("
645 + capacity + " < 0)");
646 }
647 }
|