• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import 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  */
35 public 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      */
allocate(int capacity)47     public static LongBuffer allocate(int capacity) {
48         if (capacity < 0) {
49             throw new IllegalArgumentException("capacity < 0: " + capacity);
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      */
wrap(long[] array)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      */
wrap(long[] array, int start, int longCount)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 
LongBuffer(int capacity)94     LongBuffer(int capacity) {
95         super(3, capacity, null);
96     }
97 
array()98     public final long[] array() {
99         return protectedArray();
100     }
101 
arrayOffset()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      */
asReadOnlyBuffer()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      */
compact()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      */
compareTo(LongBuffer otherBuffer)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         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         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 same as this buffer's, too.
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      */
duplicate()178     public abstract LongBuffer duplicate();
179 
180     /**
181      * Checks whether this long buffer is equal to another object.
182      * <p>
183      * If {@code other} is not a long buffer then {@code false} is returned. Two
184      * long buffers are equal if and only if their remaining longs are exactly
185      * the same. Position, limit, capacity and mark are not considered.
186      *
187      * @param other
188      *            the object to compare with this long buffer.
189      * @return {@code true} if this long buffer is equal to {@code other},
190      *         {@code false} otherwise.
191      */
192     @Override
equals(Object other)193     public boolean equals(Object other) {
194         if (!(other instanceof LongBuffer)) {
195             return false;
196         }
197         LongBuffer otherBuffer = (LongBuffer) 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 long at the current position and increase the position by 1.
215      *
216      * @return the long at the current position.
217      * @exception BufferUnderflowException
218      *                if the position is equal or greater than limit.
219      */
get()220     public abstract long get();
221 
222     /**
223      * Reads longs from the current position into the specified long array and
224      * increases the position by the number of longs read.
225      * <p>
226      * Calling this method has the same effect as
227      * {@code get(dst, 0, dst.length)}.
228      *
229      * @param dst
230      *            the destination long array.
231      * @return this buffer.
232      * @exception BufferUnderflowException
233      *                if {@code dst.length} is greater than {@code remaining()}.
234      */
get(long[] dst)235     public LongBuffer get(long[] dst) {
236         return get(dst, 0, dst.length);
237     }
238 
239     /**
240      * Reads longs from the current position into the specified long array,
241      * starting from the specified offset, and increase the position by the
242      * number of longs read.
243      *
244      * @param dst
245      *            the target long array.
246      * @param dstOffset
247      *            the offset of the long array, must not be negative and not
248      *            greater than {@code dst.length}.
249      * @param longCount
250      *            the number of longs to read, must be no less than zero and not
251      *            greater than {@code dst.length - dstOffset}.
252      * @return this buffer.
253      * @exception IndexOutOfBoundsException
254      *                if either {@code dstOffset} or {@code longCount} is invalid.
255      * @exception BufferUnderflowException
256      *                if {@code longCount} is greater than {@code remaining()}.
257      */
get(long[] dst, int dstOffset, int longCount)258     public LongBuffer get(long[] dst, int dstOffset, int longCount) {
259         Arrays.checkOffsetAndCount(dst.length, dstOffset, longCount);
260         if (longCount > remaining()) {
261             throw new BufferUnderflowException();
262         }
263         for (int i = dstOffset; i < dstOffset + longCount; ++i) {
264             dst[i] = get();
265         }
266         return this;
267     }
268 
269     /**
270      * Returns the long at the specified index; the position is not changed.
271      *
272      * @param index
273      *            the index, must not be negative and less than limit.
274      * @return the long at the specified index.
275      * @exception IndexOutOfBoundsException
276      *                if index is invalid.
277      */
get(int index)278     public abstract long get(int index);
279 
hasArray()280     public final boolean hasArray() {
281         return protectedHasArray();
282     }
283 
284     /**
285      * Calculates this buffer's hash code from the remaining chars. The
286      * position, limit, capacity and mark don't affect the hash code.
287      *
288      * @return the hash code calculated from the remaining longs.
289      */
290     @Override
hashCode()291     public int hashCode() {
292         int myPosition = position;
293         int hash = 0;
294         long l;
295         while (myPosition < limit) {
296             l = get(myPosition++);
297             hash = hash + ((int) l) ^ ((int) (l >> 32));
298         }
299         return hash;
300     }
301 
302     /**
303      * Indicates whether this buffer is direct. A direct buffer will try its
304      * best to take advantage of native memory APIs and it may not stay in the
305      * Java heap, so it is not affected by garbage collection.
306      * <p>
307      * A long buffer is direct if it is based on a byte buffer and the byte
308      * buffer is direct.
309      *
310      * @return {@code true} if this buffer is direct, {@code false} otherwise.
311      */
isDirect()312     public abstract boolean isDirect();
313 
314     /**
315      * Returns the byte order used by this buffer when converting longs from/to
316      * bytes.
317      * <p>
318      * If this buffer is not based on a byte buffer, then always return the
319      * platform's native byte order.
320      *
321      * @return the byte order used by this buffer when converting longs from/to
322      *         bytes.
323      */
order()324     public abstract ByteOrder order();
325 
326     /**
327      * Child class implements this method to realize {@code array()}.
328      *
329      * @return see {@code array()}
330      */
protectedArray()331     abstract long[] protectedArray();
332 
333     /**
334      * Child class implements this method to realize {@code arrayOffset()}.
335      *
336      * @return see {@code arrayOffset()}
337      */
protectedArrayOffset()338     abstract int protectedArrayOffset();
339 
340     /**
341      * Child class implements this method to realize {@code hasArray()}.
342      *
343      * @return see {@code hasArray()}
344      */
protectedHasArray()345     abstract boolean protectedHasArray();
346 
347     /**
348      * Writes the given long to the current position and increases the position
349      * by 1.
350      *
351      * @param l
352      *            the long to write.
353      * @return this buffer.
354      * @exception BufferOverflowException
355      *                if position is equal or greater than limit.
356      * @exception ReadOnlyBufferException
357      *                if no changes may be made to the contents of this buffer.
358      */
put(long l)359     public abstract LongBuffer put(long l);
360 
361     /**
362      * Writes longs from the given long array to the current position and
363      * increases the position by the number of longs written.
364      * <p>
365      * Calling this method has the same effect as
366      * {@code put(src, 0, src.length)}.
367      *
368      * @param src
369      *            the source long array.
370      * @return this buffer.
371      * @exception BufferOverflowException
372      *                if {@code remaining()} is less than {@code src.length}.
373      * @exception ReadOnlyBufferException
374      *                if no changes may be made to the contents of this buffer.
375      */
put(long[] src)376     public final LongBuffer put(long[] src) {
377         return put(src, 0, src.length);
378     }
379 
380     /**
381      * Writes longs from the given long array, starting from the specified
382      * offset, to the current position and increases the position by the number
383      * of longs written.
384      *
385      * @param src
386      *            the source long array.
387      * @param srcOffset
388      *            the offset of long array, must not be negative and not greater
389      *            than {@code src.length}.
390      * @param longCount
391      *            the number of longs to write, must be no less than zero and
392      *            not greater than {@code src.length - srcOffset}.
393      * @return this buffer.
394      * @exception BufferOverflowException
395      *                if {@code remaining()} is less than {@code longCount}.
396      * @exception IndexOutOfBoundsException
397      *                if either {@code srcOffset} or {@code longCount} is invalid.
398      * @exception ReadOnlyBufferException
399      *                if no changes may be made to the contents of this buffer.
400      */
put(long[] src, int srcOffset, int longCount)401     public LongBuffer put(long[] src, int srcOffset, int longCount) {
402         Arrays.checkOffsetAndCount(src.length, srcOffset, longCount);
403         if (longCount > remaining()) {
404             throw new BufferOverflowException();
405         }
406         for (int i = srcOffset; i < srcOffset + longCount; ++i) {
407             put(src[i]);
408         }
409         return this;
410     }
411 
412     /**
413      * Writes all the remaining longs of the {@code src} long buffer to this
414      * buffer's current position, and increases both buffers' position by the
415      * number of longs copied.
416      *
417      * @param src
418      *            the source long buffer.
419      * @return this buffer.
420      * @exception BufferOverflowException
421      *                if {@code src.remaining()} is greater than this buffer's
422      *                {@code remaining()}.
423      * @exception IllegalArgumentException
424      *                if {@code src} is this buffer.
425      * @exception ReadOnlyBufferException
426      *                if no changes may be made to the contents of this buffer.
427      */
put(LongBuffer src)428     public LongBuffer put(LongBuffer src) {
429         if (src == this) {
430             throw new IllegalArgumentException("src == this");
431         }
432         if (src.remaining() > remaining()) {
433             throw new BufferOverflowException();
434         }
435         long[] contents = new long[src.remaining()];
436         src.get(contents);
437         put(contents);
438         return this;
439     }
440 
441     /**
442      * Writes a long to the specified index of this buffer; the position is not
443      * changed.
444      *
445      * @param index
446      *            the index, must not be negative and less than the limit.
447      * @param l
448      *            the long to write.
449      * @return this buffer.
450      * @exception IndexOutOfBoundsException
451      *                if index is invalid.
452      * @exception ReadOnlyBufferException
453      *                if no changes may be made to the contents of this buffer.
454      */
put(int index, long l)455     public abstract LongBuffer put(int index, long l);
456 
457     /**
458      * Returns a sliced buffer that shares its content with this buffer.
459      * <p>
460      * The sliced buffer's capacity will be this buffer's {@code remaining()},
461      * and its zero position will correspond to this buffer's current position.
462      * The new buffer's position will be 0, limit will be its capacity, and its
463      * mark is cleared. The new buffer's read-only property and byte order are
464      * same as this buffer's.
465      * <p>
466      * The new buffer shares its content with this buffer, which means either
467      * buffer's change of content will be visible to the other. The two buffer's
468      * position, limit and mark are independent.
469      *
470      * @return a sliced buffer that shares its content with this buffer.
471      */
slice()472     public abstract LongBuffer slice();
473 }
474