IntBuffer.java revision 0e1b748ecabf720065a632f28330f5d4d037d5ae
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.nio; 19 20/** 21 * A buffer of ints. 22 * <p> 23 * A int buffer can be created in either of the following ways: 24 * <ul> 25 * <li>{@link #allocate(int) Allocate} a new int array and create a buffer 26 * based on it;</li> 27 * <li>{@link #wrap(int[]) Wrap} an existing int array to create a new buffer;</li> 28 * <li>Use {@link java.nio.ByteBuffer#asIntBuffer() ByteBuffer.asIntBuffer} to 29 * create a int buffer based on a byte buffer.</li> 30 * </ul> 31 */ 32public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer> { 33 34 /** 35 * Creates an int buffer based on a newly allocated int array. 36 * 37 * @param capacity 38 * the capacity of the new buffer. 39 * @return the created int buffer. 40 * @throws IllegalArgumentException 41 * if {@code capacity} is less than zero. 42 */ 43 public static IntBuffer allocate(int capacity) { 44 if (capacity < 0) { 45 throw new IllegalArgumentException(); 46 } 47 return new ReadWriteIntArrayBuffer(capacity); 48 } 49 50 /** 51 * Creates a new int buffer by wrapping the given int array. 52 * <p> 53 * Calling this method has the same effect as 54 * {@code wrap(array, 0, array.length)}. 55 * 56 * @param array 57 * the int array which the new buffer will be based on. 58 * @return the created int buffer. 59 */ 60 public static IntBuffer wrap(int[] array) { 61 return wrap(array, 0, array.length); 62 } 63 64 /** 65 * Creates a new int buffer by wrapping the given int array. 66 * <p> 67 * The new buffer's position will be {@code start}, limit will be 68 * {@code start + intCount}, capacity will be the length of the array. 69 * 70 * @param array 71 * the int array which the new buffer will be based on. 72 * @param start 73 * the start index, must not be negative and not greater than 74 * {@code array.length} 75 * @param intCount 76 * the length, must not be negative and not greater than 77 * {@code array.length - start}. 78 * @return the created int buffer. 79 * @exception IndexOutOfBoundsException 80 * if either {@code start} or {@code intCount} is invalid. 81 */ 82 public static IntBuffer wrap(int[] array, int start, int intCount) { 83 if (array == null) { 84 throw new NullPointerException(); 85 } 86 if (start < 0 || intCount < 0 || (long) intCount + (long) start > array.length) { 87 throw new IndexOutOfBoundsException(); 88 } 89 90 IntBuffer buf = new ReadWriteIntArrayBuffer(array); 91 buf.position = start; 92 buf.limit = start + intCount; 93 94 return buf; 95 } 96 97 IntBuffer(int capacity) { 98 super(2, capacity, null); 99 } 100 101 public final int[] array() { 102 return protectedArray(); 103 } 104 105 public final int arrayOffset() { 106 return protectedArrayOffset(); 107 } 108 109 /** 110 * Returns a read-only buffer that shares its content with this buffer. 111 * <p> 112 * The returned buffer is guaranteed to be a new instance, even this buffer 113 * is read-only itself. The new buffer's position, limit, capacity and mark 114 * are the same as this buffer's. 115 * <p> 116 * The new buffer shares its content with this buffer, which means this 117 * buffer's change of content will be visible to the new buffer. The two 118 * buffer's position, limit and mark are independent. 119 * 120 * @return a read-only version of this buffer. 121 */ 122 public abstract IntBuffer asReadOnlyBuffer(); 123 124 /** 125 * Compacts this int buffer. 126 * <p> 127 * The remaining ints will be moved to the head of the buffer, starting from 128 * position zero. Then the position is set to {@code remaining()}; the 129 * limit is set to capacity; the mark is cleared. 130 * 131 * @return this buffer. 132 * @exception ReadOnlyBufferException 133 * if no changes may be made to the contents of this buffer. 134 */ 135 public abstract IntBuffer compact(); 136 137 /** 138 * Compares the remaining ints of this buffer to another int buffer's 139 * remaining ints. 140 * 141 * @param otherBuffer 142 * another int buffer. 143 * @return a negative value if this is less than {@code other}; 0 if this 144 * equals to {@code other}; a positive value if this is greater 145 * than {@code other}. 146 * @exception ClassCastException 147 * if {@code other} is not an int buffer. 148 */ 149 public int compareTo(IntBuffer otherBuffer) { 150 int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining() 151 : otherBuffer.remaining(); 152 int thisPos = position; 153 int otherPos = otherBuffer.position; 154 // BEGIN android-changed 155 int thisInt, otherInt; 156 while (compareRemaining > 0) { 157 thisInt = get(thisPos); 158 otherInt = otherBuffer.get(otherPos); 159 if (thisInt != otherInt) { 160 return thisInt < otherInt ? -1 : 1; 161 } 162 thisPos++; 163 otherPos++; 164 compareRemaining--; 165 } 166 // END android-changed 167 return remaining() - otherBuffer.remaining(); 168 } 169 170 /** 171 * Returns a duplicated buffer that shares its content with this buffer. 172 * <p> 173 * The duplicated buffer's position, limit, capacity and mark are the same 174 * as this buffer. The duplicated buffer's read-only property and byte order 175 * are the same as this buffer's. 176 * <p> 177 * The new buffer shares its content with this buffer, which means either 178 * buffer's change of content will be visible to the other. The two buffer's 179 * position, limit and mark are independent. 180 * 181 * @return a duplicated buffer that shares its content with this buffer. 182 */ 183 public abstract IntBuffer duplicate(); 184 185 /** 186 * Checks whether this int buffer is equal to another object. 187 * <p> 188 * If {@code other} is not a int buffer then {@code false} is returned. Two 189 * int buffers are equal if and only if their remaining ints are exactly the 190 * same. Position, limit, capacity and mark are not considered. 191 * 192 * @param other 193 * the object to compare with this int buffer. 194 * @return {@code true} if this int buffer is equal to {@code other}, 195 * {@code false} otherwise. 196 */ 197 @Override 198 public boolean equals(Object other) { 199 if (!(other instanceof IntBuffer)) { 200 return false; 201 } 202 IntBuffer otherBuffer = (IntBuffer) other; 203 204 if (remaining() != otherBuffer.remaining()) { 205 return false; 206 } 207 208 int myPosition = position; 209 int otherPosition = otherBuffer.position; 210 boolean equalSoFar = true; 211 while (equalSoFar && (myPosition < limit)) { 212 equalSoFar = get(myPosition++) == otherBuffer.get(otherPosition++); 213 } 214 215 return equalSoFar; 216 } 217 218 /** 219 * Returns the int at the current position and increases the position by 1. 220 * 221 * @return the int at the current position. 222 * @exception BufferUnderflowException 223 * if the position is equal or greater than limit. 224 */ 225 public abstract int get(); 226 227 /** 228 * Reads ints from the current position into the specified int array and 229 * increases the position by the number of ints read. 230 * <p> 231 * Calling this method has the same effect as 232 * {@code get(dst, 0, dst.length)}. 233 * 234 * @param dst 235 * the destination int array. 236 * @return this buffer. 237 * @exception BufferUnderflowException 238 * if {@code dst.length} is greater than {@code remaining()}. 239 */ 240 public IntBuffer get(int[] dst) { 241 return get(dst, 0, dst.length); 242 } 243 244 /** 245 * Reads ints from the current position into the specified int array, 246 * starting from the specified offset, and increases the position by the 247 * number of ints read. 248 * 249 * @param dst 250 * the target int array. 251 * @param dstOffset 252 * the offset of the int array, must not be negative and not 253 * greater than {@code dst.length}. 254 * @param intCount 255 * the number of ints to read, must be no less than zero and not 256 * greater than {@code dst.length - dstOffset}. 257 * @return this buffer. 258 * @exception IndexOutOfBoundsException 259 * if either {@code dstOffset} or {@code intCount} is invalid. 260 * @exception BufferUnderflowException 261 * if {@code intCount} is greater than {@code remaining()}. 262 */ 263 public IntBuffer get(int[] dst, int dstOffset, int intCount) { 264 int length = dst.length; 265 if (dstOffset < 0 || intCount < 0 || (long) intCount + (long) dstOffset > length) { 266 throw new IndexOutOfBoundsException(); 267 } 268 if (intCount > remaining()) { 269 throw new BufferUnderflowException(); 270 } 271 for (int i = dstOffset; i < dstOffset + intCount; ++i) { 272 dst[i] = get(); 273 } 274 return this; 275 } 276 277 /** 278 * Returns an int at the specified index; the position is not changed. 279 * 280 * @param index 281 * the index, must not be negative and less than limit. 282 * @return an int at the specified index. 283 * @exception IndexOutOfBoundsException 284 * if index is invalid. 285 */ 286 public abstract int get(int index); 287 288 public final boolean hasArray() { 289 return protectedHasArray(); 290 } 291 292 /** 293 * Calculates this buffer's hash code from the remaining chars. The 294 * position, limit, capacity and mark don't affect the hash code. 295 * 296 * @return the hash code calculated from the remaining ints. 297 */ 298 @Override 299 public int hashCode() { 300 int myPosition = position; 301 int hash = 0; 302 while (myPosition < limit) { 303 hash = hash + get(myPosition++); 304 } 305 return hash; 306 } 307 308 /** 309 * Indicates whether this buffer is direct. A direct buffer will try its 310 * best to take advantage of native memory APIs and it may not stay in the 311 * Java heap, so it is not affected by garbage collection. 312 * <p> 313 * An int buffer is direct if it is based on a byte buffer and the byte 314 * buffer is direct. 315 * 316 * @return {@code true} if this buffer is direct, {@code false} otherwise. 317 */ 318 public abstract boolean isDirect(); 319 320 /** 321 * Returns the byte order used by this buffer when converting ints from/to 322 * bytes. 323 * <p> 324 * If this buffer is not based on a byte buffer, then always return the 325 * platform's native byte order. 326 * 327 * @return the byte order used by this buffer when converting ints from/to 328 * bytes. 329 */ 330 public abstract ByteOrder order(); 331 332 /** 333 * Child class implements this method to realize {@code array()}. 334 * 335 * @return see {@code array()} 336 */ 337 abstract int[] protectedArray(); 338 339 /** 340 * Child class implements this method to realize {@code arrayOffset()}. 341 * 342 * @return see {@code arrayOffset()} 343 */ 344 abstract int protectedArrayOffset(); 345 346 /** 347 * Child class implements this method to realize {@code hasArray()}. 348 * 349 * @return see {@code hasArray()} 350 */ 351 abstract boolean protectedHasArray(); 352 353 /** 354 * Writes the given int to the current position and increases the position 355 * by 1. 356 * 357 * @param i 358 * the int to write. 359 * @return this buffer. 360 * @exception BufferOverflowException 361 * if position is equal or greater than limit. 362 * @exception ReadOnlyBufferException 363 * if no changes may be made to the contents of this buffer. 364 */ 365 public abstract IntBuffer put(int i); 366 367 /** 368 * Writes ints from the given int array to the current position and 369 * increases the position by the number of ints written. 370 * <p> 371 * Calling this method has the same effect as 372 * {@code put(src, 0, src.length)}. 373 * 374 * @param src 375 * the source int array. 376 * @return this buffer. 377 * @exception BufferOverflowException 378 * if {@code remaining()} is less than {@code src.length}. 379 * @exception ReadOnlyBufferException 380 * if no changes may be made to the contents of this buffer. 381 */ 382 public final IntBuffer put(int[] src) { 383 return put(src, 0, src.length); 384 } 385 386 /** 387 * Writes ints from the given int array, starting from the specified offset, 388 * to the current position and increases the position by the number of ints 389 * written. 390 * 391 * @param src 392 * the source int array. 393 * @param srcOffset 394 * the offset of int array, must not be negative and not greater 395 * than {@code src.length}. 396 * @param intCount 397 * the number of ints to write, must be no less than zero and not 398 * greater than {@code src.length - srcOffset}. 399 * @return this buffer. 400 * @exception BufferOverflowException 401 * if {@code remaining()} is less than {@code intCount}. 402 * @exception IndexOutOfBoundsException 403 * if either {@code srcOffset} or {@code intCount} is invalid. 404 * @exception ReadOnlyBufferException 405 * if no changes may be made to the contents of this buffer. 406 */ 407 public IntBuffer put(int[] src, int srcOffset, int intCount) { 408 int length = src.length; 409 if (srcOffset < 0 || intCount < 0 || (long) intCount + (long) srcOffset > length) { 410 throw new IndexOutOfBoundsException(); 411 } 412 if (intCount > remaining()) { 413 throw new BufferOverflowException(); 414 } 415 for (int i = srcOffset; i < srcOffset + intCount; ++i) { 416 put(src[i]); 417 } 418 return this; 419 } 420 421 /** 422 * Writes all the remaining ints of the {@code src} int buffer to this 423 * buffer's current position, and increases both buffers' position by the 424 * number of ints copied. 425 * 426 * @param src 427 * the source int buffer. 428 * @return this buffer. 429 * @exception BufferOverflowException 430 * if {@code src.remaining()} is greater than this buffer's 431 * {@code remaining()}. 432 * @exception IllegalArgumentException 433 * if {@code src} is this buffer. 434 * @exception ReadOnlyBufferException 435 * if no changes may be made to the contents of this buffer. 436 */ 437 public IntBuffer put(IntBuffer src) { 438 if (src == this) { 439 throw new IllegalArgumentException(); 440 } 441 if (src.remaining() > remaining()) { 442 throw new BufferOverflowException(); 443 } 444 int[] contents = new int[src.remaining()]; 445 src.get(contents); 446 put(contents); 447 return this; 448 } 449 450 /** 451 * Write a int to the specified index of this buffer; the position is not 452 * changed. 453 * 454 * @param index 455 * the index, must not be negative and less than the limit. 456 * @param i 457 * the int to write. 458 * @return this buffer. 459 * @exception IndexOutOfBoundsException 460 * if index is invalid. 461 * @exception ReadOnlyBufferException 462 * if no changes may be made to the contents of this buffer. 463 */ 464 public abstract IntBuffer put(int index, int i); 465 466 /** 467 * Returns a sliced buffer that shares its content with this buffer. 468 * <p> 469 * The sliced buffer's capacity will be this buffer's {@code remaining()}, 470 * and its zero position will correspond to this buffer's current position. 471 * The new buffer's position will be 0, limit will be its capacity, and its 472 * mark is cleared. The new buffer's read-only property and byte order are 473 * same as this buffer's. 474 * <p> 475 * The new buffer shares its content with this buffer, which means either 476 * buffer's change of content will be visible to the other. The two buffer's 477 * position, limit and mark are independent. 478 * 479 * @return a sliced buffer that shares its content with this buffer. 480 */ 481 public abstract IntBuffer slice(); 482} 483