ShortBuffer.java revision ccbe3404e0691dab506d017550658e8e5974c83e
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 BufferFactory.newShortBuffer(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 = BufferFactory.newShortBuffer(array); 93 buf.position = start; 94 buf.limit = start + len; 95 96 return buf; 97 } 98 99 /** 100 * Constructs a {@code ShortBuffer} with given capacity. 101 * 102 * @param capacity 103 * The capacity of the buffer 104 */ 105 ShortBuffer(int capacity) { 106 super(capacity); 107 _elementSizeShift = 1; 108 } 109 110 public final short[] array() { 111 return protectedArray(); 112 } 113 114 public final int arrayOffset() { 115 return protectedArrayOffset(); 116 } 117 118 /** 119 * Returns a read-only buffer that shares its content with this buffer. 120 * <p> 121 * The returned buffer is guaranteed to be a new instance, even if this 122 * buffer is read-only itself. The new buffer's position, limit, capacity 123 * and mark are the same as this buffer's. 124 * <p> 125 * The new buffer shares its content with this buffer, which means this 126 * buffer's change of content will be visible to the new buffer. The two 127 * buffer's position, limit and mark are independent. 128 * 129 * @return a read-only version of this buffer. 130 */ 131 public abstract ShortBuffer asReadOnlyBuffer(); 132 133 /** 134 * Compacts this short buffer. 135 * <p> 136 * The remaining shorts will be moved to the head of the buffer, starting 137 * from position zero. Then the position is set to {@code remaining()}; the 138 * limit is set to capacity; the mark is cleared. 139 * 140 * @return this buffer. 141 * @exception ReadOnlyBufferException 142 * if no changes may be made to the contents of this buffer. 143 */ 144 public abstract ShortBuffer compact(); 145 146 /** 147 * Compare the remaining shorts of this buffer to another short buffer's 148 * remaining shorts. 149 * 150 * @param otherBuffer 151 * another short buffer. 152 * @return a negative value if this is less than {@code otherBuffer}; 0 if 153 * this equals to {@code otherBuffer}; a positive value if this is 154 * greater than {@code otherBuffer}. 155 * @exception ClassCastException 156 * if {@code otherBuffer} is not a short buffer. 157 */ 158 public int compareTo(ShortBuffer otherBuffer) { 159 int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining() 160 : otherBuffer.remaining(); 161 int thisPos = position; 162 int otherPos = otherBuffer.position; 163 short thisByte, otherByte; 164 while (compareRemaining > 0) { 165 thisByte = get(thisPos); 166 otherByte = otherBuffer.get(otherPos); 167 if (thisByte != otherByte) { 168 return thisByte < otherByte ? -1 : 1; 169 } 170 thisPos++; 171 otherPos++; 172 compareRemaining--; 173 } 174 return remaining() - otherBuffer.remaining(); 175 } 176 177 /** 178 * Returns a duplicated buffer that shares its content with this buffer. 179 * <p> 180 * The duplicated buffer's position, limit, capacity and mark are the same 181 * as this buffer. The duplicated buffer's read-only property and byte order 182 * are the same as this buffer's. 183 * <p> 184 * The new buffer shares its content with this buffer, which means either 185 * buffer's change of content will be visible to the other. The two buffer's 186 * position, limit and mark are independent. 187 * 188 * @return a duplicated buffer that shares its content with this buffer. 189 */ 190 public abstract ShortBuffer duplicate(); 191 192 /** 193 * Checks whether this short buffer is equal to another object. 194 * <p> 195 * If {@code other} is not a short buffer then {@code false} is returned. 196 * Two short buffers are equal if and only if their remaining shorts are 197 * exactly the same. Position, limit, capacity and mark are not considered. 198 * 199 * @param other 200 * the object to compare with this short buffer. 201 * @return {@code true} if this short buffer is equal to {@code other}, 202 * {@code false} otherwise. 203 */ 204 @Override 205 public boolean equals(Object other) { 206 if (!(other instanceof ShortBuffer)) { 207 return false; 208 } 209 ShortBuffer otherBuffer = (ShortBuffer) other; 210 211 if (remaining() != otherBuffer.remaining()) { 212 return false; 213 } 214 215 int myPosition = position; 216 int otherPosition = otherBuffer.position; 217 boolean equalSoFar = true; 218 while (equalSoFar && (myPosition < limit)) { 219 equalSoFar = get(myPosition++) == otherBuffer.get(otherPosition++); 220 } 221 222 return equalSoFar; 223 } 224 225 /** 226 * Returns the short at the current position and increases the position by 227 * 1. 228 * 229 * @return the short at the current position. 230 * @exception BufferUnderflowException 231 * if the position is equal or greater than limit. 232 */ 233 public abstract short get(); 234 235 /** 236 * Reads shorts from the current position into the specified short array and 237 * increases the position by the number of shorts read. 238 * <p> 239 * Calling this method has the same effect as 240 * {@code get(dst, 0, dst.length)}. 241 * 242 * @param dst 243 * the destination short array. 244 * @return this buffer. 245 * @exception BufferUnderflowException 246 * if {@code dst.length} is greater than {@code remaining()}. 247 */ 248 public ShortBuffer get(short[] dst) { 249 return get(dst, 0, dst.length); 250 } 251 252 /** 253 * Reads shorts from the current position into the specified short array, 254 * starting from the specified offset, and increases the position by the 255 * number of shorts read. 256 * 257 * @param dst 258 * the target short array. 259 * @param off 260 * the offset of the short array, must not be negative and not 261 * greater than {@code dst.length}. 262 * @param len 263 * the number of shorts to read, must be no less than zero and 264 * not greater than {@code dst.length - off}. 265 * @return this buffer. 266 * @exception IndexOutOfBoundsException 267 * if either {@code off} or {@code len} is invalid. 268 * @exception BufferUnderflowException 269 * if {@code len} is greater than {@code remaining()}. 270 */ 271 public ShortBuffer get(short[] dst, int off, int len) { 272 int length = dst.length; 273 if (off < 0 || len < 0 || (long) off + (long) len > length) { 274 throw new IndexOutOfBoundsException(); 275 } 276 if (len > remaining()) { 277 throw new BufferUnderflowException(); 278 } 279 for (int i = off; i < off + len; i++) { 280 dst[i] = get(); 281 } 282 return this; 283 } 284 285 /** 286 * Returns the short at the specified index; the position is not changed. 287 * 288 * @param index 289 * the index, must not be negative and less than limit. 290 * @return a short at the specified index. 291 * @exception IndexOutOfBoundsException 292 * if index is invalid. 293 */ 294 public abstract short get(int index); 295 296 public final boolean hasArray() { 297 return protectedHasArray(); 298 } 299 300 /** 301 * Calculates this buffer's hash code from the remaining chars. The 302 * position, limit, capacity and mark don't affect the hash code. 303 * 304 * @return the hash code calculated from the remaining shorts. 305 */ 306 @Override 307 public int hashCode() { 308 int myPosition = position; 309 int hash = 0; 310 while (myPosition < limit) { 311 hash = hash + get(myPosition++); 312 } 313 return hash; 314 } 315 316 /** 317 * Indicates whether this buffer is direct. A direct buffer will try its 318 * best to take advantage of native memory APIs and it may not stay in the 319 * Java heap, so it is not affected by garbage collection. 320 * <p> 321 * A short buffer is direct if it is based on a byte buffer and the byte 322 * buffer is direct. 323 * 324 * @return {@code true} if this buffer is direct, {@code false} otherwise. 325 */ 326 public abstract boolean isDirect(); 327 328 /** 329 * Returns the byte order used by this buffer when converting shorts from/to 330 * bytes. 331 * <p> 332 * If this buffer is not based on a byte buffer, then always return the 333 * platform's native byte order. 334 * 335 * @return the byte order used by this buffer when converting shorts from/to 336 * bytes. 337 */ 338 public abstract ByteOrder order(); 339 340 /** 341 * Child class implements this method to realize {@code array()}. 342 * 343 * @return see {@code array()} 344 */ 345 abstract short[] protectedArray(); 346 347 /** 348 * Child class implements this method to realize {@code arrayOffset()}. 349 * 350 * @return see {@code arrayOffset()} 351 */ 352 abstract int protectedArrayOffset(); 353 354 /** 355 * Child class implements this method to realize {@code hasArray()}. 356 * 357 * @return see {@code hasArray()} 358 */ 359 abstract boolean protectedHasArray(); 360 361 /** 362 * Writes the given short to the current position and increases the position 363 * by 1. 364 * 365 * @param s 366 * the short to write. 367 * @return this buffer. 368 * @exception BufferOverflowException 369 * if position is equal or greater than limit. 370 * @exception ReadOnlyBufferException 371 * if no changes may be made to the contents of this buffer. 372 */ 373 public abstract ShortBuffer put(short s); 374 375 /** 376 * Writes shorts from the given short array to the current position and 377 * increases the position by the number of shorts written. 378 * <p> 379 * Calling this method has the same effect as 380 * {@code put(src, 0, src.length)}. 381 * 382 * @param src 383 * the source short array. 384 * @return this buffer. 385 * @exception BufferOverflowException 386 * if {@code remaining()} is less than {@code src.length}. 387 * @exception ReadOnlyBufferException 388 * if no changes may be made to the contents of this buffer. 389 */ 390 public final ShortBuffer put(short[] src) { 391 return put(src, 0, src.length); 392 } 393 394 /** 395 * Writes shorts from the given short array, starting from the specified 396 * offset, to the current position and increases the position by the number 397 * of shorts written. 398 * 399 * @param src 400 * the source short array. 401 * @param off 402 * the offset of short array, must not be negative and not 403 * greater than {@code src.length}. 404 * @param len 405 * the number of shorts to write, must be no less than zero and 406 * not greater than {@code src.length - off}. 407 * @return this buffer. 408 * @exception BufferOverflowException 409 * if {@code remaining()} is less than {@code len}. 410 * @exception IndexOutOfBoundsException 411 * if either {@code off} or {@code len} is invalid. 412 * @exception ReadOnlyBufferException 413 * if no changes may be made to the contents of this buffer. 414 */ 415 public ShortBuffer put(short[] src, int off, int len) { 416 int length = src.length; 417 if (off < 0 || len < 0 || (long) off + (long) len > length) { 418 throw new IndexOutOfBoundsException(); 419 } 420 421 if (len > remaining()) { 422 throw new BufferOverflowException(); 423 } 424 for (int i = off; i < off + len; i++) { 425 put(src[i]); 426 } 427 return this; 428 } 429 430 /** 431 * Writes all the remaining shorts of the {@code src} short buffer to this 432 * buffer's current position, and increases both buffers' position by the 433 * number of shorts copied. 434 * 435 * @param src 436 * the source short buffer. 437 * @return this buffer. 438 * @exception BufferOverflowException 439 * if {@code src.remaining()} is greater than this buffer's 440 * {@code remaining()}. 441 * @exception IllegalArgumentException 442 * if {@code src} is this buffer. 443 * @exception ReadOnlyBufferException 444 * if no changes may be made to the contents of this buffer. 445 */ 446 public ShortBuffer put(ShortBuffer src) { 447 if (src == this) { 448 throw new IllegalArgumentException(); 449 } 450 if (src.remaining() > remaining()) { 451 throw new BufferOverflowException(); 452 } 453 short[] contents = new short[src.remaining()]; 454 src.get(contents); 455 put(contents); 456 return this; 457 } 458 459 /** 460 * Writes a short to the specified index of this buffer; the position is not 461 * changed. 462 * 463 * @param index 464 * the index, must not be negative and less than the limit. 465 * @param s 466 * the short to write. 467 * @return this buffer. 468 * @exception IndexOutOfBoundsException 469 * if index is invalid. 470 * @exception ReadOnlyBufferException 471 * if no changes may be made to the contents of this buffer. 472 */ 473 public abstract ShortBuffer put(int index, short s); 474 475 /** 476 * Returns a sliced buffer that shares its content with this buffer. 477 * <p> 478 * The sliced buffer's capacity will be this buffer's {@code remaining()}, 479 * and its zero position will correspond to this buffer's current position. 480 * The new buffer's position will be 0, limit will be its capacity, and its 481 * mark is cleared. The new buffer's read-only property and byte order are 482 * same as this buffer's. 483 * <p> 484 * The new buffer shares its content with this buffer, which means either 485 * buffer's change of content will be visible to the other. The two buffer's 486 * position, limit and mark are independent. 487 * 488 * @return a sliced buffer that shares its content with this buffer. 489 */ 490 public abstract ShortBuffer slice(); 491 492 /** 493 * Returns a string representing the state of this short buffer. 494 * 495 * @return a string representing the state of this short buffer. 496 */ 497 @Override 498 public String toString() { 499 StringBuilder buf = new StringBuilder(); 500 buf.append(getClass().getName()); 501 buf.append(", status: capacity="); 502 buf.append(capacity()); 503 buf.append(" position="); 504 buf.append(position()); 505 buf.append(" limit="); 506 buf.append(limit()); 507 return buf.toString(); 508 } 509} 510