OSDN Git Service

Imported Classpath 0.18.
[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);
108     this.owner = this;
109     this.address = VMDirectByteBuffer.allocate(capacity);
110   }
111
112   DirectByteBufferImpl(Object owner, Pointer address,
113                        int capacity, int limit,
114                        int position)
115   {
116     super(capacity, limit, position, -1);
117     this.owner = owner;
118     this.address = address;
119   }
120
121   /**
122    * Allocates a new direct byte buffer.
123    */
124   public static ByteBuffer allocate(int capacity)
125   {
126     return new DirectByteBufferImpl.ReadWrite(capacity);
127   }
128
129   protected void finalize() throws Throwable
130   {
131     if (owner == this)
132         VMDirectByteBuffer.free(address);
133   }
134
135   public byte get()
136   {
137     checkForUnderflow();
138
139     int pos = position();
140     byte result = VMDirectByteBuffer.get(address, pos);
141     position(pos + 1);
142     return result;
143   }
144
145   public byte get(int index)
146   {
147     checkIndex(index);
148
149     return VMDirectByteBuffer.get(address, index);
150   }
151
152   public ByteBuffer get(byte[] dst, int offset, int length)
153   {
154     checkArraySize(dst.length, offset, length);
155     checkForUnderflow(length);
156
157     int index = position();
158     VMDirectByteBuffer.get(address, index, dst, offset, length);
159     position(index+length);
160
161     return this;
162   }
163
164   public ByteBuffer put(byte value)
165   {
166     checkForOverflow();
167
168     int pos = position();
169     VMDirectByteBuffer.put(address, pos, value);
170     position(pos + 1);
171     return this;
172   }
173
174   public ByteBuffer put(int index, byte value)
175   {
176     checkIndex(index);
177
178     VMDirectByteBuffer.put(address, index, value);
179     return this;
180   }
181
182   public ByteBuffer put (byte[] src, int offset, int length)
183   {
184     checkArraySize (src.length, offset, length);
185     checkForUnderflow (length);
186
187     int index = position ();
188     VMDirectByteBuffer.put (address, index, src, offset, length);
189     position (index + length);
190
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 }