1 /* MappedByteBufferImpl.java --
2    Copyright (C) 2002, 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 import java.io.IOException;
44 
45 final class MappedByteBufferImpl extends MappedByteBuffer
46 {
47   private final boolean readOnly;
48 
49   /** Posix uses this for the pointer returned by mmap;
50    * Win32 uses it for the pointer returned by MapViewOfFile. */
51   public RawData implPtr;
52   /** Posix uses this for the actual length passed to mmap;
53    * Win32 uses it for the pointer returned by CreateFileMapping. */
54   public long implLen;
55 
MappedByteBufferImpl(RawData address, int size, boolean readOnly)56   public MappedByteBufferImpl(RawData address, int size, boolean readOnly)
57     throws IOException
58   {
59     super(size, size, 0, -1, address);
60     this.readOnly = readOnly;
61   }
62 
isReadOnly()63   public boolean isReadOnly()
64   {
65     return readOnly;
66   }
67 
get()68   public byte get()
69   {
70     checkForUnderflow();
71 
72     int pos = position();
73     byte result = VMDirectByteBuffer.get(address, pos);
74     position(pos + 1);
75     return result;
76   }
77 
put(byte value)78   public ByteBuffer put(byte value)
79   {
80     checkIfReadOnly();
81     checkForOverflow();
82 
83     int pos = position();
84     VMDirectByteBuffer.put(address, pos, value);
85     position(pos + 1);
86     return this;
87   }
88 
get(int index)89   public byte get(int index)
90   {
91     checkIndex(index);
92 
93     return VMDirectByteBuffer.get(address, index);
94   }
95 
get(byte[] dst, int offset, int length)96   public ByteBuffer get(byte[] dst, int offset, int length)
97   {
98     checkArraySize(dst.length, offset, length);
99     checkForUnderflow(length);
100 
101     int index = position();
102     VMDirectByteBuffer.get(address, index, dst, offset, length);
103     position(index+length);
104 
105     return this;
106   }
107 
put(int index, byte value)108   public ByteBuffer put(int index, byte value)
109   {
110     checkIfReadOnly();
111     checkIndex(index);
112 
113     VMDirectByteBuffer.put(address, index, value);
114     return this;
115   }
116 
compact()117   public ByteBuffer compact()
118   {
119     checkIfReadOnly();
120     mark = -1;
121     int pos = position();
122     if (pos > 0)
123       {
124 	int count = remaining();
125 	// Call shiftDown method optimized for direct buffers.
126 	VMDirectByteBuffer.shiftDown(address, 0, pos, count);
127 	position(count);
128 	limit(capacity());
129       }
130     else
131       {
132 	position(limit());
133 	limit(capacity());
134       }
135     return this;
136   }
137 
isDirect()138   public boolean isDirect()
139   {
140     return true;
141   }
142 
slice()143   public ByteBuffer slice()
144   {
145     int rem = remaining();
146     if (isReadOnly())
147         return new DirectByteBufferImpl.ReadOnly
148       (this, VMDirectByteBuffer.adjustAddress(address, position()),
149        rem, rem, 0);
150     else
151         return new DirectByteBufferImpl.ReadWrite
152       (this, VMDirectByteBuffer.adjustAddress(address, position()),
153        rem, rem, 0);
154   }
155 
duplicate(boolean readOnly)156   private ByteBuffer duplicate(boolean readOnly)
157   {
158     int pos = position();
159     reset();
160     int mark = position();
161     position(pos);
162     DirectByteBufferImpl result;
163     if (readOnly)
164         result = new DirectByteBufferImpl.ReadOnly(this, address, capacity(),
165                                                    limit(), pos);
166     else
167         result = new DirectByteBufferImpl.ReadWrite(this, address, capacity(),
168                                                     limit(), pos);
169 
170     if (mark != pos)
171       {
172 	result.position(mark);
173 	result.mark();
174 	result.position(pos);
175       }
176     return result;
177   }
178 
duplicate()179   public ByteBuffer duplicate()
180   {
181     return duplicate(isReadOnly());
182   }
183 
asReadOnlyBuffer()184   public ByteBuffer asReadOnlyBuffer()
185   {
186     return duplicate(true);
187   }
188 
asCharBuffer()189   public CharBuffer asCharBuffer()
190   {
191     return new CharViewBufferImpl(this, remaining() >> 1);
192   }
193 
asShortBuffer()194   public ShortBuffer asShortBuffer()
195   {
196     return new ShortViewBufferImpl(this, remaining() >> 1);
197   }
198 
asIntBuffer()199   public IntBuffer asIntBuffer()
200   {
201     return new IntViewBufferImpl(this, remaining() >> 2);
202   }
203 
asLongBuffer()204   public LongBuffer asLongBuffer()
205   {
206     return new LongViewBufferImpl(this, remaining() >> 3);
207   }
208 
asFloatBuffer()209   public FloatBuffer asFloatBuffer()
210   {
211     return new FloatViewBufferImpl(this, remaining() >> 2);
212   }
213 
asDoubleBuffer()214   public DoubleBuffer asDoubleBuffer()
215   {
216     return new DoubleViewBufferImpl(this, remaining() >> 3);
217   }
218 
getChar()219   public char getChar()
220   {
221     return ByteBufferHelper.getChar(this, order());
222   }
223 
putChar(char value)224   public ByteBuffer putChar(char value)
225   {
226     ByteBufferHelper.putChar(this, value, order());
227     return this;
228   }
229 
getChar(int index)230   public char getChar(int index)
231   {
232     return ByteBufferHelper.getChar(this, index, order());
233   }
234 
putChar(int index, char value)235   public ByteBuffer putChar(int index, char value)
236   {
237     ByteBufferHelper.putChar(this, index, value, order());
238     return this;
239   }
240 
getShort()241   public short getShort()
242   {
243     return ByteBufferHelper.getShort(this, order());
244   }
245 
putShort(short value)246   public ByteBuffer putShort(short value)
247   {
248     ByteBufferHelper.putShort(this, value, order());
249     return this;
250   }
251 
getShort(int index)252   public short getShort(int index)
253   {
254     return ByteBufferHelper.getShort(this, index, order());
255   }
256 
putShort(int index, short value)257   public ByteBuffer putShort(int index, short value)
258   {
259     ByteBufferHelper.putShort(this, index, value, order());
260     return this;
261   }
262 
getInt()263   public int getInt()
264   {
265     return ByteBufferHelper.getInt(this, order());
266   }
267 
putInt(int value)268   public ByteBuffer putInt(int value)
269   {
270     ByteBufferHelper.putInt(this, value, order());
271     return this;
272   }
273 
getInt(int index)274   public int getInt(int index)
275   {
276     return ByteBufferHelper.getInt(this, index, order());
277   }
278 
putInt(int index, int value)279   public ByteBuffer putInt(int index, int value)
280   {
281     ByteBufferHelper.putInt(this, index, value, order());
282     return this;
283   }
284 
getLong()285   public long getLong()
286   {
287     return ByteBufferHelper.getLong(this, order());
288   }
289 
putLong(long value)290   public ByteBuffer putLong(long value)
291   {
292     ByteBufferHelper.putLong(this, value, order());
293     return this;
294   }
295 
getLong(int index)296   public long getLong(int index)
297   {
298     return ByteBufferHelper.getLong(this, index, order());
299   }
300 
putLong(int index, long value)301   public ByteBuffer putLong(int index, long value)
302   {
303     ByteBufferHelper.putLong(this, index, value, order());
304     return this;
305   }
306 
getFloat()307   public float getFloat()
308   {
309     return ByteBufferHelper.getFloat(this, order());
310   }
311 
putFloat(float value)312   public ByteBuffer putFloat(float value)
313   {
314     ByteBufferHelper.putFloat(this, value, order());
315     return this;
316   }
317 
getFloat(int index)318   public float getFloat(int index)
319   {
320     return ByteBufferHelper.getFloat(this, index, order());
321   }
322 
putFloat(int index, float value)323   public ByteBuffer putFloat(int index, float value)
324   {
325     ByteBufferHelper.putFloat(this, index, value, order());
326     return this;
327   }
328 
getDouble()329   public double getDouble()
330   {
331     return ByteBufferHelper.getDouble(this, order());
332   }
333 
putDouble(double value)334   public ByteBuffer putDouble(double value)
335   {
336     ByteBufferHelper.putDouble(this, value, order());
337     return this;
338   }
339 
getDouble(int index)340   public double getDouble(int index)
341   {
342     return ByteBufferHelper.getDouble(this, index, order());
343   }
344 
putDouble(int index, double value)345   public ByteBuffer putDouble(int index, double value)
346   {
347     ByteBufferHelper.putDouble(this, index, value, order());
348     return this;
349   }
350 
351   // NOTE: In libgcj these methods are implemented in natFileChannelXxx.cc,
352   // because they're small, and to put them next to FileChannelImpl::mapImpl.
unmapImpl()353   native void unmapImpl();
isLoadedImpl()354   native boolean isLoadedImpl();
355     // FIXME: Try to load all pages into memory.
loadImpl()356   native void loadImpl();
357 
forceImpl()358   native void forceImpl();
359 }
360