]>
Commit | Line | Data |
---|---|---|
5560b019 | 1 | /* DirectByteBufferImpl.java -- |
40c23042 | 2 | Copyright (C) 2003, 2004 Free Software Foundation, Inc. |
5560b019 MK |
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 | ||
3a5eb283 | 39 | package java.nio; |
5560b019 | 40 | |
5560b019 MK |
41 | import gnu.gcj.RawData; |
42 | ||
b4345a57 | 43 | abstract class DirectByteBufferImpl extends ByteBuffer |
5560b019 | 44 | { |
b4345a57 JF |
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 | } | |
35d0b14d | 84 | |
b4345a57 JF |
85 | final static class ReadWrite extends DirectByteBufferImpl |
86 | { | |
87 | ReadWrite(int capacity) | |
88 | { | |
89 | super(capacity); | |
90 | } | |
91 | ||
7ef52736 MK |
92 | ReadWrite(RawData address, int capacity) |
93 | { | |
94 | super(address, capacity); | |
95 | } | |
96 | ||
b4345a57 JF |
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 | } | |
6f3aed57 | 109 | |
b4345a57 | 110 | DirectByteBufferImpl(int capacity) |
6f3aed57 | 111 | { |
b4345a57 JF |
112 | super(capacity, capacity, 0, -1); |
113 | this.owner = this; | |
114 | this.address = VMDirectByteBuffer.allocate(capacity); | |
6f3aed57 | 115 | } |
b4345a57 | 116 | |
7ef52736 MK |
117 | DirectByteBufferImpl(RawData address, int capacity) |
118 | { | |
119 | super(capacity, capacity, 0, -1); | |
120 | this.owner = this; | |
121 | this.address = address; | |
122 | } | |
123 | ||
b4345a57 JF |
124 | DirectByteBufferImpl(Object owner, RawData address, |
125 | int capacity, int limit, | |
126 | int position) | |
5560b019 | 127 | { |
b38cd28c | 128 | super(capacity, limit, position, -1); |
35d0b14d | 129 | this.owner = owner; |
b4345a57 | 130 | this.address = address; |
5560b019 MK |
131 | } |
132 | ||
4dbbd945 MK |
133 | /** |
134 | * Allocates a new direct byte buffer. | |
135 | */ | |
136 | public static ByteBuffer allocate(int capacity) | |
137 | { | |
b4345a57 | 138 | return new DirectByteBufferImpl.ReadWrite(capacity); |
4dbbd945 MK |
139 | } |
140 | ||
b38cd28c | 141 | protected void finalize() throws Throwable |
5560b019 | 142 | { |
b4345a57 JF |
143 | if (owner == this) |
144 | VMDirectByteBuffer.free(address); | |
5560b019 MK |
145 | } |
146 | ||
b38cd28c | 147 | public byte get() |
5560b019 | 148 | { |
23c41c08 DT |
149 | checkForUnderflow(); |
150 | ||
35d0b14d | 151 | int pos = position(); |
11dde1bb | 152 | byte result = VMDirectByteBuffer.get(address, pos); |
b38cd28c | 153 | position(pos + 1); |
5560b019 MK |
154 | return result; |
155 | } | |
156 | ||
b38cd28c | 157 | public byte get(int index) |
5560b019 | 158 | { |
23c41c08 DT |
159 | checkIndex(index); |
160 | ||
11dde1bb | 161 | return VMDirectByteBuffer.get(address, index); |
35d0b14d PB |
162 | } |
163 | ||
b38cd28c | 164 | public ByteBuffer get(byte[] dst, int offset, int length) |
35d0b14d | 165 | { |
23c41c08 DT |
166 | checkArraySize(dst.length, offset, length); |
167 | checkForUnderflow(length); | |
35d0b14d PB |
168 | |
169 | int index = position(); | |
11dde1bb | 170 | VMDirectByteBuffer.get(address, index, dst, offset, length); |
35d0b14d PB |
171 | position(index+length); |
172 | ||
173 | return this; | |
5560b019 MK |
174 | } |
175 | ||
b38cd28c | 176 | public ByteBuffer put(byte value) |
5560b019 | 177 | { |
23c41c08 DT |
178 | checkForOverflow(); |
179 | ||
35d0b14d | 180 | int pos = position(); |
11dde1bb | 181 | VMDirectByteBuffer.put(address, pos, value); |
b38cd28c | 182 | position(pos + 1); |
5560b019 MK |
183 | return this; |
184 | } | |
185 | ||
b38cd28c | 186 | public ByteBuffer put(int index, byte value) |
5560b019 | 187 | { |
23c41c08 DT |
188 | checkIndex(index); |
189 | ||
11dde1bb | 190 | VMDirectByteBuffer.put(address, index, value); |
5560b019 MK |
191 | return this; |
192 | } | |
193 | ||
86a80fc3 MK |
194 | void shiftDown(int dst_offset, int src_offset, int count) |
195 | { | |
11dde1bb | 196 | VMDirectByteBuffer.shiftDown(address, dst_offset, src_offset, count); |
86a80fc3 MK |
197 | } |
198 | ||
b38cd28c | 199 | public ByteBuffer compact() |
5560b019 | 200 | { |
40c23042 PB |
201 | int pos = position(); |
202 | if (pos > 0) | |
5560b019 | 203 | { |
40c23042 | 204 | int count = remaining(); |
11dde1bb | 205 | VMDirectByteBuffer.shiftDown(address, 0, pos, count); |
40c23042 PB |
206 | position(count); |
207 | limit(capacity()); | |
5560b019 | 208 | } |
5560b019 MK |
209 | return this; |
210 | } | |
211 | ||
b38cd28c | 212 | public ByteBuffer slice() |
5560b019 | 213 | { |
35d0b14d | 214 | int rem = remaining(); |
b4345a57 JF |
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 | |
11dde1bb | 221 | (owner, VMDirectByteBuffer.adjustAddress(address, position()), |
b4345a57 | 222 | rem, rem, 0); |
5560b019 MK |
223 | } |
224 | ||
b38cd28c | 225 | private ByteBuffer duplicate(boolean readOnly) |
35d0b14d PB |
226 | { |
227 | int pos = position(); | |
228 | reset(); | |
229 | int mark = position(); | |
230 | position(pos); | |
b4345a57 JF |
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 | ||
35d0b14d PB |
239 | if (mark != pos) |
240 | { | |
241 | result.position(mark); | |
242 | result.mark(); | |
243 | result.position(pos); | |
244 | } | |
245 | return result; | |
246 | } | |
247 | ||
b38cd28c | 248 | public ByteBuffer duplicate() |
5560b019 | 249 | { |
35d0b14d | 250 | return duplicate(isReadOnly()); |
5560b019 MK |
251 | } |
252 | ||
b38cd28c | 253 | public ByteBuffer asReadOnlyBuffer() |
5560b019 | 254 | { |
35d0b14d | 255 | return duplicate(true); |
5560b019 MK |
256 | } |
257 | ||
b38cd28c | 258 | public boolean isDirect() |
5560b019 MK |
259 | { |
260 | return true; | |
261 | } | |
262 | ||
b38cd28c | 263 | public CharBuffer asCharBuffer() |
5560b019 | 264 | { |
b38cd28c | 265 | return new CharViewBufferImpl(this, remaining() >> 1); |
5560b019 | 266 | } |
35d0b14d | 267 | |
b38cd28c | 268 | public ShortBuffer asShortBuffer() |
5560b019 | 269 | { |
b38cd28c | 270 | return new ShortViewBufferImpl(this, remaining() >> 1); |
5560b019 | 271 | } |
35d0b14d | 272 | |
b38cd28c | 273 | public IntBuffer asIntBuffer() |
5560b019 | 274 | { |
b38cd28c | 275 | return new IntViewBufferImpl(this, remaining() >> 2); |
5560b019 | 276 | } |
35d0b14d | 277 | |
b38cd28c | 278 | public LongBuffer asLongBuffer() |
5560b019 | 279 | { |
b38cd28c | 280 | return new LongViewBufferImpl(this, remaining() >> 3); |
5560b019 | 281 | } |
35d0b14d | 282 | |
b38cd28c | 283 | public FloatBuffer asFloatBuffer() |
5560b019 | 284 | { |
b38cd28c | 285 | return new FloatViewBufferImpl(this, remaining() >> 2); |
5560b019 | 286 | } |
35d0b14d | 287 | |
b38cd28c | 288 | public DoubleBuffer asDoubleBuffer() |
35d0b14d | 289 | { |
b38cd28c | 290 | return new DoubleViewBufferImpl(this, remaining() >> 3); |
35d0b14d PB |
291 | } |
292 | ||
b38cd28c | 293 | public char getChar() |
5560b019 | 294 | { |
40c23042 | 295 | return ByteBufferHelper.getChar(this, order()); |
5560b019 MK |
296 | } |
297 | ||
b38cd28c | 298 | public ByteBuffer putChar(char value) |
5560b019 | 299 | { |
40c23042 | 300 | ByteBufferHelper.putChar(this, value, order()); |
5560b019 MK |
301 | return this; |
302 | } | |
303 | ||
b38cd28c | 304 | public char getChar(int index) |
5560b019 | 305 | { |
40c23042 | 306 | return ByteBufferHelper.getChar(this, index, order()); |
5560b019 MK |
307 | } |
308 | ||
b38cd28c | 309 | public ByteBuffer putChar(int index, char value) |
5560b019 | 310 | { |
40c23042 | 311 | ByteBufferHelper.putChar(this, index, value, order()); |
5560b019 MK |
312 | return this; |
313 | } | |
314 | ||
b38cd28c | 315 | public short getShort() |
5560b019 | 316 | { |
40c23042 | 317 | return ByteBufferHelper.getShort(this, order()); |
5560b019 MK |
318 | } |
319 | ||
b38cd28c | 320 | public ByteBuffer putShort(short value) |
5560b019 | 321 | { |
40c23042 | 322 | ByteBufferHelper.putShort(this, value, order()); |
5560b019 MK |
323 | return this; |
324 | } | |
325 | ||
b38cd28c | 326 | public short getShort(int index) |
5560b019 | 327 | { |
40c23042 | 328 | return ByteBufferHelper.getShort(this, index, order()); |
5560b019 MK |
329 | } |
330 | ||
b38cd28c | 331 | public ByteBuffer putShort(int index, short value) |
5560b019 | 332 | { |
40c23042 | 333 | ByteBufferHelper.putShort(this, index, value, order()); |
5560b019 MK |
334 | return this; |
335 | } | |
336 | ||
b38cd28c | 337 | public int getInt() |
5560b019 | 338 | { |
40c23042 | 339 | return ByteBufferHelper.getInt(this, order()); |
5560b019 MK |
340 | } |
341 | ||
b38cd28c | 342 | public ByteBuffer putInt(int value) |
5560b019 | 343 | { |
40c23042 | 344 | ByteBufferHelper.putInt(this, value, order()); |
5560b019 MK |
345 | return this; |
346 | } | |
347 | ||
b38cd28c | 348 | public int getInt(int index) |
5560b019 | 349 | { |
40c23042 | 350 | return ByteBufferHelper.getInt(this, index, order()); |
5560b019 MK |
351 | } |
352 | ||
b38cd28c | 353 | public ByteBuffer putInt(int index, int value) |
5560b019 | 354 | { |
40c23042 | 355 | ByteBufferHelper.putInt(this, index, value, order()); |
5560b019 MK |
356 | return this; |
357 | } | |
358 | ||
b38cd28c | 359 | public long getLong() |
5560b019 | 360 | { |
40c23042 | 361 | return ByteBufferHelper.getLong(this, order()); |
5560b019 MK |
362 | } |
363 | ||
b38cd28c | 364 | public ByteBuffer putLong(long value) |
5560b019 | 365 | { |
b38cd28c | 366 | ByteBufferHelper.putLong(this, value, order()); |
40c23042 | 367 | return this; |
5560b019 MK |
368 | } |
369 | ||
b38cd28c | 370 | public long getLong(int index) |
5560b019 | 371 | { |
b38cd28c | 372 | return ByteBufferHelper.getLong(this, index, order()); |
5560b019 MK |
373 | } |
374 | ||
b38cd28c | 375 | public ByteBuffer putLong(int index, long value) |
5560b019 | 376 | { |
b38cd28c | 377 | ByteBufferHelper.putLong(this, index, value, order()); |
40c23042 | 378 | return this; |
5560b019 MK |
379 | } |
380 | ||
b38cd28c | 381 | public float getFloat() |
5560b019 | 382 | { |
b38cd28c | 383 | return ByteBufferHelper.getFloat(this, order()); |
5560b019 MK |
384 | } |
385 | ||
b38cd28c | 386 | public ByteBuffer putFloat(float value) |
5560b019 | 387 | { |
b38cd28c | 388 | ByteBufferHelper.putFloat(this, value, order()); |
40c23042 | 389 | return this; |
5560b019 MK |
390 | } |
391 | ||
b38cd28c | 392 | public float getFloat(int index) |
5560b019 | 393 | { |
b38cd28c | 394 | return ByteBufferHelper.getFloat(this, index, order()); |
5560b019 MK |
395 | } |
396 | ||
b38cd28c | 397 | public ByteBuffer putFloat(int index, float value) |
5560b019 | 398 | { |
b38cd28c | 399 | ByteBufferHelper.putFloat(this, index, value, order()); |
40c23042 | 400 | return this; |
5560b019 MK |
401 | } |
402 | ||
b38cd28c | 403 | public double getDouble() |
5560b019 | 404 | { |
b38cd28c | 405 | return ByteBufferHelper.getDouble(this, order()); |
5560b019 MK |
406 | } |
407 | ||
b38cd28c | 408 | public ByteBuffer putDouble(double value) |
5560b019 | 409 | { |
b38cd28c | 410 | ByteBufferHelper.putDouble(this, value, order()); |
40c23042 | 411 | return this; |
5560b019 MK |
412 | } |
413 | ||
b38cd28c | 414 | public double getDouble(int index) |
5560b019 | 415 | { |
b38cd28c | 416 | return ByteBufferHelper.getDouble(this, index, order()); |
5560b019 MK |
417 | } |
418 | ||
b38cd28c | 419 | public ByteBuffer putDouble(int index, double value) |
5560b019 | 420 | { |
b38cd28c | 421 | ByteBufferHelper.putDouble(this, index, value, order()); |
40c23042 | 422 | return this; |
5560b019 MK |
423 | } |
424 | } |