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 23 * questions. 24 */ 25 26 package java.nio; 27 28 import java.util.Spliterator; 29 import jdk.internal.HotSpotIntrinsicCandidate; 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 * {@code 0} {@code <=} 100 * <i>mark</i> {@code <=} 101 * <i>position</i> {@code <=} 102 * <i>limit</i> {@code <=} 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 private int position = 0; 188 private int limit; 189 private int capacity; 190 191 // Used only by direct buffers 192 // NOTE: hoisted here for speed in JNI GetDirectBufferAddress 193 long address; 194 195 // Creates a new buffer with the given mark, position, limit, and capacity, 196 // after checking invariants. 197 // 198 Buffer(int mark, int pos, int lim, int cap) { // package-private 199 if (cap < 0) 200 throw createCapacityException(cap); 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 an {@code IllegalArgumentException} indicating that the source 214 * and target are the same {@code Buffer}. Intended for use in 215 * {@code put(src)} when the parameter is the {@code Buffer} on which the 216 * method is being invoked. 217 * 218 * @returns IllegalArgumentException 219 * With a message indicating equal source and target buffers 220 */ 221 static IllegalArgumentException createSameBufferException() { 222 return new IllegalArgumentException("The source buffer is this buffer"); 223 } 224 225 /** 226 * Verify that the capacity is nonnegative. 227 * 228 * @param capacity 229 * The new buffer's capacity, in $type$s 230 * 231 * @throws IllegalArgumentException 232 * If the {@code capacity} is a negative integer 233 */ 234 static IllegalArgumentException createCapacityException(int capacity) { 235 assert capacity < 0 : "capacity expected to be negative"; 236 return new IllegalArgumentException("capacity < 0: (" 237 + capacity + " < 0)"); 238 } 239 240 /** 241 * Returns this buffer's capacity. 242 * 243 * @return The capacity of this buffer 244 */ 245 public final int capacity() { 246 return capacity; 247 } 248 249 /** 250 * Returns this buffer's position. 251 * 252 * @return The position of this buffer 253 */ 254 public final int position() { 255 return position; 256 } 257 258 /** 259 * Sets this buffer's position. If the mark is defined and larger than the 260 * new position then it is discarded. 261 * 262 * @param newPosition 263 * The new position value; must be non-negative 264 * and no larger than the current limit 265 * 266 * @return This buffer 267 * 268 * @throws IllegalArgumentException 269 * If the preconditions on {@code newPosition} do not hold 270 */ 271 public Buffer position(int newPosition) { 272 if (newPosition > limit | newPosition < 0) 273 throw createPositionException(newPosition); 274 position = newPosition; 275 if (mark > position) mark = -1; 276 return this; 277 } 278 279 /** 280 * Verify that {@code 0 < newPosition <= limit} 281 * 282 * @param newPosition 283 * The new position value 284 * 285 * @throws IllegalArgumentException 286 * If the specified position is out of bounds. 287 */ 288 private IllegalArgumentException createPositionException(int newPosition) { 289 String msg = null; 290 291 if (newPosition > limit) { 292 msg = "newPosition > limit: (" + newPosition + " > " + limit + ")"; 293 } else { // assume negative 294 assert newPosition < 0 : "newPosition expected to be negative"; 295 msg = "newPosition < 0: (" + newPosition + " < 0)"; 296 } 297 298 return new IllegalArgumentException(msg); 299 } 300 301 /** 302 * Returns this buffer's limit. 303 * 304 * @return The limit of this buffer 305 */ 306 public final int limit() { 307 return limit; 308 } 309 310 /** 311 * Sets this buffer's limit. If the position is larger than the new limit 312 * then it is set to the new limit. If the mark is defined and larger than 313 * the new limit then it is discarded. 314 * 315 * @param newLimit 316 * The new limit value; must be non-negative 317 * and no larger than this buffer's capacity 318 * 319 * @return This buffer 320 * 321 * @throws IllegalArgumentException 322 * If the preconditions on {@code newLimit} do not hold 323 */ 324 public Buffer limit(int newLimit) { 325 if (newLimit > capacity | newLimit < 0) 326 throw createLimitException(newLimit); 327 limit = newLimit; 328 if (position > limit) position = limit; 329 if (mark > limit) mark = -1; 330 return this; 331 } 332 333 /** 334 * Verify that {@code 0 < newLimit <= capacity} 335 * 336 * @param newLimit 337 * The new limit value 338 * 339 * @throws IllegalArgumentException 340 * If the specified limit is out of bounds. 341 */ 342 private IllegalArgumentException createLimitException(int newLimit) { 343 String msg = null; 344 345 if (newLimit > capacity) { 346 msg = "newLimit > capacity: (" + newLimit + " > " + capacity + ")"; 347 } else { // assume negative 348 assert newLimit < 0 : "newLimit expected to be negative"; 349 msg = "newLimit < 0: (" + newLimit + " < 0)"; 350 } 351 352 return new IllegalArgumentException(msg); 353 } 354 355 /** 356 * Sets this buffer's mark at its position. 357 * 358 * @return This buffer 359 */ 360 public Buffer mark() { 361 mark = position; 362 return this; 363 } 364 365 /** 366 * Resets this buffer's position to the previously-marked position. 367 * 368 * <p> Invoking this method neither changes nor discards the mark's 369 * value. </p> 370 * 371 * @return This buffer 372 * 373 * @throws InvalidMarkException 374 * If the mark has not been set 375 */ 376 public Buffer reset() { 377 int m = mark; 378 if (m < 0) 379 throw new InvalidMarkException(); 380 position = m; 381 return this; 382 } 383 384 /** 385 * Clears this buffer. The position is set to zero, the limit is set to 386 * the capacity, and the mark is discarded. 387 * 388 * <p> Invoke this method before using a sequence of channel-read or 389 * <i>put</i> operations to fill this buffer. For example: 390 * 391 * <blockquote><pre> 392 * buf.clear(); // Prepare buffer for reading 393 * in.read(buf); // Read data</pre></blockquote> 394 * 395 * <p> This method does not actually erase the data in the buffer, but it 396 * is named as if it did because it will most often be used in situations 397 * in which that might as well be the case. </p> 398 * 399 * @return This buffer 400 */ 401 public Buffer clear() { 402 position = 0; 403 limit = capacity; 404 mark = -1; 405 return this; 406 } 407 408 /** 409 * Flips this buffer. The limit is set to the current position and then 410 * the position is set to zero. If the mark is defined then it is 411 * discarded. 412 * 413 * <p> After a sequence of channel-read or <i>put</i> operations, invoke 414 * this method to prepare for a sequence of channel-write or relative 415 * <i>get</i> operations. For example: 416 * 417 * <blockquote><pre> 418 * buf.put(magic); // Prepend header 419 * in.read(buf); // Read data into rest of buffer 420 * buf.flip(); // Flip buffer 421 * out.write(buf); // Write header + data to channel</pre></blockquote> 422 * 423 * <p> This method is often used in conjunction with the {@link 424 * java.nio.ByteBuffer#compact compact} method when transferring data from 425 * one place to another. </p> 426 * 427 * @return This buffer 428 */ 429 public Buffer flip() { 430 limit = position; 431 position = 0; 432 mark = -1; 433 return this; 434 } 435 436 /** 437 * Rewinds this buffer. The position is set to zero and the mark is 438 * discarded. 439 * 440 * <p> Invoke this method before a sequence of channel-write or <i>get</i> 441 * operations, assuming that the limit has already been set 442 * appropriately. For example: 443 * 444 * <blockquote><pre> 445 * out.write(buf); // Write remaining data 446 * buf.rewind(); // Rewind buffer 447 * buf.get(array); // Copy data into array</pre></blockquote> 448 * 449 * @return This buffer 450 */ 451 public Buffer rewind() { 452 position = 0; 453 mark = -1; 454 return this; 455 } 456 457 /** 458 * Returns the number of elements between the current position and the 459 * limit. 460 * 461 * @return The number of elements remaining in this buffer 462 */ 463 public final int remaining() { 464 return limit - position; 465 } 466 467 /** 468 * Tells whether there are any elements between the current position and 469 * the limit. 470 * 471 * @return {@code true} if, and only if, there is at least one element 472 * remaining in this buffer 473 */ 474 public final boolean hasRemaining() { 475 return position < limit; 476 } 477 478 /** 479 * Tells whether or not this buffer is read-only. 480 * 481 * @return {@code true} if, and only if, this buffer is read-only 482 */ 483 public abstract boolean isReadOnly(); 484 485 /** 486 * Tells whether or not this buffer is backed by an accessible 487 * array. 488 * 489 * <p> If this method returns {@code true} then the {@link #array() array} 490 * and {@link #arrayOffset() arrayOffset} methods may safely be invoked. 491 * </p> 492 * 493 * @return {@code true} if, and only if, this buffer 494 * is backed by an array and is not read-only 495 * 496 * @since 1.6 497 */ 498 public abstract boolean hasArray(); 499 500 /** 501 * Returns the array that backs this 502 * buffer <i>(optional operation)</i>. 503 * 504 * <p> This method is intended to allow array-backed buffers to be 505 * passed to native code more efficiently. Concrete subclasses 506 * provide more strongly-typed return values for this method. 507 * 508 * <p> Modifications to this buffer's content will cause the returned 509 * array's content to be modified, and vice versa. 510 * 511 * <p> Invoke the {@link #hasArray hasArray} method before invoking this 512 * method in order to ensure that this buffer has an accessible backing 513 * array. </p> 514 * 515 * @return The array that backs this buffer 516 * 517 * @throws ReadOnlyBufferException 518 * If this buffer is backed by an array but is read-only 519 * 520 * @throws UnsupportedOperationException 521 * If this buffer is not backed by an accessible array 522 * 523 * @since 1.6 524 */ 525 public abstract Object array(); 526 527 /** 528 * Returns the offset within this buffer's backing array of the first 529 * element of the buffer <i>(optional operation)</i>. 530 * 531 * <p> If this buffer is backed by an array then buffer position <i>p</i> 532 * corresponds to array index <i>p</i> + {@code arrayOffset()}. 533 * 534 * <p> Invoke the {@link #hasArray hasArray} method before invoking this 535 * method in order to ensure that this buffer has an accessible backing 536 * array. </p> 537 * 538 * @return The offset within this buffer's array 539 * of the first element of the buffer 540 * 541 * @throws ReadOnlyBufferException 542 * If this buffer is backed by an array but is read-only 543 * 544 * @throws UnsupportedOperationException 545 * If this buffer is not backed by an accessible array 546 * 547 * @since 1.6 548 */ 549 public abstract int arrayOffset(); 550 551 /** 552 * Tells whether or not this buffer is 553 * <a href="ByteBuffer.html#direct"><i>direct</i></a>. 554 * 555 * @return {@code true} if, and only if, this buffer is direct 556 * 557 * @since 1.6 558 */ 559 public abstract boolean isDirect(); 560 561 562 // -- Package-private methods for bounds checking, etc. -- 563 564 /** 565 * Checks the current position against the limit, throwing a {@link 566 * BufferUnderflowException} if it is not smaller than the limit, and then 567 * increments the position. 568 * 569 * @return The current position value, before it is incremented 570 */ 571 final int nextGetIndex() { // package-private 572 if (position >= limit) 573 throw new BufferUnderflowException(); 574 return position++; 575 } 576 577 final int nextGetIndex(int nb) { // package-private 578 if (limit - position < nb) 579 throw new BufferUnderflowException(); 580 int p = position; 581 position += nb; 582 return p; 583 } 584 585 /** 586 * Checks the current position against the limit, throwing a {@link 587 * BufferOverflowException} if it is not smaller than the limit, and then 588 * increments the position. 589 * 590 * @return The current position value, before it is incremented 591 */ 592 final int nextPutIndex() { // package-private 593 if (position >= limit) 594 throw new BufferOverflowException(); 595 return position++; 596 } 597 598 final int nextPutIndex(int nb) { // package-private 599 if (limit - position < nb) 600 throw new BufferOverflowException(); 601 int p = position; 602 position += nb; 603 return p; 604 } 605 606 /** 607 * Checks the given index against the limit, throwing an {@link 608 * IndexOutOfBoundsException} if it is not smaller than the limit 609 * or is smaller than zero. 610 */ 611 @HotSpotIntrinsicCandidate 612 final int checkIndex(int i) { // package-private 613 if ((i < 0) || (i >= limit)) 614 throw new IndexOutOfBoundsException(); 615 return i; 616 } 617 618 final int checkIndex(int i, int nb) { // package-private 619 if ((i < 0) || (nb > limit - i)) 620 throw new IndexOutOfBoundsException(); 621 return i; 622 } 623 624 final int markValue() { // package-private 625 return mark; 626 } 627 628 final void truncate() { // package-private 629 mark = -1; 630 position = 0; 631 limit = 0; 632 capacity = 0; 633 } 634 635 final void discardMark() { // package-private 636 mark = -1; 637 } 638 639 static void checkBounds(int off, int len, int size) { // package-private 640 if ((off | len | (off + len) | (size - (off + len))) < 0) 641 throw new IndexOutOfBoundsException(); 642 } 643 644 }