2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / nio / channels / FileChannelImpl.java
blob89ac11ad514b38b7ba1ba64571d9fff242fd6b7b
1 /* FileChannelImpl.java --
2 Copyright (C) 2002 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
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.
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. */
39 package java.nio.channels;
41 import java.io.EOFException;
42 import java.io.FileDescriptor;
43 import java.io.FileInputStream;
44 import java.io.FileOutputStream;
45 import java.io.IOException;
46 import java.io.RandomAccessFile;
47 import java.nio.ByteBuffer;
48 import java.nio.MappedByteBuffer;
49 import java.nio.MappedByteBufferImpl;
50 import gnu.classpath.Configuration;
51 import gnu.gcj.RawData;
53 /**
54 * This file is not user visible !
55 * But alas, Java does not have a concept of friendly packages
56 * so this class is public.
57 * Instances of this class are created by invoking getChannel
58 * Upon a Input/Output/RandomAccessFile object.
61 public class FileChannelImpl extends FileChannel
63 static
65 // load the shared library needed for native methods.
66 if (Configuration.INIT_LOAD_LIBRARY)
68 System.loadLibrary ("javanio");
72 public RawData map_address;
74 int length;
75 FileDescriptor fd;
76 MappedByteBuffer buf;
77 Object file_obj; // just to keep it live...
79 public FileChannelImpl (FileDescriptor fd, boolean write, Object obj)
81 if (!(obj instanceof RandomAccessFile)
82 && !(obj instanceof FileInputStream)
83 && !(obj instanceof FileOutputStream))
84 throw new InternalError ();
86 this.fd = fd;
87 this.file_obj = obj;
90 public FileChannelImpl ()
92 this (new FileDescriptor (), true, null);
95 private native long implPosition ();
96 private native FileChannel implPosition (long newPosition);
97 private native FileChannel implTruncate (long size);
99 private native RawData nio_mmap_file (long pos, long size, int mode);
100 private native void nio_unmmap_file (RawData map_address, int size);
101 private native void nio_msync (RawData map_address, int length);
103 public native long size () throws IOException;
105 protected void implCloseChannel() throws IOException
107 if (map_address != null)
109 nio_unmmap_file (map_address, (int) length);
110 map_address = null;
113 if (file_obj instanceof RandomAccessFile)
115 RandomAccessFile o = (RandomAccessFile) file_obj;
116 o.close();
118 else if (file_obj instanceof FileInputStream)
120 FileInputStream o = (FileInputStream) file_obj;
121 o.close();
123 else if (file_obj instanceof FileOutputStream)
125 FileOutputStream o = (FileOutputStream) file_obj;
126 o.close();
130 public int read (ByteBuffer dst) throws IOException
132 // Check if file is mapped into memory.
133 if (buf != null)
135 // FIXME: implement this
136 throw new Error ("Accessing mapped buffers not implemented.");
139 // File not mapped, access it directly.
140 return implRead (dst);
143 public int read (ByteBuffer dst, long position)
144 throws IOException
146 if (position < 0)
147 throw new IllegalArgumentException ();
149 if (!isOpen ())
150 throw new ClosedChannelException ();
152 if (file_obj instanceof FileOutputStream)
153 throw new NonReadableChannelException ();
155 int result;
156 long oldPosition;
158 oldPosition = implPosition ();
159 position (position);
160 result = implRead (dst);
161 implPosition (oldPosition);
163 return result;
166 private int implRead (ByteBuffer dst) throws IOException
168 int result;
169 byte[] buffer = new byte [dst.remaining ()];
171 result = implRead (buffer, 0, buffer.length);
173 if (result > 0)
174 dst.put (buffer, 0, result);
176 return result;
179 private native int implRead (byte[] buffer, int offset, int length)
180 throws IOException;
182 public long read (ByteBuffer[] dsts, int offset, int length)
183 throws IOException
185 long result = 0;
187 for (int i = offset; i < offset + length; i++)
189 result += read (dsts [i]);
192 return result;
195 public int write (ByteBuffer src) throws IOException
197 // Check if file is mapped into memory.
198 if (buf != null)
200 // FIXME: implement this
201 throw new Error ("Accessing mapped buffers not implemented.");
204 // File not mapped, access it directly.
205 return implWrite (src);
208 public int write (ByteBuffer src, long position)
209 throws IOException
211 if (position < 0)
212 throw new IllegalArgumentException ();
214 if (!isOpen ())
215 throw new ClosedChannelException ();
217 if (file_obj instanceof FileInputStream)
218 throw new NonWritableChannelException ();
220 int result;
221 long oldPosition;
223 oldPosition = implPosition ();
224 position (position);
225 result = implWrite (src);
226 implPosition (oldPosition);
228 return result;
231 private int implWrite (ByteBuffer src) throws IOException
233 byte[] buffer = new byte [src.remaining ()];
235 src.get (buffer, 0, buffer.length);
236 return implWrite (buffer, 0, buffer.length);
239 private native int implWrite (byte[] buffer, int offset, int length)
240 throws IOException;
242 public long write(ByteBuffer[] srcs, int offset, int length)
243 throws IOException
245 long result = 0;
247 for (int i = offset;i < offset + length;i++)
249 result += write (srcs[i]);
252 return result;
255 public MappedByteBuffer map (FileChannel.MapMode mode, long position,
256 long size)
257 throws IOException
259 if ((mode != MapMode.READ_ONLY
260 && mode != MapMode.READ_WRITE
261 && mode != MapMode.PRIVATE)
262 || position < 0
263 || size < 0
264 || size > Integer.MAX_VALUE)
265 throw new IllegalArgumentException ();
267 // FIXME: Make this working.
268 int cmode = mode.m;
269 map_address = nio_mmap_file (position, size, cmode);
270 length = (int) size;
271 buf = new MappedByteBufferImpl (this);
272 return buf;
275 static MappedByteBuffer create_direct_mapped_buffer (RawData map_address,
276 long length)
277 throws IOException
279 FileChannelImpl ch = new FileChannelImpl ();
280 ch.map_address = map_address;
281 ch.length = (int) length;
282 ch.buf = new MappedByteBufferImpl (ch);
283 return ch.buf;
287 * msync with the disk
289 public void force (boolean metaData) throws IOException
291 if (!isOpen ())
292 throw new ClosedChannelException ();
294 // FIXME: What to do with metaData ?
296 nio_msync (map_address, length);
299 public long transferTo (long position, long count, WritableByteChannel target)
300 throws IOException
302 if (position < 0
303 || count < 0)
304 throw new IllegalArgumentException ();
306 if (!isOpen ())
307 throw new ClosedChannelException ();
309 if (file_obj instanceof FileOutputStream)
310 throw new NonReadableChannelException ();
312 // XXX: count needs to be casted from long to int. Dataloss ?
313 ByteBuffer buffer = ByteBuffer.allocate ((int) count);
314 read (buffer, position);
315 buffer.flip();
316 return target.write (buffer);
319 public long transferFrom (ReadableByteChannel src, long position, long count)
320 throws IOException
322 if (position < 0
323 || count < 0)
324 throw new IllegalArgumentException ();
326 if (!isOpen ())
327 throw new ClosedChannelException ();
329 if (file_obj instanceof FileInputStream)
330 throw new NonWritableChannelException ();
332 // XXX: count needs to be casted from long to int. Dataloss ?
333 ByteBuffer buffer = ByteBuffer.allocate ((int) count);
334 src.read (buffer);
335 buffer.flip();
336 return write (buffer, position);
339 public FileLock lock (long position, long size, boolean shared)
340 throws IOException
342 if (position < 0
343 || size < 0)
344 throw new IllegalArgumentException ();
346 if (!isOpen ())
347 throw new ClosedChannelException ();
349 if (shared &&
350 file_obj instanceof FileOutputStream)
351 throw new NonReadableChannelException ();
353 if (!shared &&
354 file_obj instanceof FileInputStream)
355 throw new NonWritableChannelException ();
357 throw new Error ("Not implemented");
360 public FileLock tryLock (long position, long size, boolean shared)
361 throws IOException
363 if (position < 0
364 || size < 0)
365 throw new IllegalArgumentException ();
367 if (!isOpen ())
368 throw new ClosedChannelException ();
370 throw new Error ("Not implemented");
373 public long position ()
374 throws IOException
376 if (!isOpen ())
377 throw new ClosedChannelException ();
379 return implPosition ();
382 public FileChannel position (long newPosition)
383 throws IOException
385 if (newPosition < 0)
386 throw new IllegalArgumentException ();
388 if (!isOpen ())
389 throw new ClosedChannelException ();
391 return implPosition (newPosition);
394 public FileChannel truncate (long size)
395 throws IOException
397 if (size < 0)
398 throw new IllegalArgumentException ();
400 if (!isOpen ())
401 throw new ClosedChannelException ();
403 if (file_obj instanceof FileInputStream)
404 throw new NonWritableChannelException ();
406 return implTruncate (size);