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