author | psandoz |
Thu, 24 Mar 2016 11:21:18 +0100 | |
changeset 36933 | 3e6453e2d833 |
parent 32227 | 34721a47bc92 |
child 38321 | ff5b89346438 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
36933
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
2 |
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package java.nio; |
|
27 |
||
36933
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
28 |
import jdk.internal.HotSpotIntrinsicCandidate; |
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
29 |
|
17922
d56eec572de5
8014854: (bf) CharBuffer.chars too slow with default implementation
alanb
parents:
10325
diff
changeset
|
30 |
import java.util.Spliterator; |
2 | 31 |
|
32 |
/** |
|
33 |
* A container for data of a specific primitive type. |
|
34 |
* |
|
35 |
* <p> A buffer is a linear, finite sequence of elements of a specific |
|
36 |
* primitive type. Aside from its content, the essential properties of a |
|
37 |
* buffer are its capacity, limit, and position: </p> |
|
38 |
* |
|
39 |
* <blockquote> |
|
40 |
* |
|
41 |
* <p> A buffer's <i>capacity</i> is the number of elements it contains. The |
|
42 |
* capacity of a buffer is never negative and never changes. </p> |
|
43 |
* |
|
44 |
* <p> A buffer's <i>limit</i> is the index of the first element that should |
|
45 |
* not be read or written. A buffer's limit is never negative and is never |
|
46 |
* greater than its capacity. </p> |
|
47 |
* |
|
48 |
* <p> A buffer's <i>position</i> is the index of the next element to be |
|
49 |
* read or written. A buffer's position is never negative and is never |
|
50 |
* greater than its limit. </p> |
|
51 |
* |
|
52 |
* </blockquote> |
|
53 |
* |
|
54 |
* <p> There is one subclass of this class for each non-boolean primitive type. |
|
55 |
* |
|
56 |
* |
|
18574
4aeaeb541678
8019380: doclint warnings in java.nio, java.nio.file.**, java.nio.channels.**
alanb
parents:
18164
diff
changeset
|
57 |
* <h2> Transferring data </h2> |
2 | 58 |
* |
59 |
* <p> Each subclass of this class defines two categories of <i>get</i> and |
|
60 |
* <i>put</i> operations: </p> |
|
61 |
* |
|
62 |
* <blockquote> |
|
63 |
* |
|
64 |
* <p> <i>Relative</i> operations read or write one or more elements starting |
|
65 |
* at the current position and then increment the position by the number of |
|
66 |
* elements transferred. If the requested transfer exceeds the limit then a |
|
67 |
* relative <i>get</i> operation throws a {@link BufferUnderflowException} |
|
68 |
* and a relative <i>put</i> operation throws a {@link |
|
69 |
* BufferOverflowException}; in either case, no data is transferred. </p> |
|
70 |
* |
|
71 |
* <p> <i>Absolute</i> operations take an explicit element index and do not |
|
72 |
* affect the position. Absolute <i>get</i> and <i>put</i> operations throw |
|
73 |
* an {@link IndexOutOfBoundsException} if the index argument exceeds the |
|
74 |
* limit. </p> |
|
75 |
* |
|
76 |
* </blockquote> |
|
77 |
* |
|
78 |
* <p> Data may also, of course, be transferred in to or out of a buffer by the |
|
79 |
* I/O operations of an appropriate channel, which are always relative to the |
|
80 |
* current position. |
|
81 |
* |
|
82 |
* |
|
18574
4aeaeb541678
8019380: doclint warnings in java.nio, java.nio.file.**, java.nio.channels.**
alanb
parents:
18164
diff
changeset
|
83 |
* <h2> Marking and resetting </h2> |
2 | 84 |
* |
85 |
* <p> A buffer's <i>mark</i> is the index to which its position will be reset |
|
86 |
* when the {@link #reset reset} method is invoked. The mark is not always |
|
87 |
* defined, but when it is defined it is never negative and is never greater |
|
88 |
* than the position. If the mark is defined then it is discarded when the |
|
89 |
* position or the limit is adjusted to a value smaller than the mark. If the |
|
90 |
* mark is not defined then invoking the {@link #reset reset} method causes an |
|
91 |
* {@link InvalidMarkException} to be thrown. |
|
92 |
* |
|
93 |
* |
|
18574
4aeaeb541678
8019380: doclint warnings in java.nio, java.nio.file.**, java.nio.channels.**
alanb
parents:
18164
diff
changeset
|
94 |
* <h2> Invariants </h2> |
2 | 95 |
* |
96 |
* <p> The following invariant holds for the mark, position, limit, and |
|
97 |
* capacity values: |
|
98 |
* |
|
99 |
* <blockquote> |
|
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
100 |
* {@code 0} {@code <=} |
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
101 |
* <i>mark</i> {@code <=} |
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
102 |
* <i>position</i> {@code <=} |
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
103 |
* <i>limit</i> {@code <=} |
2 | 104 |
* <i>capacity</i> |
105 |
* </blockquote> |
|
106 |
* |
|
107 |
* <p> A newly-created buffer always has a position of zero and a mark that is |
|
108 |
* undefined. The initial limit may be zero, or it may be some other value |
|
109 |
* that depends upon the type of the buffer and the manner in which it is |
|
110 |
* constructed. Each element of a newly-allocated buffer is initialized |
|
111 |
* to zero. |
|
112 |
* |
|
113 |
* |
|
18574
4aeaeb541678
8019380: doclint warnings in java.nio, java.nio.file.**, java.nio.channels.**
alanb
parents:
18164
diff
changeset
|
114 |
* <h2> Clearing, flipping, and rewinding </h2> |
2 | 115 |
* |
116 |
* <p> In addition to methods for accessing the position, limit, and capacity |
|
117 |
* values and for marking and resetting, this class also defines the following |
|
118 |
* operations upon buffers: |
|
119 |
* |
|
120 |
* <ul> |
|
121 |
* |
|
122 |
* <li><p> {@link #clear} makes a buffer ready for a new sequence of |
|
123 |
* channel-read or relative <i>put</i> operations: It sets the limit to the |
|
124 |
* capacity and the position to zero. </p></li> |
|
125 |
* |
|
126 |
* <li><p> {@link #flip} makes a buffer ready for a new sequence of |
|
127 |
* channel-write or relative <i>get</i> operations: It sets the limit to the |
|
128 |
* current position and then sets the position to zero. </p></li> |
|
129 |
* |
|
130 |
* <li><p> {@link #rewind} makes a buffer ready for re-reading the data that |
|
131 |
* it already contains: It leaves the limit unchanged and sets the position |
|
132 |
* to zero. </p></li> |
|
133 |
* |
|
134 |
* </ul> |
|
135 |
* |
|
136 |
* |
|
18574
4aeaeb541678
8019380: doclint warnings in java.nio, java.nio.file.**, java.nio.channels.**
alanb
parents:
18164
diff
changeset
|
137 |
* <h2> Read-only buffers </h2> |
2 | 138 |
* |
139 |
* <p> Every buffer is readable, but not every buffer is writable. The |
|
140 |
* mutation methods of each buffer class are specified as <i>optional |
|
141 |
* operations</i> that will throw a {@link ReadOnlyBufferException} when |
|
142 |
* invoked upon a read-only buffer. A read-only buffer does not allow its |
|
143 |
* content to be changed, but its mark, position, and limit values are mutable. |
|
144 |
* Whether or not a buffer is read-only may be determined by invoking its |
|
145 |
* {@link #isReadOnly isReadOnly} method. |
|
146 |
* |
|
147 |
* |
|
18574
4aeaeb541678
8019380: doclint warnings in java.nio, java.nio.file.**, java.nio.channels.**
alanb
parents:
18164
diff
changeset
|
148 |
* <h2> Thread safety </h2> |
2 | 149 |
* |
150 |
* <p> Buffers are not safe for use by multiple concurrent threads. If a |
|
151 |
* buffer is to be used by more than one thread then access to the buffer |
|
152 |
* should be controlled by appropriate synchronization. |
|
153 |
* |
|
154 |
* |
|
18574
4aeaeb541678
8019380: doclint warnings in java.nio, java.nio.file.**, java.nio.channels.**
alanb
parents:
18164
diff
changeset
|
155 |
* <h2> Invocation chaining </h2> |
2 | 156 |
* |
157 |
* <p> Methods in this class that do not otherwise have a value to return are |
|
158 |
* specified to return the buffer upon which they are invoked. This allows |
|
159 |
* method invocations to be chained; for example, the sequence of statements |
|
160 |
* |
|
161 |
* <blockquote><pre> |
|
162 |
* b.flip(); |
|
163 |
* b.position(23); |
|
164 |
* b.limit(42);</pre></blockquote> |
|
165 |
* |
|
166 |
* can be replaced by the single, more compact statement |
|
167 |
* |
|
168 |
* <blockquote><pre> |
|
169 |
* b.flip().position(23).limit(42);</pre></blockquote> |
|
170 |
* |
|
171 |
* |
|
172 |
* @author Mark Reinhold |
|
173 |
* @author JSR-51 Expert Group |
|
174 |
* @since 1.4 |
|
175 |
*/ |
|
176 |
||
177 |
public abstract class Buffer { |
|
178 |
||
17922
d56eec572de5
8014854: (bf) CharBuffer.chars too slow with default implementation
alanb
parents:
10325
diff
changeset
|
179 |
/** |
d56eec572de5
8014854: (bf) CharBuffer.chars too slow with default implementation
alanb
parents:
10325
diff
changeset
|
180 |
* The characteristics of Spliterators that traverse and split elements |
d56eec572de5
8014854: (bf) CharBuffer.chars too slow with default implementation
alanb
parents:
10325
diff
changeset
|
181 |
* maintained in Buffers. |
d56eec572de5
8014854: (bf) CharBuffer.chars too slow with default implementation
alanb
parents:
10325
diff
changeset
|
182 |
*/ |
d56eec572de5
8014854: (bf) CharBuffer.chars too slow with default implementation
alanb
parents:
10325
diff
changeset
|
183 |
static final int SPLITERATOR_CHARACTERISTICS = |
d56eec572de5
8014854: (bf) CharBuffer.chars too slow with default implementation
alanb
parents:
10325
diff
changeset
|
184 |
Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED; |
d56eec572de5
8014854: (bf) CharBuffer.chars too slow with default implementation
alanb
parents:
10325
diff
changeset
|
185 |
|
2 | 186 |
// Invariants: mark <= position <= limit <= capacity |
187 |
private int mark = -1; |
|
188 |
private int position = 0; |
|
189 |
private int limit; |
|
190 |
private int capacity; |
|
191 |
||
36933
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
192 |
// Used by heap byte buffers or direct buffers with Unsafe access |
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
193 |
// For heap byte buffers this field will be the address relative to the |
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
194 |
// array base address and offset into that array. The address might |
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
195 |
// not align on a word boundary for slices, nor align at a long word |
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
196 |
// (8 byte) boundary for byte[] allocations on 32-bit systems. |
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
197 |
// For direct buffers it is the start address of the memory region. The |
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
198 |
// address might not align on a word boundary for slices, nor when created |
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
199 |
// using JNI, see NewDirectByteBuffer(void*, long). |
3e6453e2d833
8149469: ByteBuffer API and implementation enhancements for VarHandles
psandoz
parents:
32227
diff
changeset
|
200 |
// Should ideally be declared final |
2 | 201 |
// NOTE: hoisted here for speed in JNI GetDirectBufferAddress |
202 |
long address; |
|
203 |
||
204 |
// Creates a new buffer with the given mark, position, limit, and capacity, |
|
205 |
// after checking invariants. |
|
206 |
// |
|
207 |
Buffer(int mark, int pos, int lim, int cap) { // package-private |
|
208 |
if (cap < 0) |
|
31873
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
209 |
throw createCapacityException(cap); |
2 | 210 |
this.capacity = cap; |
211 |
limit(lim); |
|
212 |
position(pos); |
|
213 |
if (mark >= 0) { |
|
214 |
if (mark > pos) |
|
215 |
throw new IllegalArgumentException("mark > position: (" |
|
216 |
+ mark + " > " + pos + ")"); |
|
217 |
this.mark = mark; |
|
218 |
} |
|
219 |
} |
|
220 |
||
221 |
/** |
|
31873
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
222 |
* Returns an {@code IllegalArgumentException} indicating that the source |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
223 |
* and target are the same {@code Buffer}. Intended for use in |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
224 |
* {@code put(src)} when the parameter is the {@code Buffer} on which the |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
225 |
* method is being invoked. |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
226 |
* |
32227
34721a47bc92
8132478: [tidy] three new warnings from java docs (java.net, javax.annotation)
avstepan
parents:
32143
diff
changeset
|
227 |
* @return IllegalArgumentException |
34721a47bc92
8132478: [tidy] three new warnings from java docs (java.net, javax.annotation)
avstepan
parents:
32143
diff
changeset
|
228 |
* With a message indicating equal source and target buffers |
31873
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
229 |
*/ |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
230 |
static IllegalArgumentException createSameBufferException() { |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
231 |
return new IllegalArgumentException("The source buffer is this buffer"); |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
232 |
} |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
233 |
|
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
234 |
/** |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
235 |
* Verify that the capacity is nonnegative. |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
236 |
* |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
237 |
* @param capacity |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
238 |
* The new buffer's capacity, in $type$s |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
239 |
* |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
240 |
* @throws IllegalArgumentException |
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
241 |
* If the {@code capacity} is a negative integer |
31873
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
242 |
*/ |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
243 |
static IllegalArgumentException createCapacityException(int capacity) { |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
244 |
assert capacity < 0 : "capacity expected to be negative"; |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
245 |
return new IllegalArgumentException("capacity < 0: (" |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
246 |
+ capacity + " < 0)"); |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
247 |
} |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
248 |
|
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
249 |
/** |
18164 | 250 |
* Returns this buffer's capacity. |
2 | 251 |
* |
252 |
* @return The capacity of this buffer |
|
253 |
*/ |
|
254 |
public final int capacity() { |
|
255 |
return capacity; |
|
256 |
} |
|
257 |
||
258 |
/** |
|
18164 | 259 |
* Returns this buffer's position. |
2 | 260 |
* |
261 |
* @return The position of this buffer |
|
262 |
*/ |
|
263 |
public final int position() { |
|
264 |
return position; |
|
265 |
} |
|
266 |
||
267 |
/** |
|
268 |
* Sets this buffer's position. If the mark is defined and larger than the |
|
18164 | 269 |
* new position then it is discarded. |
2 | 270 |
* |
271 |
* @param newPosition |
|
272 |
* The new position value; must be non-negative |
|
273 |
* and no larger than the current limit |
|
274 |
* |
|
275 |
* @return This buffer |
|
276 |
* |
|
277 |
* @throws IllegalArgumentException |
|
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
278 |
* If the preconditions on {@code newPosition} do not hold |
2 | 279 |
*/ |
27292
7ff4b24b33ce
4774077: Use covariant return types in the NIO buffer hierarchy
rwarburton
parents:
25859
diff
changeset
|
280 |
public Buffer position(int newPosition) { |
31873
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
281 |
if (newPosition > limit | newPosition < 0) |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
282 |
throw createPositionException(newPosition); |
2 | 283 |
position = newPosition; |
284 |
if (mark > position) mark = -1; |
|
285 |
return this; |
|
286 |
} |
|
287 |
||
288 |
/** |
|
31873
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
289 |
* Verify that {@code 0 < newPosition <= limit} |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
290 |
* |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
291 |
* @param newPosition |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
292 |
* The new position value |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
293 |
* |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
294 |
* @throws IllegalArgumentException |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
295 |
* If the specified position is out of bounds. |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
296 |
*/ |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
297 |
private IllegalArgumentException createPositionException(int newPosition) { |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
298 |
String msg = null; |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
299 |
|
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
300 |
if (newPosition > limit) { |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
301 |
msg = "newPosition > limit: (" + newPosition + " > " + limit + ")"; |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
302 |
} else { // assume negative |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
303 |
assert newPosition < 0 : "newPosition expected to be negative"; |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
304 |
msg = "newPosition < 0: (" + newPosition + " < 0)"; |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
305 |
} |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
306 |
|
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
307 |
return new IllegalArgumentException(msg); |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
308 |
} |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
309 |
|
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
310 |
/** |
18164 | 311 |
* Returns this buffer's limit. |
2 | 312 |
* |
313 |
* @return The limit of this buffer |
|
314 |
*/ |
|
315 |
public final int limit() { |
|
316 |
return limit; |
|
317 |
} |
|
318 |
||
319 |
/** |
|
320 |
* Sets this buffer's limit. If the position is larger than the new limit |
|
321 |
* then it is set to the new limit. If the mark is defined and larger than |
|
18164 | 322 |
* the new limit then it is discarded. |
2 | 323 |
* |
324 |
* @param newLimit |
|
325 |
* The new limit value; must be non-negative |
|
326 |
* and no larger than this buffer's capacity |
|
327 |
* |
|
328 |
* @return This buffer |
|
329 |
* |
|
330 |
* @throws IllegalArgumentException |
|
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
331 |
* If the preconditions on {@code newLimit} do not hold |
2 | 332 |
*/ |
27292
7ff4b24b33ce
4774077: Use covariant return types in the NIO buffer hierarchy
rwarburton
parents:
25859
diff
changeset
|
333 |
public Buffer limit(int newLimit) { |
31873
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
334 |
if (newLimit > capacity | newLimit < 0) |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
335 |
throw createLimitException(newLimit); |
2 | 336 |
limit = newLimit; |
337 |
if (position > limit) position = limit; |
|
338 |
if (mark > limit) mark = -1; |
|
339 |
return this; |
|
340 |
} |
|
341 |
||
342 |
/** |
|
31873
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
343 |
* Verify that {@code 0 < newLimit <= capacity} |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
344 |
* |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
345 |
* @param newLimit |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
346 |
* The new limit value |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
347 |
* |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
348 |
* @throws IllegalArgumentException |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
349 |
* If the specified limit is out of bounds. |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
350 |
*/ |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
351 |
private IllegalArgumentException createLimitException(int newLimit) { |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
352 |
String msg = null; |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
353 |
|
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
354 |
if (newLimit > capacity) { |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
355 |
msg = "newLimit > capacity: (" + newLimit + " > " + capacity + ")"; |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
356 |
} else { // assume negative |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
357 |
assert newLimit < 0 : "newLimit expected to be negative"; |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
358 |
msg = "newLimit < 0: (" + newLimit + " < 0)"; |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
359 |
} |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
360 |
|
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
361 |
return new IllegalArgumentException(msg); |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
362 |
} |
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
363 |
|
87b015c2cd36
8065556: (bf) Buffer.position and other methods should include detail in IAE
bpb
parents:
31671
diff
changeset
|
364 |
/** |
18164 | 365 |
* Sets this buffer's mark at its position. |
2 | 366 |
* |
367 |
* @return This buffer |
|
368 |
*/ |
|
27292
7ff4b24b33ce
4774077: Use covariant return types in the NIO buffer hierarchy
rwarburton
parents:
25859
diff
changeset
|
369 |
public Buffer mark() { |
2 | 370 |
mark = position; |
371 |
return this; |
|
372 |
} |
|
373 |
||
374 |
/** |
|
375 |
* Resets this buffer's position to the previously-marked position. |
|
376 |
* |
|
377 |
* <p> Invoking this method neither changes nor discards the mark's |
|
378 |
* value. </p> |
|
379 |
* |
|
380 |
* @return This buffer |
|
381 |
* |
|
382 |
* @throws InvalidMarkException |
|
383 |
* If the mark has not been set |
|
384 |
*/ |
|
27292
7ff4b24b33ce
4774077: Use covariant return types in the NIO buffer hierarchy
rwarburton
parents:
25859
diff
changeset
|
385 |
public Buffer reset() { |
2 | 386 |
int m = mark; |
387 |
if (m < 0) |
|
388 |
throw new InvalidMarkException(); |
|
389 |
position = m; |
|
390 |
return this; |
|
391 |
} |
|
392 |
||
393 |
/** |
|
394 |
* Clears this buffer. The position is set to zero, the limit is set to |
|
395 |
* the capacity, and the mark is discarded. |
|
396 |
* |
|
397 |
* <p> Invoke this method before using a sequence of channel-read or |
|
398 |
* <i>put</i> operations to fill this buffer. For example: |
|
399 |
* |
|
400 |
* <blockquote><pre> |
|
401 |
* buf.clear(); // Prepare buffer for reading |
|
402 |
* in.read(buf); // Read data</pre></blockquote> |
|
403 |
* |
|
404 |
* <p> This method does not actually erase the data in the buffer, but it |
|
405 |
* is named as if it did because it will most often be used in situations |
|
406 |
* in which that might as well be the case. </p> |
|
407 |
* |
|
408 |
* @return This buffer |
|
409 |
*/ |
|
27292
7ff4b24b33ce
4774077: Use covariant return types in the NIO buffer hierarchy
rwarburton
parents:
25859
diff
changeset
|
410 |
public Buffer clear() { |
2 | 411 |
position = 0; |
412 |
limit = capacity; |
|
413 |
mark = -1; |
|
414 |
return this; |
|
415 |
} |
|
416 |
||
417 |
/** |
|
418 |
* Flips this buffer. The limit is set to the current position and then |
|
419 |
* the position is set to zero. If the mark is defined then it is |
|
420 |
* discarded. |
|
421 |
* |
|
422 |
* <p> After a sequence of channel-read or <i>put</i> operations, invoke |
|
423 |
* this method to prepare for a sequence of channel-write or relative |
|
424 |
* <i>get</i> operations. For example: |
|
425 |
* |
|
426 |
* <blockquote><pre> |
|
427 |
* buf.put(magic); // Prepend header |
|
428 |
* in.read(buf); // Read data into rest of buffer |
|
429 |
* buf.flip(); // Flip buffer |
|
430 |
* out.write(buf); // Write header + data to channel</pre></blockquote> |
|
431 |
* |
|
432 |
* <p> This method is often used in conjunction with the {@link |
|
433 |
* java.nio.ByteBuffer#compact compact} method when transferring data from |
|
434 |
* one place to another. </p> |
|
435 |
* |
|
436 |
* @return This buffer |
|
437 |
*/ |
|
27292
7ff4b24b33ce
4774077: Use covariant return types in the NIO buffer hierarchy
rwarburton
parents:
25859
diff
changeset
|
438 |
public Buffer flip() { |
2 | 439 |
limit = position; |
440 |
position = 0; |
|
441 |
mark = -1; |
|
442 |
return this; |
|
443 |
} |
|
444 |
||
445 |
/** |
|
446 |
* Rewinds this buffer. The position is set to zero and the mark is |
|
447 |
* discarded. |
|
448 |
* |
|
449 |
* <p> Invoke this method before a sequence of channel-write or <i>get</i> |
|
450 |
* operations, assuming that the limit has already been set |
|
451 |
* appropriately. For example: |
|
452 |
* |
|
453 |
* <blockquote><pre> |
|
454 |
* out.write(buf); // Write remaining data |
|
455 |
* buf.rewind(); // Rewind buffer |
|
456 |
* buf.get(array); // Copy data into array</pre></blockquote> |
|
457 |
* |
|
458 |
* @return This buffer |
|
459 |
*/ |
|
27292
7ff4b24b33ce
4774077: Use covariant return types in the NIO buffer hierarchy
rwarburton
parents:
25859
diff
changeset
|
460 |
public Buffer rewind() { |
2 | 461 |
position = 0; |
462 |
mark = -1; |
|
463 |
return this; |
|
464 |
} |
|
465 |
||
466 |
/** |
|
467 |
* Returns the number of elements between the current position and the |
|
18164 | 468 |
* limit. |
2 | 469 |
* |
470 |
* @return The number of elements remaining in this buffer |
|
471 |
*/ |
|
472 |
public final int remaining() { |
|
473 |
return limit - position; |
|
474 |
} |
|
475 |
||
476 |
/** |
|
477 |
* Tells whether there are any elements between the current position and |
|
18164 | 478 |
* the limit. |
2 | 479 |
* |
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
480 |
* @return {@code true} if, and only if, there is at least one element |
2 | 481 |
* remaining in this buffer |
482 |
*/ |
|
483 |
public final boolean hasRemaining() { |
|
484 |
return position < limit; |
|
485 |
} |
|
486 |
||
487 |
/** |
|
18164 | 488 |
* Tells whether or not this buffer is read-only. |
2 | 489 |
* |
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
490 |
* @return {@code true} if, and only if, this buffer is read-only |
2 | 491 |
*/ |
492 |
public abstract boolean isReadOnly(); |
|
493 |
||
494 |
/** |
|
495 |
* Tells whether or not this buffer is backed by an accessible |
|
496 |
* array. |
|
497 |
* |
|
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
498 |
* <p> If this method returns {@code true} then the {@link #array() array} |
2 | 499 |
* and {@link #arrayOffset() arrayOffset} methods may safely be invoked. |
500 |
* </p> |
|
501 |
* |
|
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
502 |
* @return {@code true} if, and only if, this buffer |
2 | 503 |
* is backed by an array and is not read-only |
504 |
* |
|
505 |
* @since 1.6 |
|
506 |
*/ |
|
507 |
public abstract boolean hasArray(); |
|
508 |
||
509 |
/** |
|
510 |
* Returns the array that backs this |
|
511 |
* buffer <i>(optional operation)</i>. |
|
512 |
* |
|
513 |
* <p> This method is intended to allow array-backed buffers to be |
|
514 |
* passed to native code more efficiently. Concrete subclasses |
|
515 |
* provide more strongly-typed return values for this method. |
|
516 |
* |
|
517 |
* <p> Modifications to this buffer's content will cause the returned |
|
518 |
* array's content to be modified, and vice versa. |
|
519 |
* |
|
520 |
* <p> Invoke the {@link #hasArray hasArray} method before invoking this |
|
521 |
* method in order to ensure that this buffer has an accessible backing |
|
522 |
* array. </p> |
|
523 |
* |
|
524 |
* @return The array that backs this buffer |
|
525 |
* |
|
526 |
* @throws ReadOnlyBufferException |
|
527 |
* If this buffer is backed by an array but is read-only |
|
528 |
* |
|
529 |
* @throws UnsupportedOperationException |
|
530 |
* If this buffer is not backed by an accessible array |
|
531 |
* |
|
532 |
* @since 1.6 |
|
533 |
*/ |
|
534 |
public abstract Object array(); |
|
535 |
||
536 |
/** |
|
537 |
* Returns the offset within this buffer's backing array of the first |
|
538 |
* element of the buffer <i>(optional operation)</i>. |
|
539 |
* |
|
540 |
* <p> If this buffer is backed by an array then buffer position <i>p</i> |
|
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
541 |
* corresponds to array index <i>p</i> + {@code arrayOffset()}. |
2 | 542 |
* |
543 |
* <p> Invoke the {@link #hasArray hasArray} method before invoking this |
|
544 |
* method in order to ensure that this buffer has an accessible backing |
|
545 |
* array. </p> |
|
546 |
* |
|
547 |
* @return The offset within this buffer's array |
|
548 |
* of the first element of the buffer |
|
549 |
* |
|
550 |
* @throws ReadOnlyBufferException |
|
551 |
* If this buffer is backed by an array but is read-only |
|
552 |
* |
|
553 |
* @throws UnsupportedOperationException |
|
554 |
* If this buffer is not backed by an accessible array |
|
555 |
* |
|
556 |
* @since 1.6 |
|
557 |
*/ |
|
558 |
public abstract int arrayOffset(); |
|
559 |
||
560 |
/** |
|
561 |
* Tells whether or not this buffer is |
|
18164 | 562 |
* <a href="ByteBuffer.html#direct"><i>direct</i></a>. |
2 | 563 |
* |
32143
394ab6a6658d
8133459: replace <tt> tags (obsolete in html5) in java.nio docs
avstepan
parents:
31873
diff
changeset
|
564 |
* @return {@code true} if, and only if, this buffer is direct |
2 | 565 |
* |
566 |
* @since 1.6 |
|
567 |
*/ |
|
568 |
public abstract boolean isDirect(); |
|
569 |
||
570 |
||
571 |
// -- Package-private methods for bounds checking, etc. -- |
|
572 |
||
573 |
/** |
|
574 |
* Checks the current position against the limit, throwing a {@link |
|
575 |
* BufferUnderflowException} if it is not smaller than the limit, and then |
|
18164 | 576 |
* increments the position. |
2 | 577 |
* |
578 |
* @return The current position value, before it is incremented |
|
579 |
*/ |
|
580 |
final int nextGetIndex() { // package-private |
|
581 |
if (position >= limit) |
|
582 |
throw new BufferUnderflowException(); |
|
583 |
return position++; |
|
584 |
} |
|
585 |
||
586 |
final int nextGetIndex(int nb) { // package-private |
|
587 |
if (limit - position < nb) |
|
588 |
throw new BufferUnderflowException(); |
|
589 |
int p = position; |
|
590 |
position += nb; |
|
591 |
return p; |
|
592 |
} |
|
593 |
||
594 |
/** |
|
595 |
* Checks the current position against the limit, throwing a {@link |
|
596 |
* BufferOverflowException} if it is not smaller than the limit, and then |
|
18164 | 597 |
* increments the position. |
2 | 598 |
* |
599 |
* @return The current position value, before it is incremented |
|
600 |
*/ |
|
601 |
final int nextPutIndex() { // package-private |
|
602 |
if (position >= limit) |
|
603 |
throw new BufferOverflowException(); |
|
604 |
return position++; |
|
605 |
} |
|
606 |
||
607 |
final int nextPutIndex(int nb) { // package-private |
|
608 |
if (limit - position < nb) |
|
609 |
throw new BufferOverflowException(); |
|
610 |
int p = position; |
|
611 |
position += nb; |
|
612 |
return p; |
|
613 |
} |
|
614 |
||
615 |
/** |
|
616 |
* Checks the given index against the limit, throwing an {@link |
|
617 |
* IndexOutOfBoundsException} if it is not smaller than the limit |
|
618 |
* or is smaller than zero. |
|
619 |
*/ |
|
31671
362e0c0acece
8076112: Add @HotSpotIntrinsicCandidate annotation to indicate methods for which Java Runtime has intrinsics
zmajo
parents:
27292
diff
changeset
|
620 |
@HotSpotIntrinsicCandidate |
2 | 621 |
final int checkIndex(int i) { // package-private |
622 |
if ((i < 0) || (i >= limit)) |
|
623 |
throw new IndexOutOfBoundsException(); |
|
624 |
return i; |
|
625 |
} |
|
626 |
||
627 |
final int checkIndex(int i, int nb) { // package-private |
|
628 |
if ((i < 0) || (nb > limit - i)) |
|
629 |
throw new IndexOutOfBoundsException(); |
|
630 |
return i; |
|
631 |
} |
|
632 |
||
633 |
final int markValue() { // package-private |
|
634 |
return mark; |
|
635 |
} |
|
636 |
||
10325
b72c20cd583a
7047325: Internal API to improve management of direct buffers
coffeys
parents:
5506
diff
changeset
|
637 |
final void truncate() { // package-private |
b72c20cd583a
7047325: Internal API to improve management of direct buffers
coffeys
parents:
5506
diff
changeset
|
638 |
mark = -1; |
b72c20cd583a
7047325: Internal API to improve management of direct buffers
coffeys
parents:
5506
diff
changeset
|
639 |
position = 0; |
b72c20cd583a
7047325: Internal API to improve management of direct buffers
coffeys
parents:
5506
diff
changeset
|
640 |
limit = 0; |
b72c20cd583a
7047325: Internal API to improve management of direct buffers
coffeys
parents:
5506
diff
changeset
|
641 |
capacity = 0; |
b72c20cd583a
7047325: Internal API to improve management of direct buffers
coffeys
parents:
5506
diff
changeset
|
642 |
} |
b72c20cd583a
7047325: Internal API to improve management of direct buffers
coffeys
parents:
5506
diff
changeset
|
643 |
|
1634
3871c2046043
6593946: (bf) X-Buffer.compact() does not discard mark as specified
alanb
parents:
2
diff
changeset
|
644 |
final void discardMark() { // package-private |
3871c2046043
6593946: (bf) X-Buffer.compact() does not discard mark as specified
alanb
parents:
2
diff
changeset
|
645 |
mark = -1; |
3871c2046043
6593946: (bf) X-Buffer.compact() does not discard mark as specified
alanb
parents:
2
diff
changeset
|
646 |
} |
3871c2046043
6593946: (bf) X-Buffer.compact() does not discard mark as specified
alanb
parents:
2
diff
changeset
|
647 |
|
2 | 648 |
static void checkBounds(int off, int len, int size) { // package-private |
649 |
if ((off | len | (off + len) | (size - (off + len))) < 0) |
|
650 |
throw new IndexOutOfBoundsException(); |
|
651 |
} |
|
652 |
||
653 |
} |