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