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