d73f090cdb7ffbe31c9de0dff037146568734b31
[gcc.git] / libjava / java / nio / DirectByteBufferImpl.java
1 /* DirectByteBufferImpl.java --
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package java.nio;
40
41 import gnu.gcj.RawData;
42
43 abstract class DirectByteBufferImpl extends ByteBuffer
44 {
45 /** The owner is used to keep alive the object that actually owns the
46 * memory. There are three possibilities:
47 * 1) owner == this: We allocated the memory and we should free it,
48 * but *only* in finalize (if we've been sliced
49 * other objects will also have access to the
50 * memory).
51 * 2) owner == null: The byte buffer was created thru
52 * JNI.NewDirectByteBuffer. The JNI code is
53 * responsible for freeing the memory.
54 * 3) owner == some other object: The other object allocated the
55 * memory and should free it.
56 */
57 private final Object owner;
58 final RawData address;
59
60 final static class ReadOnly extends DirectByteBufferImpl
61 {
62 ReadOnly(Object owner, RawData address,
63 int capacity, int limit,
64 int position)
65 {
66 super(owner, address, capacity, limit, position);
67 }
68
69 public ByteBuffer put(byte value)
70 {
71 throw new ReadOnlyBufferException ();
72 }
73
74 public ByteBuffer put(int index, byte value)
75 {
76 throw new ReadOnlyBufferException ();
77 }
78
79 public boolean isReadOnly()
80 {
81 return true;
82 }
83 }
84
85 final static class ReadWrite extends DirectByteBufferImpl
86 {
87 ReadWrite(int capacity)
88 {
89 super(capacity);
90 }
91
92 ReadWrite(RawData address, int capacity)
93 {
94 super(address, capacity);
95 }
96
97 ReadWrite(Object owner, RawData address,
98 int capacity, int limit,
99 int position)
100 {
101 super(owner, address, capacity, limit, position);
102 }
103
104 public boolean isReadOnly()
105 {
106 return false;
107 }
108 }
109
110 DirectByteBufferImpl(int capacity)
111 {
112 super(capacity, capacity, 0, -1);
113 this.owner = this;
114 this.address = VMDirectByteBuffer.allocate(capacity);
115 }
116
117 DirectByteBufferImpl(RawData address, int capacity)
118 {
119 super(capacity, capacity, 0, -1);
120 this.owner = this;
121 this.address = address;
122 }
123
124 DirectByteBufferImpl(Object owner, RawData address,
125 int capacity, int limit,
126 int position)
127 {
128 super(capacity, limit, position, -1);
129 this.owner = owner;
130 this.address = address;
131 }
132
133 /**
134 * Allocates a new direct byte buffer.
135 */
136 public static ByteBuffer allocate(int capacity)
137 {
138 return new DirectByteBufferImpl.ReadWrite(capacity);
139 }
140
141 protected void finalize() throws Throwable
142 {
143 if (owner == this)
144 VMDirectByteBuffer.free(address);
145 }
146
147 public byte get()
148 {
149 checkForUnderflow();
150
151 int pos = position();
152 byte result = VMDirectByteBuffer.get(address, pos);
153 position(pos + 1);
154 return result;
155 }
156
157 public byte get(int index)
158 {
159 checkIndex(index);
160
161 return VMDirectByteBuffer.get(address, index);
162 }
163
164 public ByteBuffer get(byte[] dst, int offset, int length)
165 {
166 checkArraySize(dst.length, offset, length);
167 checkForUnderflow(length);
168
169 int index = position();
170 VMDirectByteBuffer.get(address, index, dst, offset, length);
171 position(index+length);
172
173 return this;
174 }
175
176 public ByteBuffer put(byte value)
177 {
178 checkForOverflow();
179
180 int pos = position();
181 VMDirectByteBuffer.put(address, pos, value);
182 position(pos + 1);
183 return this;
184 }
185
186 public ByteBuffer put(int index, byte value)
187 {
188 checkIndex(index);
189
190 VMDirectByteBuffer.put(address, index, value);
191 return this;
192 }
193
194 void shiftDown(int dst_offset, int src_offset, int count)
195 {
196 VMDirectByteBuffer.shiftDown(address, dst_offset, src_offset, count);
197 }
198
199 public ByteBuffer compact()
200 {
201 int pos = position();
202 if (pos > 0)
203 {
204 int count = remaining();
205 VMDirectByteBuffer.shiftDown(address, 0, pos, count);
206 position(count);
207 limit(capacity());
208 }
209 return this;
210 }
211
212 public ByteBuffer slice()
213 {
214 int rem = remaining();
215 if (isReadOnly())
216 return new DirectByteBufferImpl.ReadOnly
217 (owner, VMDirectByteBuffer.adjustAddress(address, position()),
218 rem, rem, 0);
219 else
220 return new DirectByteBufferImpl.ReadWrite
221 (owner, VMDirectByteBuffer.adjustAddress(address, position()),
222 rem, rem, 0);
223 }
224
225 private ByteBuffer duplicate(boolean readOnly)
226 {
227 int pos = position();
228 reset();
229 int mark = position();
230 position(pos);
231 DirectByteBufferImpl result;
232 if (readOnly)
233 result = new DirectByteBufferImpl.ReadOnly(owner, address, capacity(),
234 limit(), pos);
235 else
236 result = new DirectByteBufferImpl.ReadWrite(owner, address, capacity(),
237 limit(), pos);
238
239 if (mark != pos)
240 {
241 result.position(mark);
242 result.mark();
243 result.position(pos);
244 }
245 return result;
246 }
247
248 public ByteBuffer duplicate()
249 {
250 return duplicate(isReadOnly());
251 }
252
253 public ByteBuffer asReadOnlyBuffer()
254 {
255 return duplicate(true);
256 }
257
258 public boolean isDirect()
259 {
260 return true;
261 }
262
263 public CharBuffer asCharBuffer()
264 {
265 return new CharViewBufferImpl(this, remaining() >> 1);
266 }
267
268 public ShortBuffer asShortBuffer()
269 {
270 return new ShortViewBufferImpl(this, remaining() >> 1);
271 }
272
273 public IntBuffer asIntBuffer()
274 {
275 return new IntViewBufferImpl(this, remaining() >> 2);
276 }
277
278 public LongBuffer asLongBuffer()
279 {
280 return new LongViewBufferImpl(this, remaining() >> 3);
281 }
282
283 public FloatBuffer asFloatBuffer()
284 {
285 return new FloatViewBufferImpl(this, remaining() >> 2);
286 }
287
288 public DoubleBuffer asDoubleBuffer()
289 {
290 return new DoubleViewBufferImpl(this, remaining() >> 3);
291 }
292
293 public char getChar()
294 {
295 return ByteBufferHelper.getChar(this, order());
296 }
297
298 public ByteBuffer putChar(char value)
299 {
300 ByteBufferHelper.putChar(this, value, order());
301 return this;
302 }
303
304 public char getChar(int index)
305 {
306 return ByteBufferHelper.getChar(this, index, order());
307 }
308
309 public ByteBuffer putChar(int index, char value)
310 {
311 ByteBufferHelper.putChar(this, index, value, order());
312 return this;
313 }
314
315 public short getShort()
316 {
317 return ByteBufferHelper.getShort(this, order());
318 }
319
320 public ByteBuffer putShort(short value)
321 {
322 ByteBufferHelper.putShort(this, value, order());
323 return this;
324 }
325
326 public short getShort(int index)
327 {
328 return ByteBufferHelper.getShort(this, index, order());
329 }
330
331 public ByteBuffer putShort(int index, short value)
332 {
333 ByteBufferHelper.putShort(this, index, value, order());
334 return this;
335 }
336
337 public int getInt()
338 {
339 return ByteBufferHelper.getInt(this, order());
340 }
341
342 public ByteBuffer putInt(int value)
343 {
344 ByteBufferHelper.putInt(this, value, order());
345 return this;
346 }
347
348 public int getInt(int index)
349 {
350 return ByteBufferHelper.getInt(this, index, order());
351 }
352
353 public ByteBuffer putInt(int index, int value)
354 {
355 ByteBufferHelper.putInt(this, index, value, order());
356 return this;
357 }
358
359 public long getLong()
360 {
361 return ByteBufferHelper.getLong(this, order());
362 }
363
364 public ByteBuffer putLong(long value)
365 {
366 ByteBufferHelper.putLong(this, value, order());
367 return this;
368 }
369
370 public long getLong(int index)
371 {
372 return ByteBufferHelper.getLong(this, index, order());
373 }
374
375 public ByteBuffer putLong(int index, long value)
376 {
377 ByteBufferHelper.putLong(this, index, value, order());
378 return this;
379 }
380
381 public float getFloat()
382 {
383 return ByteBufferHelper.getFloat(this, order());
384 }
385
386 public ByteBuffer putFloat(float value)
387 {
388 ByteBufferHelper.putFloat(this, value, order());
389 return this;
390 }
391
392 public float getFloat(int index)
393 {
394 return ByteBufferHelper.getFloat(this, index, order());
395 }
396
397 public ByteBuffer putFloat(int index, float value)
398 {
399 ByteBufferHelper.putFloat(this, index, value, order());
400 return this;
401 }
402
403 public double getDouble()
404 {
405 return ByteBufferHelper.getDouble(this, order());
406 }
407
408 public ByteBuffer putDouble(double value)
409 {
410 ByteBufferHelper.putDouble(this, value, order());
411 return this;
412 }
413
414 public double getDouble(int index)
415 {
416 return ByteBufferHelper.getDouble(this, index, order());
417 }
418
419 public ByteBuffer putDouble(int index, double value)
420 {
421 ByteBufferHelper.putDouble(this, index, value, order());
422 return this;
423 }
424 }