38 |
|
|
39 |
package java.nio; |
package java.nio; |
40 |
|
|
|
import gnu.classpath.Configuration; |
|
41 |
import gnu.classpath.RawData; |
import gnu.classpath.RawData; |
42 |
|
|
43 |
final class DirectByteBufferImpl extends ByteBuffer |
abstract class DirectByteBufferImpl extends ByteBuffer |
44 |
{ |
{ |
45 |
static |
/** 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(Object owner, RawData address, |
93 |
|
int capacity, int limit, |
94 |
|
int position) |
95 |
|
{ |
96 |
|
super(owner, address, capacity, limit, position); |
97 |
|
} |
98 |
|
|
99 |
|
public boolean isReadOnly() |
100 |
|
{ |
101 |
|
return false; |
102 |
|
} |
103 |
|
} |
104 |
|
|
105 |
|
DirectByteBufferImpl(int capacity) |
106 |
|
{ |
107 |
|
super(capacity, capacity, 0, -1); |
108 |
|
this.owner = this; |
109 |
|
this.address = VMDirectByteBuffer.allocate(capacity); |
110 |
|
} |
111 |
|
|
112 |
|
DirectByteBufferImpl(Object owner, RawData address, |
113 |
|
int capacity, int limit, |
114 |
|
int position) |
115 |
{ |
{ |
116 |
// load the shared library needed for native methods. |
super(capacity, limit, position, -1); |
117 |
if (Configuration.INIT_LOAD_LIBRARY) |
this.owner = owner; |
118 |
{ |
this.address = address; |
|
System.loadLibrary ("javanio"); |
|
|
} |
|
119 |
} |
} |
|
|
|
|
/** Used by MappedByteBufferImpl to prevent premature GC. */ |
|
|
protected Object owner; |
|
120 |
|
|
121 |
RawData address; |
/** |
122 |
private boolean readOnly; |
* Allocates a new direct byte buffer. |
123 |
|
*/ |
124 |
public DirectByteBufferImpl (RawData address, long len) |
public static ByteBuffer allocate(int capacity) |
125 |
{ |
{ |
126 |
this (null, address, (int) len, (int) len, 0, false); |
return new DirectByteBufferImpl.ReadWrite(capacity); |
|
} |
|
|
|
|
|
public DirectByteBufferImpl (Object owner, RawData address, |
|
|
int capacity, int limit, |
|
|
int position, boolean readOnly) |
|
|
{ |
|
|
super (capacity, limit, position, -1); |
|
|
this.address = address; |
|
|
this.readOnly = readOnly; |
|
|
this.owner = owner; |
|
127 |
} |
} |
128 |
|
|
129 |
private static native RawData allocateImpl (int capacity); |
protected void finalize() throws Throwable |
|
private static native void freeImpl (RawData address); |
|
|
|
|
|
protected void finalize () throws Throwable |
|
130 |
{ |
{ |
131 |
freeImpl (address); |
if (owner == this) |
132 |
|
VMDirectByteBuffer.free(address); |
133 |
} |
} |
134 |
|
|
135 |
static native byte getImpl (RawData address, int index); |
public byte get() |
|
static native void putImpl (RawData address, int index, byte value); |
|
|
|
|
|
public byte get () |
|
136 |
{ |
{ |
137 |
checkForUnderflow(); |
checkForUnderflow(); |
138 |
|
|
139 |
int pos = position(); |
int pos = position(); |
140 |
byte result = getImpl (address, pos); |
byte result = VMDirectByteBuffer.get(address, pos); |
141 |
position (pos + 1); |
position(pos + 1); |
142 |
return result; |
return result; |
143 |
} |
} |
144 |
|
|
145 |
public byte get (int index) |
public byte get(int index) |
146 |
{ |
{ |
147 |
checkIndex(index); |
checkIndex(index); |
148 |
|
|
149 |
return getImpl (address, index); |
return VMDirectByteBuffer.get(address, index); |
150 |
} |
} |
151 |
|
|
152 |
static native void getImpl (RawData address, int index, |
public ByteBuffer get(byte[] dst, int offset, int length) |
|
byte[] dst, int offset, int length); |
|
|
|
|
|
public ByteBuffer get (byte[] dst, int offset, int length) |
|
153 |
{ |
{ |
154 |
checkArraySize(dst.length, offset, length); |
checkArraySize(dst.length, offset, length); |
155 |
checkForUnderflow(length); |
checkForUnderflow(length); |
156 |
|
|
157 |
int index = position(); |
int index = position(); |
158 |
getImpl(address, index, dst, offset, length); |
VMDirectByteBuffer.get(address, index, dst, offset, length); |
159 |
position(index+length); |
position(index+length); |
160 |
|
|
161 |
return this; |
return this; |
162 |
} |
} |
163 |
|
|
164 |
public ByteBuffer put (byte value) |
public ByteBuffer put(byte value) |
165 |
{ |
{ |
|
checkIfReadOnly(); |
|
166 |
checkForOverflow(); |
checkForOverflow(); |
167 |
|
|
168 |
int pos = position(); |
int pos = position(); |
169 |
putImpl (address, pos, value); |
VMDirectByteBuffer.put(address, pos, value); |
170 |
position (pos + 1); |
position(pos + 1); |
171 |
return this; |
return this; |
172 |
} |
} |
173 |
|
|
174 |
public ByteBuffer put (int index, byte value) |
public ByteBuffer put(int index, byte value) |
175 |
{ |
{ |
|
checkIfReadOnly(); |
|
176 |
checkIndex(index); |
checkIndex(index); |
177 |
|
|
178 |
putImpl (address, index, value); |
VMDirectByteBuffer.put(address, index, value); |
179 |
return this; |
return this; |
180 |
} |
} |
181 |
|
|
|
static native void shiftDown(RawData address, int dst_offset, int src_offset, int count); |
|
|
|
|
182 |
void shiftDown(int dst_offset, int src_offset, int count) |
void shiftDown(int dst_offset, int src_offset, int count) |
183 |
{ |
{ |
184 |
shiftDown(address, dst_offset, src_offset, count); |
VMDirectByteBuffer.shiftDown(address, dst_offset, src_offset, count); |
185 |
} |
} |
186 |
|
|
187 |
public ByteBuffer compact () |
public ByteBuffer compact() |
188 |
{ |
{ |
189 |
int pos = position(); |
int pos = position(); |
190 |
if (pos > 0) |
if (pos > 0) |
191 |
{ |
{ |
192 |
int count = remaining(); |
int count = remaining(); |
193 |
shiftDown(address, 0, pos, count); |
VMDirectByteBuffer.shiftDown(address, 0, pos, count); |
194 |
position(count); |
position(count); |
195 |
limit(capacity()); |
limit(capacity()); |
196 |
} |
} |
197 |
return this; |
return this; |
198 |
} |
} |
199 |
|
|
200 |
public static native RawData adjustAddress(RawData address, int offset); |
public ByteBuffer slice() |
|
|
|
|
public ByteBuffer slice () |
|
201 |
{ |
{ |
202 |
int rem = remaining(); |
int rem = remaining(); |
203 |
return new DirectByteBufferImpl (owner, |
if (isReadOnly()) |
204 |
adjustAddress(address, position()), |
return new DirectByteBufferImpl.ReadOnly |
205 |
rem, rem, 0, isReadOnly ()); |
(owner, VMDirectByteBuffer.adjustAddress(address, position()), |
206 |
|
rem, rem, 0); |
207 |
|
else |
208 |
|
return new DirectByteBufferImpl.ReadWrite |
209 |
|
(owner, VMDirectByteBuffer.adjustAddress(address, position()), |
210 |
|
rem, rem, 0); |
211 |
} |
} |
212 |
|
|
213 |
private ByteBuffer duplicate (boolean readOnly) |
private ByteBuffer duplicate(boolean readOnly) |
214 |
{ |
{ |
215 |
int pos = position(); |
int pos = position(); |
216 |
reset(); |
reset(); |
217 |
int mark = position(); |
int mark = position(); |
218 |
position(pos); |
position(pos); |
219 |
DirectByteBufferImpl result |
DirectByteBufferImpl result; |
220 |
= new DirectByteBufferImpl (owner, address, capacity (), limit (), |
if (readOnly) |
221 |
pos, readOnly); |
result = new DirectByteBufferImpl.ReadOnly(owner, address, capacity(), |
222 |
|
limit(), pos); |
223 |
|
else |
224 |
|
result = new DirectByteBufferImpl.ReadWrite(owner, address, capacity(), |
225 |
|
limit(), pos); |
226 |
|
|
227 |
if (mark != pos) |
if (mark != pos) |
228 |
{ |
{ |
229 |
result.position(mark); |
result.position(mark); |
233 |
return result; |
return result; |
234 |
} |
} |
235 |
|
|
236 |
public ByteBuffer duplicate () |
public ByteBuffer duplicate() |
237 |
{ |
{ |
238 |
return duplicate(isReadOnly()); |
return duplicate(isReadOnly()); |
239 |
} |
} |
240 |
|
|
241 |
public ByteBuffer asReadOnlyBuffer () |
public ByteBuffer asReadOnlyBuffer() |
242 |
{ |
{ |
243 |
return duplicate(true); |
return duplicate(true); |
244 |
} |
} |
245 |
|
|
246 |
public boolean isReadOnly () |
public boolean isDirect() |
|
{ |
|
|
return readOnly; |
|
|
} |
|
|
|
|
|
public boolean isDirect () |
|
247 |
{ |
{ |
248 |
return true; |
return true; |
249 |
} |
} |
250 |
|
|
251 |
public CharBuffer asCharBuffer () |
public CharBuffer asCharBuffer() |
252 |
{ |
{ |
253 |
return new CharViewBufferImpl (this, remaining() >> 1); |
return new CharViewBufferImpl(this, remaining() >> 1); |
254 |
} |
} |
255 |
|
|
256 |
public ShortBuffer asShortBuffer () |
public ShortBuffer asShortBuffer() |
257 |
{ |
{ |
258 |
return new ShortViewBufferImpl (this, remaining() >> 1); |
return new ShortViewBufferImpl(this, remaining() >> 1); |
259 |
} |
} |
260 |
|
|
261 |
public IntBuffer asIntBuffer () |
public IntBuffer asIntBuffer() |
262 |
{ |
{ |
263 |
return new IntViewBufferImpl (this, remaining() >> 2); |
return new IntViewBufferImpl(this, remaining() >> 2); |
264 |
} |
} |
265 |
|
|
266 |
public LongBuffer asLongBuffer () |
public LongBuffer asLongBuffer() |
267 |
{ |
{ |
268 |
return new LongViewBufferImpl (this, remaining() >> 3); |
return new LongViewBufferImpl(this, remaining() >> 3); |
269 |
} |
} |
270 |
|
|
271 |
public FloatBuffer asFloatBuffer () |
public FloatBuffer asFloatBuffer() |
272 |
{ |
{ |
273 |
return new FloatViewBufferImpl (this, remaining() >> 2); |
return new FloatViewBufferImpl(this, remaining() >> 2); |
274 |
} |
} |
275 |
|
|
276 |
public DoubleBuffer asDoubleBuffer () |
public DoubleBuffer asDoubleBuffer() |
277 |
{ |
{ |
278 |
return new DoubleViewBufferImpl (this, remaining() >> 3); |
return new DoubleViewBufferImpl(this, remaining() >> 3); |
279 |
} |
} |
280 |
|
|
281 |
public char getChar () |
public char getChar() |
282 |
{ |
{ |
283 |
return ByteBufferHelper.getChar(this, order()); |
return ByteBufferHelper.getChar(this, order()); |
284 |
} |
} |
285 |
|
|
286 |
public ByteBuffer putChar (char value) |
public ByteBuffer putChar(char value) |
287 |
{ |
{ |
288 |
ByteBufferHelper.putChar(this, value, order()); |
ByteBufferHelper.putChar(this, value, order()); |
289 |
return this; |
return this; |
290 |
} |
} |
291 |
|
|
292 |
public char getChar (int index) |
public char getChar(int index) |
293 |
{ |
{ |
294 |
return ByteBufferHelper.getChar(this, index, order()); |
return ByteBufferHelper.getChar(this, index, order()); |
295 |
} |
} |
296 |
|
|
297 |
public ByteBuffer putChar (int index, char value) |
public ByteBuffer putChar(int index, char value) |
298 |
{ |
{ |
299 |
ByteBufferHelper.putChar(this, index, value, order()); |
ByteBufferHelper.putChar(this, index, value, order()); |
300 |
return this; |
return this; |
301 |
} |
} |
302 |
|
|
303 |
public short getShort () |
public short getShort() |
304 |
{ |
{ |
305 |
return ByteBufferHelper.getShort(this, order()); |
return ByteBufferHelper.getShort(this, order()); |
306 |
} |
} |
307 |
|
|
308 |
public ByteBuffer putShort (short value) |
public ByteBuffer putShort(short value) |
309 |
{ |
{ |
310 |
ByteBufferHelper.putShort(this, value, order()); |
ByteBufferHelper.putShort(this, value, order()); |
311 |
return this; |
return this; |
312 |
} |
} |
313 |
|
|
314 |
public short getShort (int index) |
public short getShort(int index) |
315 |
{ |
{ |
316 |
return ByteBufferHelper.getShort(this, index, order()); |
return ByteBufferHelper.getShort(this, index, order()); |
317 |
} |
} |
318 |
|
|
319 |
public ByteBuffer putShort (int index, short value) |
public ByteBuffer putShort(int index, short value) |
320 |
{ |
{ |
321 |
ByteBufferHelper.putShort(this, index, value, order()); |
ByteBufferHelper.putShort(this, index, value, order()); |
322 |
return this; |
return this; |
323 |
} |
} |
324 |
|
|
325 |
public int getInt () |
public int getInt() |
326 |
{ |
{ |
327 |
return ByteBufferHelper.getInt(this, order()); |
return ByteBufferHelper.getInt(this, order()); |
328 |
} |
} |
329 |
|
|
330 |
public ByteBuffer putInt (int value) |
public ByteBuffer putInt(int value) |
331 |
{ |
{ |
332 |
ByteBufferHelper.putInt(this, value, order()); |
ByteBufferHelper.putInt(this, value, order()); |
333 |
return this; |
return this; |
334 |
} |
} |
335 |
|
|
336 |
public int getInt (int index) |
public int getInt(int index) |
337 |
{ |
{ |
338 |
return ByteBufferHelper.getInt(this, index, order()); |
return ByteBufferHelper.getInt(this, index, order()); |
339 |
} |
} |
340 |
|
|
341 |
public ByteBuffer putInt (int index, int value) |
public ByteBuffer putInt(int index, int value) |
342 |
{ |
{ |
343 |
ByteBufferHelper.putInt(this, index, value, order()); |
ByteBufferHelper.putInt(this, index, value, order()); |
344 |
return this; |
return this; |
345 |
} |
} |
346 |
|
|
347 |
public long getLong () |
public long getLong() |
348 |
{ |
{ |
349 |
return ByteBufferHelper.getLong(this, order()); |
return ByteBufferHelper.getLong(this, order()); |
350 |
} |
} |
351 |
|
|
352 |
public ByteBuffer putLong (long value) |
public ByteBuffer putLong(long value) |
353 |
{ |
{ |
354 |
ByteBufferHelper.putLong (this, value, order()); |
ByteBufferHelper.putLong(this, value, order()); |
355 |
return this; |
return this; |
356 |
} |
} |
357 |
|
|
358 |
public long getLong (int index) |
public long getLong(int index) |
359 |
{ |
{ |
360 |
return ByteBufferHelper.getLong (this, index, order()); |
return ByteBufferHelper.getLong(this, index, order()); |
361 |
} |
} |
362 |
|
|
363 |
public ByteBuffer putLong (int index, long value) |
public ByteBuffer putLong(int index, long value) |
364 |
{ |
{ |
365 |
ByteBufferHelper.putLong (this, index, value, order()); |
ByteBufferHelper.putLong(this, index, value, order()); |
366 |
return this; |
return this; |
367 |
} |
} |
368 |
|
|
369 |
public float getFloat () |
public float getFloat() |
370 |
{ |
{ |
371 |
return ByteBufferHelper.getFloat (this, order()); |
return ByteBufferHelper.getFloat(this, order()); |
372 |
} |
} |
373 |
|
|
374 |
public ByteBuffer putFloat (float value) |
public ByteBuffer putFloat(float value) |
375 |
{ |
{ |
376 |
ByteBufferHelper.putFloat (this, value, order()); |
ByteBufferHelper.putFloat(this, value, order()); |
377 |
return this; |
return this; |
378 |
} |
} |
379 |
|
|
380 |
public float getFloat (int index) |
public float getFloat(int index) |
381 |
{ |
{ |
382 |
return ByteBufferHelper.getFloat (this, index, order()); |
return ByteBufferHelper.getFloat(this, index, order()); |
383 |
} |
} |
384 |
|
|
385 |
public ByteBuffer putFloat (int index, float value) |
public ByteBuffer putFloat(int index, float value) |
386 |
{ |
{ |
387 |
ByteBufferHelper.putFloat (this, index, value, order()); |
ByteBufferHelper.putFloat(this, index, value, order()); |
388 |
return this; |
return this; |
389 |
} |
} |
390 |
|
|
391 |
public double getDouble () |
public double getDouble() |
392 |
{ |
{ |
393 |
return ByteBufferHelper.getDouble (this, order()); |
return ByteBufferHelper.getDouble(this, order()); |
394 |
} |
} |
395 |
|
|
396 |
public ByteBuffer putDouble (double value) |
public ByteBuffer putDouble(double value) |
397 |
{ |
{ |
398 |
ByteBufferHelper.putDouble (this, value, order()); |
ByteBufferHelper.putDouble(this, value, order()); |
399 |
return this; |
return this; |
400 |
} |
} |
401 |
|
|
402 |
public double getDouble (int index) |
public double getDouble(int index) |
403 |
{ |
{ |
404 |
return ByteBufferHelper.getDouble (this, index, order()); |
return ByteBufferHelper.getDouble(this, index, order()); |
405 |
} |
} |
406 |
|
|
407 |
public ByteBuffer putDouble (int index, double value) |
public ByteBuffer putDouble(int index, double value) |
408 |
{ |
{ |
409 |
ByteBufferHelper.putDouble (this, index, value, order()); |
ByteBufferHelper.putDouble(this, index, value, order()); |
410 |
return this; |
return this; |
411 |
} |
} |
412 |
} |
} |