OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / 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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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.classpath.Pointer;
42
43 abstract class DirectByteBufferImpl extends ByteBuffer
44 {
45   /**
46    * The owner is used to keep alive the object that actually owns the
47    * memory. There are three possibilities:
48    *  1) owner == this: We allocated the memory and we should free it,
49    *                    but *only* in finalize (if we've been sliced
50    *                    other objects will also have access to the
51    *                    memory).
52    *  2) owner == null: The byte buffer was created thru
53    *                    JNI.NewDirectByteBuffer. The JNI code is
54    *                    responsible for freeing the memory.
55    *  3) owner == some other object: The other object allocated the
56    *                                 memory and should free it.
57    */
58   private final Object owner;
59
60   static final class ReadOnly extends DirectByteBufferImpl
61   {
62     ReadOnly(Object owner, Pointer 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   static final class ReadWrite extends DirectByteBufferImpl
86   {
87     ReadWrite(int capacity)
88     {
89       super(capacity);
90     }
91
92     ReadWrite(Object owner, Pointer 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, VMDirectByteBuffer.allocate(capacity), null, 0);
108     this.owner = this;
109   }
110
111   DirectByteBufferImpl(Object owner, Pointer address,
112                        int capacity, int limit,
113                        int position)
114   {
115     super(capacity, limit, position, -1, address, null, 0);
116     this.owner = owner;
117   }
118
119   /**
120    * Allocates a new direct byte buffer.
121    */
122   public static ByteBuffer allocate(int capacity)
123   {
124     return new DirectByteBufferImpl.ReadWrite(capacity);
125   }
126
127   protected void finalize() throws Throwable
128   {
129     if (owner == this)
130         VMDirectByteBuffer.free(address);
131   }
132
133   public byte get()
134   {
135     checkForUnderflow();
136
137     int pos = position();
138     byte result = VMDirectByteBuffer.get(address, pos);
139     position(pos + 1);
140     return result;
141   }
142
143   public byte get(int index)
144   {
145     checkIndex(index);
146
147     return VMDirectByteBuffer.get(address, index);
148   }
149
150   public ByteBuffer get(byte[] dst, int offset, int length)
151   {
152     checkArraySize(dst.length, offset, length);
153     checkForUnderflow(length);
154
155     int index = position();
156     VMDirectByteBuffer.get(address, index, dst, offset, length);
157     position(index+length);
158
159     return this;
160   }
161
162   public ByteBuffer put(byte value)
163   {
164     checkForOverflow();
165
166     int pos = position();
167     VMDirectByteBuffer.put(address, pos, value);
168     position(pos + 1);
169     return this;
170   }
171
172   public ByteBuffer put(int index, byte value)
173   {
174     checkIndex(index);
175
176     VMDirectByteBuffer.put(address, index, value);
177     return this;
178   }
179
180   public ByteBuffer put (byte[] src, int offset, int length)
181   {
182     checkArraySize (src.length, offset, length);
183     checkForUnderflow (length);
184
185     int index = position ();
186     VMDirectByteBuffer.put (address, index, src, offset, length);
187     position (index + length);
188
189     return this;
190   }
191
192   void shiftDown(int dst_offset, int src_offset, int count)
193   {
194     VMDirectByteBuffer.shiftDown(address, dst_offset, src_offset, count);
195   }
196
197   public ByteBuffer compact()
198   {
199     checkIfReadOnly();
200     mark = -1;
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     else
210       {
211         position(limit());
212         limit(capacity());
213       }
214     return this;
215   }
216
217   public ByteBuffer slice()
218   {
219     int rem = remaining();
220     if (isReadOnly())
221         return new DirectByteBufferImpl.ReadOnly
222       (owner, VMDirectByteBuffer.adjustAddress(address, position()),
223        rem, rem, 0);
224     else
225         return new DirectByteBufferImpl.ReadWrite
226       (owner, VMDirectByteBuffer.adjustAddress(address, position()),
227        rem, rem, 0);
228   }
229
230   private ByteBuffer duplicate(boolean readOnly)
231   {
232     int pos = position();
233     if (this.mark != -1)
234       reset();
235     int mark = position();
236     position(pos);
237     DirectByteBufferImpl result;
238     if (readOnly)
239         result = new DirectByteBufferImpl.ReadOnly(owner, address, capacity(),
240                                                    limit(), pos);
241     else
242         result = new DirectByteBufferImpl.ReadWrite(owner, address, capacity(),
243                                                     limit(), pos);
244
245     if (mark != pos)
246       {
247         result.position(mark);
248         result.mark();
249         result.position(pos);
250       }
251     return result;
252   }
253
254   public ByteBuffer duplicate()
255   {
256     return duplicate(isReadOnly());
257   }
258
259   public ByteBuffer asReadOnlyBuffer()
260   {
261     return duplicate(true);
262   }
263
264   public boolean isDirect()
265   {
266     return true;
267   }
268
269   public CharBuffer asCharBuffer()
270   {
271     return new CharViewBufferImpl(this, remaining() >> 1);
272   }
273
274   public ShortBuffer asShortBuffer()
275   {
276     return new ShortViewBufferImpl(this, remaining() >> 1);
277   }
278
279   public IntBuffer asIntBuffer()
280   {
281     return new IntViewBufferImpl(this, remaining() >> 2);
282   }
283
284   public LongBuffer asLongBuffer()
285   {
286     return new LongViewBufferImpl(this, remaining() >> 3);
287   }
288
289   public FloatBuffer asFloatBuffer()
290   {
291     return new FloatViewBufferImpl(this, remaining() >> 2);
292   }
293
294   public DoubleBuffer asDoubleBuffer()
295   {
296     return new DoubleViewBufferImpl(this, remaining() >> 3);
297   }
298
299   public char getChar()
300   {
301     return ByteBufferHelper.getChar(this, order());
302   }
303
304   public ByteBuffer putChar(char value)
305   {
306     ByteBufferHelper.putChar(this, value, order());
307     return this;
308   }
309
310   public char getChar(int index)
311   {
312     return ByteBufferHelper.getChar(this, index, order());
313   }
314
315   public ByteBuffer putChar(int index, char value)
316   {
317     ByteBufferHelper.putChar(this, index, value, order());
318     return this;
319   }
320
321   public short getShort()
322   {
323     return ByteBufferHelper.getShort(this, order());
324   }
325
326   public ByteBuffer putShort(short value)
327   {
328     ByteBufferHelper.putShort(this, value, order());
329     return this;
330   }
331
332   public short getShort(int index)
333   {
334     return ByteBufferHelper.getShort(this, index, order());
335   }
336
337   public ByteBuffer putShort(int index, short value)
338   {
339     ByteBufferHelper.putShort(this, index, value, order());
340     return this;
341   }
342
343   public int getInt()
344   {
345     return ByteBufferHelper.getInt(this, order());
346   }
347
348   public ByteBuffer putInt(int value)
349   {
350     ByteBufferHelper.putInt(this, value, order());
351     return this;
352   }
353
354   public int getInt(int index)
355   {
356     return ByteBufferHelper.getInt(this, index, order());
357   }
358
359   public ByteBuffer putInt(int index, int value)
360   {
361     ByteBufferHelper.putInt(this, index, value, order());
362     return this;
363   }
364
365   public long getLong()
366   {
367     return ByteBufferHelper.getLong(this, order());
368   }
369
370   public ByteBuffer putLong(long value)
371   {
372     ByteBufferHelper.putLong(this, value, order());
373     return this;
374   }
375
376   public long getLong(int index)
377   {
378     return ByteBufferHelper.getLong(this, index, order());
379   }
380
381   public ByteBuffer putLong(int index, long value)
382   {
383     ByteBufferHelper.putLong(this, index, value, order());
384     return this;
385   }
386
387   public float getFloat()
388   {
389     return ByteBufferHelper.getFloat(this, order());
390   }
391
392   public ByteBuffer putFloat(float value)
393   {
394     ByteBufferHelper.putFloat(this, value, order());
395     return this;
396   }
397
398   public float getFloat(int index)
399   {
400     return ByteBufferHelper.getFloat(this, index, order());
401   }
402
403   public ByteBuffer putFloat(int index, float value)
404   {
405     ByteBufferHelper.putFloat(this, index, value, order());
406     return this;
407   }
408
409   public double getDouble()
410   {
411     return ByteBufferHelper.getDouble(this, order());
412   }
413
414   public ByteBuffer putDouble(double value)
415   {
416     ByteBufferHelper.putDouble(this, value, order());
417     return this;
418   }
419
420   public double getDouble(int index)
421   {
422     return ByteBufferHelper.getDouble(this, index, order());
423   }
424
425   public ByteBuffer putDouble(int index, double value)
426   {
427     ByteBufferHelper.putDouble(this, index, value, order());
428     return this;
429   }
430 }