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