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