OSDN Git Service

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