OSDN Git Service

* configure.ac (INTERPRETER): New AM_CONDITIONAL.
[pf3gnuchains/gcc-fork.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., 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.gcj.RawData;
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, 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   static final 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 = null;
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     checkIfReadOnly();
202     mark = -1;
203     int pos = position();
204     if (pos > 0)
205       {
206         int count = remaining();
207         VMDirectByteBuffer.shiftDown(address, 0, pos, count);
208         position(count);
209         limit(capacity());
210       }
211     else
212       {
213         position(limit());
214         limit(capacity());
215       }
216     return this;
217   }
218
219   public ByteBuffer slice()
220   {
221     int rem = remaining();
222     if (isReadOnly())
223         return new DirectByteBufferImpl.ReadOnly
224       (owner, VMDirectByteBuffer.adjustAddress(address, position()),
225        rem, rem, 0);
226     else
227         return new DirectByteBufferImpl.ReadWrite
228       (owner, VMDirectByteBuffer.adjustAddress(address, position()),
229        rem, rem, 0);
230   }
231
232   private ByteBuffer duplicate(boolean readOnly)
233   {
234     int pos = position();
235     reset();
236     int mark = position();
237     position(pos);
238     DirectByteBufferImpl result;
239     if (readOnly)
240         result = new DirectByteBufferImpl.ReadOnly(owner, address, capacity(),
241                                                    limit(), pos);
242     else
243         result = new DirectByteBufferImpl.ReadWrite(owner, address, capacity(),
244                                                     limit(), pos);
245
246     if (mark != pos)
247       {
248         result.position(mark);
249         result.mark();
250         result.position(pos);
251       }
252     return result;
253   }
254
255   public ByteBuffer duplicate()
256   {
257     return duplicate(isReadOnly());
258   }
259
260   public ByteBuffer asReadOnlyBuffer()
261   {
262     return duplicate(true);
263   }
264
265   public boolean isDirect()
266   {
267     return true;
268   }
269
270   public CharBuffer asCharBuffer()
271   {
272     return new CharViewBufferImpl(this, remaining() >> 1);
273   }
274
275   public ShortBuffer asShortBuffer()
276   {
277     return new ShortViewBufferImpl(this, remaining() >> 1);
278   }
279
280   public IntBuffer asIntBuffer()
281   {
282     return new IntViewBufferImpl(this, remaining() >> 2);
283   }
284
285   public LongBuffer asLongBuffer()
286   {
287     return new LongViewBufferImpl(this, remaining() >> 3);
288   }
289
290   public FloatBuffer asFloatBuffer()
291   {
292     return new FloatViewBufferImpl(this, remaining() >> 2);
293   }
294
295   public DoubleBuffer asDoubleBuffer()
296   {
297     return new DoubleViewBufferImpl(this, remaining() >> 3);
298   }
299
300   public char getChar()
301   {
302     return ByteBufferHelper.getChar(this, order());
303   }
304   
305   public ByteBuffer putChar(char value)
306   {
307     ByteBufferHelper.putChar(this, value, order());
308     return this;
309   }
310   
311   public char getChar(int index)
312   {
313     return ByteBufferHelper.getChar(this, index, order());
314   }
315   
316   public ByteBuffer putChar(int index, char value)
317   {
318     ByteBufferHelper.putChar(this, index, value, order());
319     return this;
320   }
321
322   public short getShort()
323   {
324     return ByteBufferHelper.getShort(this, order());
325   }
326   
327   public ByteBuffer putShort(short value)
328   {
329     ByteBufferHelper.putShort(this, value, order());
330     return this;
331   }
332   
333   public short getShort(int index)
334   {
335     return ByteBufferHelper.getShort(this, index, order());
336   }
337   
338   public ByteBuffer putShort(int index, short value)
339   {
340     ByteBufferHelper.putShort(this, index, value, order());
341     return this;
342   }
343
344   public int getInt()
345   {
346     return ByteBufferHelper.getInt(this, order());
347   }
348   
349   public ByteBuffer putInt(int value)
350   {
351     ByteBufferHelper.putInt(this, value, order());
352     return this;
353   }
354   
355   public int getInt(int index)
356   {
357     return ByteBufferHelper.getInt(this, index, order());
358   }
359   
360   public ByteBuffer putInt(int index, int value)
361   {
362     ByteBufferHelper.putInt(this, index, value, order());
363     return this;
364   }
365
366   public long getLong()
367   {
368     return ByteBufferHelper.getLong(this, order());
369   }
370   
371   public ByteBuffer putLong(long value)
372   {
373     ByteBufferHelper.putLong(this, value, order());
374     return this;
375   }
376   
377   public long getLong(int index)
378   {
379     return ByteBufferHelper.getLong(this, index, order());
380   }
381   
382   public ByteBuffer putLong(int index, long value)
383   {
384     ByteBufferHelper.putLong(this, index, value, order());
385     return this;
386   }
387
388   public float getFloat()
389   {
390     return ByteBufferHelper.getFloat(this, order());
391   }
392   
393   public ByteBuffer putFloat(float value)
394   {
395     ByteBufferHelper.putFloat(this, value, order());
396     return this;
397   }
398   
399   public float getFloat(int index)
400   {
401     return ByteBufferHelper.getFloat(this, index, order());
402   }
403
404   public ByteBuffer putFloat(int index, float value)
405   {
406     ByteBufferHelper.putFloat(this, index, value, order());
407     return this;
408   }
409
410   public double getDouble()
411   {
412     return ByteBufferHelper.getDouble(this, order());
413   }
414
415   public ByteBuffer putDouble(double value)
416   {
417     ByteBufferHelper.putDouble(this, value, order());
418     return this;
419   }
420   
421   public double getDouble(int index)
422   {
423     return ByteBufferHelper.getDouble(this, index, order());
424   }
425   
426   public ByteBuffer putDouble(int index, double value)
427   {
428     ByteBufferHelper.putDouble(this, index, value, order());
429     return this;
430   }
431 }