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