History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/nio/Buffer.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/nio/Buffer.java+555−0
@@ -0,0 +1,555 @@
1+/*
2+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
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
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
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+ *
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.
24+ */
25+
26+package java.nio;
27+
28+
29+/**
30+ * A container for data of a specific primitive type.
31+ *
32+ * <p> A buffer is a linear, finite sequence of elements of a specific
33+ * primitive type. Aside from its content, the essential properties of a
34+ * buffer are its capacity, limit, and position: </p>
35+ *
36+ * <blockquote>
37+ *
38+ * <p> A buffer's <i>capacity</i> is the number of elements it contains. The
39+ * capacity of a buffer is never negative and never changes. </p>
40+ *
41+ * <p> A buffer's <i>limit</i> is the index of the first element that should
42+ * not be read or written. A buffer's limit is never negative and is never
43+ * greater than its capacity. </p>
44+ *
45+ * <p> A buffer's <i>position</i> is the index of the next element to be
46+ * read or written. A buffer's position is never negative and is never
47+ * greater than its limit. </p>
48+ *
49+ * </blockquote>
50+ *
51+ * <p> There is one subclass of this class for each non-boolean primitive type.
52+ *
53+ *
54+ * <h4> Transferring data </h4>
55+ *
56+ * <p> Each subclass of this class defines two categories of <i>get</i> and
57+ * <i>put</i> operations: </p>
58+ *
59+ * <blockquote>
60+ *
61+ * <p> <i>Relative</i> operations read or write one or more elements starting
62+ * at the current position and then increment the position by the number of
63+ * elements transferred. If the requested transfer exceeds the limit then a
64+ * relative <i>get</i> operation throws a {@link BufferUnderflowException}
65+ * and a relative <i>put</i> operation throws a {@link
66+ * BufferOverflowException}; in either case, no data is transferred. </p>
67+ *
68+ * <p> <i>Absolute</i> operations take an explicit element index and do not
69+ * affect the position. Absolute <i>get</i> and <i>put</i> operations throw
70+ * an {@link IndexOutOfBoundsException} if the index argument exceeds the
71+ * limit. </p>
72+ *
73+ * </blockquote>
74+ *
75+ * <p> Data may also, of course, be transferred in to or out of a buffer by the
76+ * I/O operations of an appropriate channel, which are always relative to the
77+ * current position.
78+ *
79+ *
80+ * <h4> Marking and resetting </h4>
81+ *
82+ * <p> A buffer's <i>mark</i> is the index to which its position will be reset
83+ * when the {@link #reset reset} method is invoked. The mark is not always
84+ * defined, but when it is defined it is never negative and is never greater
85+ * than the position. If the mark is defined then it is discarded when the
86+ * position or the limit is adjusted to a value smaller than the mark. If the
87+ * mark is not defined then invoking the {@link #reset reset} method causes an
88+ * {@link InvalidMarkException} to be thrown.
89+ *
90+ *
91+ * <h4> Invariants </h4>
92+ *
93+ * <p> The following invariant holds for the mark, position, limit, and
94+ * capacity values:
95+ *
96+ * <blockquote>
97+ * <tt>0</tt> <tt>&lt;=</tt>
98+ * <i>mark</i> <tt>&lt;=</tt>
99+ * <i>position</i> <tt>&lt;=</tt>
100+ * <i>limit</i> <tt>&lt;=</tt>
101+ * <i>capacity</i>
102+ * </blockquote>
103+ *
104+ * <p> A newly-created buffer always has a position of zero and a mark that is
105+ * undefined. The initial limit may be zero, or it may be some other value
106+ * that depends upon the type of the buffer and the manner in which it is
107+ * constructed. Each element of a newly-allocated buffer is initialized
108+ * to zero.
109+ *
110+ *
111+ * <h4> Clearing, flipping, and rewinding </h4>
112+ *
113+ * <p> In addition to methods for accessing the position, limit, and capacity
114+ * values and for marking and resetting, this class also defines the following
115+ * operations upon buffers:
116+ *
117+ * <ul>
118+ *
119+ * <li><p> {@link #clear} makes a buffer ready for a new sequence of
120+ * channel-read or relative <i>put</i> operations: It sets the limit to the
121+ * capacity and the position to zero. </p></li>
122+ *
123+ * <li><p> {@link #flip} makes a buffer ready for a new sequence of
124+ * channel-write or relative <i>get</i> operations: It sets the limit to the
125+ * current position and then sets the position to zero. </p></li>
126+ *
127+ * <li><p> {@link #rewind} makes a buffer ready for re-reading the data that
128+ * it already contains: It leaves the limit unchanged and sets the position
129+ * to zero. </p></li>
130+ *
131+ * </ul>
132+ *
133+ *
134+ * <h4> Read-only buffers </h4>
135+ *
136+ * <p> Every buffer is readable, but not every buffer is writable. The
137+ * mutation methods of each buffer class are specified as <i>optional
138+ * operations</i> that will throw a {@link ReadOnlyBufferException} when
139+ * invoked upon a read-only buffer. A read-only buffer does not allow its
140+ * content to be changed, but its mark, position, and limit values are mutable.
141+ * Whether or not a buffer is read-only may be determined by invoking its
142+ * {@link #isReadOnly isReadOnly} method.
143+ *
144+ *
145+ * <h4> Thread safety </h4>
146+ *
147+ * <p> Buffers are not safe for use by multiple concurrent threads. If a
148+ * buffer is to be used by more than one thread then access to the buffer
149+ * should be controlled by appropriate synchronization.
150+ *
151+ *
152+ * <h4> Invocation chaining </h4>
153+ *
154+ * <p> Methods in this class that do not otherwise have a value to return are
155+ * specified to return the buffer upon which they are invoked. This allows
156+ * method invocations to be chained; for example, the sequence of statements
157+ *
158+ * <blockquote><pre>
159+ * b.flip();
160+ * b.position(23);
161+ * b.limit(42);</pre></blockquote>
162+ *
163+ * can be replaced by the single, more compact statement
164+ *
165+ * <blockquote><pre>
166+ * b.flip().position(23).limit(42);</pre></blockquote>
167+ *
168+ *
169+ * @author Mark Reinhold
170+ * @author JSR-51 Expert Group
171+ * @since 1.4
172+ */
173+
174+public abstract class Buffer {
175+
176+ // Invariants: mark <= position <= limit <= capacity
177+ private int mark = -1;
178+ private int position = 0;
179+ private int limit;
180+ private int capacity;
181+
182+ // Used only by direct buffers
183+ // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
184+ long address;
185+
186+ // Creates a new buffer with the given mark, position, limit, and capacity,
187+ // after checking invariants.
188+ //
189+ Buffer(int mark, int pos, int lim, int cap) { // package-private
190+ if (cap < 0)
191+ throw new IllegalArgumentException("Negative capacity: " + cap);
192+ this.capacity = cap;
193+ limit(lim);
194+ position(pos);
195+ if (mark >= 0) {
196+ if (mark > pos)
197+ throw new IllegalArgumentException("mark > position: ("
198+ + mark + " > " + pos + ")");
199+ this.mark = mark;
200+ }
201+ }
202+
203+ /**
204+ * Returns this buffer's capacity. </p>
205+ *
206+ * @return The capacity of this buffer
207+ */
208+ public final int capacity() {
209+ return capacity;
210+ }
211+
212+ /**
213+ * Returns this buffer's position. </p>
214+ *
215+ * @return The position of this buffer
216+ */
217+ public final int position() {
218+ return position;
219+ }
220+
221+ /**
222+ * Sets this buffer's position. If the mark is defined and larger than the
223+ * new position then it is discarded. </p>
224+ *
225+ * @param newPosition
226+ * The new position value; must be non-negative
227+ * and no larger than the current limit
228+ *
229+ * @return This buffer
230+ *
231+ * @throws IllegalArgumentException
232+ * If the preconditions on <tt>newPosition</tt> do not hold
233+ */
234+ public final Buffer position(int newPosition) {
235+ if ((newPosition > limit) || (newPosition < 0))
236+ throw new IllegalArgumentException();
237+ position = newPosition;
238+ if (mark > position) mark = -1;
239+ return this;
240+ }
241+
242+ /**
243+ * Returns this buffer's limit. </p>
244+ *
245+ * @return The limit of this buffer
246+ */
247+ public final int limit() {
248+ return limit;
249+ }
250+
251+ /**
252+ * Sets this buffer's limit. If the position is larger than the new limit
253+ * then it is set to the new limit. If the mark is defined and larger than
254+ * the new limit then it is discarded. </p>
255+ *
256+ * @param newLimit
257+ * The new limit value; must be non-negative
258+ * and no larger than this buffer's capacity
259+ *
260+ * @return This buffer
261+ *
262+ * @throws IllegalArgumentException
263+ * If the preconditions on <tt>newLimit</tt> do not hold
264+ */
265+ public final Buffer limit(int newLimit) {
266+ if ((newLimit > capacity) || (newLimit < 0))
267+ throw new IllegalArgumentException();
268+ limit = newLimit;
269+ if (position > limit) position = limit;
270+ if (mark > limit) mark = -1;
271+ return this;
272+ }
273+
274+ /**
275+ * Sets this buffer's mark at its position. </p>
276+ *
277+ * @return This buffer
278+ */
279+ public final Buffer mark() {
280+ mark = position;
281+ return this;
282+ }
283+
284+ /**
285+ * Resets this buffer's position to the previously-marked position.
286+ *
287+ * <p> Invoking this method neither changes nor discards the mark's
288+ * value. </p>
289+ *
290+ * @return This buffer
291+ *
292+ * @throws InvalidMarkException
293+ * If the mark has not been set
294+ */
295+ public final Buffer reset() {
296+ int m = mark;
297+ if (m < 0)
298+ throw new InvalidMarkException();
299+ position = m;
300+ return this;
301+ }
302+
303+ /**
304+ * Clears this buffer. The position is set to zero, the limit is set to
305+ * the capacity, and the mark is discarded.
306+ *
307+ * <p> Invoke this method before using a sequence of channel-read or
308+ * <i>put</i> operations to fill this buffer. For example:
309+ *
310+ * <blockquote><pre>
311+ * buf.clear(); // Prepare buffer for reading
312+ * in.read(buf); // Read data</pre></blockquote>
313+ *
314+ * <p> This method does not actually erase the data in the buffer, but it
315+ * is named as if it did because it will most often be used in situations
316+ * in which that might as well be the case. </p>
317+ *
318+ * @return This buffer
319+ */
320+ public final Buffer clear() {
321+ position = 0;
322+ limit = capacity;
323+ mark = -1;
324+ return this;
325+ }
326+
327+ /**
328+ * Flips this buffer. The limit is set to the current position and then
329+ * the position is set to zero. If the mark is defined then it is
330+ * discarded.
331+ *
332+ * <p> After a sequence of channel-read or <i>put</i> operations, invoke
333+ * this method to prepare for a sequence of channel-write or relative
334+ * <i>get</i> operations. For example:
335+ *
336+ * <blockquote><pre>
337+ * buf.put(magic); // Prepend header
338+ * in.read(buf); // Read data into rest of buffer
339+ * buf.flip(); // Flip buffer
340+ * out.write(buf); // Write header + data to channel</pre></blockquote>
341+ *
342+ * <p> This method is often used in conjunction with the {@link
343+ * java.nio.ByteBuffer#compact compact} method when transferring data from
344+ * one place to another. </p>
345+ *
346+ * @return This buffer
347+ */
348+ public final Buffer flip() {
349+ limit = position;
350+ position = 0;
351+ mark = -1;
352+ return this;
353+ }
354+
355+ /**
356+ * Rewinds this buffer. The position is set to zero and the mark is
357+ * discarded.
358+ *
359+ * <p> Invoke this method before a sequence of channel-write or <i>get</i>
360+ * operations, assuming that the limit has already been set
361+ * appropriately. For example:
362+ *
363+ * <blockquote><pre>
364+ * out.write(buf); // Write remaining data
365+ * buf.rewind(); // Rewind buffer
366+ * buf.get(array); // Copy data into array</pre></blockquote>
367+ *
368+ * @return This buffer
369+ */
370+ public final Buffer rewind() {
371+ position = 0;
372+ mark = -1;
373+ return this;
374+ }
375+
376+ /**
377+ * Returns the number of elements between the current position and the
378+ * limit. </p>
379+ *
380+ * @return The number of elements remaining in this buffer
381+ */
382+ public final int remaining() {
383+ return limit - position;
384+ }
385+
386+ /**
387+ * Tells whether there are any elements between the current position and
388+ * the limit. </p>
389+ *
390+ * @return <tt>true</tt> if, and only if, there is at least one element
391+ * remaining in this buffer
392+ */
393+ public final boolean hasRemaining() {
394+ return position < limit;
395+ }
396+
397+ /**
398+ * Tells whether or not this buffer is read-only. </p>
399+ *
400+ * @return <tt>true</tt> if, and only if, this buffer is read-only
401+ */
402+ public abstract boolean isReadOnly();
403+
404+ /**
405+ * Tells whether or not this buffer is backed by an accessible
406+ * array.
407+ *
408+ * <p> If this method returns <tt>true</tt> then the {@link #array() array}
409+ * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
410+ * </p>
411+ *
412+ * @return <tt>true</tt> if, and only if, this buffer
413+ * is backed by an array and is not read-only
414+ *
415+ * @since 1.6
416+ */
417+ public abstract boolean hasArray();
418+
419+ /**
420+ * Returns the array that backs this
421+ * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
422+ *
423+ * <p> This method is intended to allow array-backed buffers to be
424+ * passed to native code more efficiently. Concrete subclasses
425+ * provide more strongly-typed return values for this method.
426+ *
427+ * <p> Modifications to this buffer's content will cause the returned
428+ * array's content to be modified, and vice versa.
429+ *
430+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
431+ * method in order to ensure that this buffer has an accessible backing
432+ * array. </p>
433+ *
434+ * @return The array that backs this buffer
435+ *
436+ * @throws ReadOnlyBufferException
437+ * If this buffer is backed by an array but is read-only
438+ *
439+ * @throws UnsupportedOperationException
440+ * If this buffer is not backed by an accessible array
441+ *
442+ * @since 1.6
443+ */
444+ public abstract Object array();
445+
446+ /**
447+ * Returns the offset within this buffer's backing array of the first
448+ * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
449+ *
450+ * <p> If this buffer is backed by an array then buffer position <i>p</i>
451+ * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
452+ *
453+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
454+ * method in order to ensure that this buffer has an accessible backing
455+ * array. </p>
456+ *
457+ * @return The offset within this buffer's array
458+ * of the first element of the buffer
459+ *
460+ * @throws ReadOnlyBufferException
461+ * If this buffer is backed by an array but is read-only
462+ *
463+ * @throws UnsupportedOperationException
464+ * If this buffer is not backed by an accessible array
465+ *
466+ * @since 1.6
467+ */
468+ public abstract int arrayOffset();
469+
470+ /**
471+ * Tells whether or not this buffer is
472+ * <a href="ByteBuffer.html#direct"><i>direct</i></a>. </p>
473+ *
474+ * @return <tt>true</tt> if, and only if, this buffer is direct
475+ *
476+ * @since 1.6
477+ */
478+ public abstract boolean isDirect();
479+
480+
481+ // -- Package-private methods for bounds checking, etc. --
482+
483+ /**
484+ * Checks the current position against the limit, throwing a {@link
485+ * BufferUnderflowException} if it is not smaller than the limit, and then
486+ * increments the position. </p>
487+ *
488+ * @return The current position value, before it is incremented
489+ */
490+ final int nextGetIndex() { // package-private
491+ if (position >= limit)
492+ throw new BufferUnderflowException();
493+ return position++;
494+ }
495+
496+ final int nextGetIndex(int nb) { // package-private
497+ if (limit - position < nb)
498+ throw new BufferUnderflowException();
499+ int p = position;
500+ position += nb;
501+ return p;
502+ }
503+
504+ /**
505+ * Checks the current position against the limit, throwing a {@link
506+ * BufferOverflowException} if it is not smaller than the limit, and then
507+ * increments the position. </p>
508+ *
509+ * @return The current position value, before it is incremented
510+ */
511+ final int nextPutIndex() { // package-private
512+ if (position >= limit)
513+ throw new BufferOverflowException();
514+ return position++;
515+ }
516+
517+ final int nextPutIndex(int nb) { // package-private
518+ if (limit - position < nb)
519+ throw new BufferOverflowException();
520+ int p = position;
521+ position += nb;
522+ return p;
523+ }
524+
525+ /**
526+ * Checks the given index against the limit, throwing an {@link
527+ * IndexOutOfBoundsException} if it is not smaller than the limit
528+ * or is smaller than zero.
529+ */
530+ final int checkIndex(int i) { // package-private
531+ if ((i < 0) || (i >= limit))
532+ throw new IndexOutOfBoundsException();
533+ return i;
534+ }
535+
536+ final int checkIndex(int i, int nb) { // package-private
537+ if ((i < 0) || (nb > limit - i))
538+ throw new IndexOutOfBoundsException();
539+ return i;
540+ }
541+
542+ final int markValue() { // package-private
543+ return mark;
544+ }
545+
546+ final void discardMark() { // package-private
547+ mark = -1;
548+ }
549+
550+ static void checkBounds(int off, int len, int size) { // package-private
551+ if ((off | len | (off + len) | (size - (off + len))) < 0)
552+ throw new IndexOutOfBoundsException();
553+ }
554+
555+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t