• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package java.nio;
18 
19 /** A buffer is a list of elements of a specific primitive type.
20  * <p>
21  * A buffer can be described by the following properties:
22  * <ul>
23  * <li>Capacity: the number of elements a buffer can hold. Capacity may not be negative and never changes.</li>
24  * <li>Position: a cursor of this buffer. Elements are read or written at the position if you do not specify an index explicitly.
25  * Position may not be negative and not greater than the limit.</li>
26  * <li>Limit: controls the scope of accessible elements. You can only read or write elements from index zero to
27  * <code>limit - 1</code>. Accessing elements out of the scope will cause an exception. Limit may not be negative and not greater
28  * than capacity.</li>
29  * <li>Mark: used to remember the current position, so that you can reset the position later. Mark may not be negative and no
30  * greater than position.</li>
31  * <li>A buffer can be read-only or read-write. Trying to modify the elements of a read-only buffer will cause a
32  * <code>ReadOnlyBufferException</code>, while changing the position, limit and mark of a read-only buffer is OK.</li>
33  * <li>A buffer can be direct or indirect. A direct buffer will try its best to take advantage of native memory APIs and it may
34  * not stay in the Java heap, thus it is not affected by garbage collection.</li>
35  * </ul>
36  * </p>
37  * <p>
38  * Buffers are not thread-safe. If concurrent access to a buffer instance is required, then the callers are responsible to take
39  * care of the synchronization issues.
40  * </p>
41  *
42  * @since Android 1.0 */
43 public abstract class Buffer {
44 
45 	/** <code>UNSET_MARK</code> means the mark has not been set. */
46 	final static int UNSET_MARK = -1;
47 
48 	/** The capacity of this buffer, which never change. */
49 	final int capacity;
50 
51 	/** <code>limit - 1</code> is the last element that can be read or written. Limit must be no less than zero and no greater than
52 	 * <code>capacity</code>. */
53 	int limit;
54 
55 	/** Mark is where position will be set when <code>reset()</code> is called. Mark is not set by default. Mark is always no less
56 	 * than zero and no greater than <code>position</code>. */
57 	int mark = UNSET_MARK;
58 
59 	/** The current position of this buffer. Position is always no less than zero and no greater than <code>limit</code>. */
60 	int position = 0;
61 
62 	/** Construct a buffer with the specified capacity.
63 	 *
64 	 * @param capacity the capacity of this buffer. */
Buffer(int capacity)65 	Buffer (int capacity) {
66 		super();
67 		if (capacity < 0) {
68 			throw new IllegalArgumentException();
69 		}
70 		this.capacity = this.limit = capacity;
71 	}
72 
73 	/** Returns the capacity of this buffer.
74 	 *
75 	 * @return the number of elements that are contained in this buffer.
76 	 * @since Android 1.0 */
capacity()77 	public final int capacity () {
78 		return capacity;
79 	}
80 
81 	/** Clears this buffer.
82 	 * <p>
83 	 * While the content of this buffer is not changed, the following internal changes take place: the current position is reset
84 	 * back to the start of the buffer, the value of the buffer limit is made equal to the capacity and mark is cleared.
85 	 * </p>
86 	 *
87 	 * @return this buffer.
88 	 * @since Android 1.0 */
clear()89 	public final Buffer clear () {
90 		position = 0;
91 		mark = UNSET_MARK;
92 		limit = capacity;
93 		return this;
94 	}
95 
96 	/** Flips this buffer.
97 	 * <p>
98 	 * The limit is set to the current position, then the position is set to zero, and the mark is cleared.
99 	 * </p>
100 	 * <p>
101 	 * The content of this buffer is not changed.
102 	 * </p>
103 	 *
104 	 * @return this buffer.
105 	 * @since Android 1.0 */
flip()106 	public final Buffer flip () {
107 		limit = position;
108 		position = 0;
109 		mark = UNSET_MARK;
110 		return this;
111 	}
112 
113 	/** Indicates if there are elements remaining in this buffer, that is if {@code position < limit}.
114 	 *
115 	 * @return {@code true} if there are elements remaining in this buffer, {@code false} otherwise.
116 	 * @since Android 1.0 */
hasRemaining()117 	public final boolean hasRemaining () {
118 		return position < limit;
119 	}
120 
121 	/** Indicates whether this buffer is read-only.
122 	 *
123 	 * @return {@code true} if this buffer is read-only, {@code false} otherwise.
124 	 * @since Android 1.0 */
isReadOnly()125 	public abstract boolean isReadOnly ();
126 
127 	/** Returns the limit of this buffer.
128 	 *
129 	 * @return the limit of this buffer.
130 	 * @since Android 1.0 */
limit()131 	public final int limit () {
132 		return limit;
133 	}
134 
135 	/** Sets the limit of this buffer.
136 	 * <p>
137 	 * If the current position in the buffer is in excess of <code>newLimit</code> then, on returning from this call, it will have
138 	 * been adjusted to be equivalent to <code>newLimit</code>. If the mark is set and is greater than the new limit, then it is
139 	 * cleared.
140 	 * </p>
141 	 *
142 	 * @param newLimit the new limit, must not be negative and not greater than capacity.
143 	 * @return this buffer.
144 	 * @exception IllegalArgumentException if <code>newLimit</code> is invalid.
145 	 * @since Android 1.0 */
limit(int newLimit)146 	public final Buffer limit (int newLimit) {
147 		if (newLimit < 0 || newLimit > capacity) {
148 			throw new IllegalArgumentException();
149 		}
150 
151 		limit = newLimit;
152 		if (position > newLimit) {
153 			position = newLimit;
154 		}
155 		if ((mark != UNSET_MARK) && (mark > newLimit)) {
156 			mark = UNSET_MARK;
157 		}
158 		return this;
159 	}
160 
161 	/** Marks the current position, so that the position may return to this point later by calling <code>reset()</code>.
162 	 *
163 	 * @return this buffer.
164 	 * @since Android 1.0 */
mark()165 	public final Buffer mark () {
166 		mark = position;
167 		return this;
168 	}
169 
170 	/** Returns the position of this buffer.
171 	 *
172 	 * @return the value of this buffer's current position.
173 	 * @since Android 1.0 */
position()174 	public final int position () {
175 		return position;
176 	}
177 
178 	/** Sets the position of this buffer.
179 	 * <p>
180 	 * If the mark is set and it is greater than the new position, then it is cleared.
181 	 * </p>
182 	 *
183 	 * @param newPosition the new position, must be not negative and not greater than limit.
184 	 * @return this buffer.
185 	 * @exception IllegalArgumentException if <code>newPosition</code> is invalid.
186 	 * @since Android 1.0 */
position(int newPosition)187 	public final Buffer position (int newPosition) {
188 		if (newPosition < 0 || newPosition > limit) {
189 			throw new IllegalArgumentException();
190 		}
191 
192 		position = newPosition;
193 		if ((mark != UNSET_MARK) && (mark > position)) {
194 			mark = UNSET_MARK;
195 		}
196 		return this;
197 	}
198 
199 	/** Returns the number of remaining elements in this buffer, that is {@code limit - position}.
200 	 *
201 	 * @return the number of remaining elements in this buffer.
202 	 * @since Android 1.0 */
remaining()203 	public final int remaining () {
204 		return limit - position;
205 	}
206 
207 	/** Resets the position of this buffer to the <code>mark</code>.
208 	 *
209 	 * @return this buffer.
210 	 * @exception InvalidMarkException if the mark is not set.
211 	 * @since Android 1.0 */
reset()212 	public final Buffer reset () {
213 		if (mark == UNSET_MARK) {
214 			throw new InvalidMarkException();
215 		}
216 		position = mark;
217 		return this;
218 	}
219 
220 	/** Rewinds this buffer.
221 	 * <p>
222 	 * The position is set to zero, and the mark is cleared. The content of this buffer is not changed.
223 	 * </p>
224 	 *
225 	 * @return this buffer.
226 	 * @since Android 1.0 */
rewind()227 	public final Buffer rewind () {
228 		position = 0;
229 		mark = UNSET_MARK;
230 		return this;
231 	}
232 }
233