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)
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
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
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
;
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
65 // load the shared library needed for native methods.
66 if (Configuration
.INIT_LOAD_LIBRARY
)
68 System
.loadLibrary ("javanio");
72 public RawData map_address
;
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 ();
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
);
113 if (file_obj
instanceof RandomAccessFile
)
115 RandomAccessFile o
= (RandomAccessFile
) file_obj
;
118 else if (file_obj
instanceof FileInputStream
)
120 FileInputStream o
= (FileInputStream
) file_obj
;
123 else if (file_obj
instanceof FileOutputStream
)
125 FileOutputStream o
= (FileOutputStream
) file_obj
;
130 public int read (ByteBuffer dst
) throws IOException
132 // Check if file is mapped into memory.
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
)
147 throw new IllegalArgumentException ();
150 throw new ClosedChannelException ();
152 if (file_obj
instanceof FileOutputStream
)
153 throw new NonReadableChannelException ();
158 oldPosition
= implPosition ();
160 result
= implRead (dst
);
161 implPosition (oldPosition
);
166 private int implRead (ByteBuffer dst
) throws IOException
169 byte[] buffer
= new byte [dst
.remaining ()];
171 result
= implRead (buffer
, 0, buffer
.length
);
174 dst
.put (buffer
, 0, result
);
179 private native int implRead (byte[] buffer
, int offset
, int length
)
182 public long read (ByteBuffer
[] dsts
, int offset
, int length
)
187 for (int i
= offset
; i
< offset
+ length
; i
++)
189 result
+= read (dsts
[i
]);
195 public int write (ByteBuffer src
) throws IOException
197 // Check if file is mapped into memory.
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
)
212 throw new IllegalArgumentException ();
215 throw new ClosedChannelException ();
217 if (file_obj
instanceof FileInputStream
)
218 throw new NonWritableChannelException ();
223 oldPosition
= implPosition ();
225 result
= implWrite (src
);
226 implPosition (oldPosition
);
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
)
242 public long write(ByteBuffer
[] srcs
, int offset
, int length
)
247 for (int i
= offset
;i
< offset
+ length
;i
++)
249 result
+= write (srcs
[i
]);
255 public MappedByteBuffer
map (FileChannel
.MapMode mode
, long position
,
259 if ((mode
!= MapMode
.READ_ONLY
260 && mode
!= MapMode
.READ_WRITE
261 && mode
!= MapMode
.PRIVATE
)
264 || size
> Integer
.MAX_VALUE
)
265 throw new IllegalArgumentException ();
267 // FIXME: Make this working.
269 map_address
= nio_mmap_file (position
, size
, cmode
);
271 buf
= new MappedByteBufferImpl (this);
275 static MappedByteBuffer
create_direct_mapped_buffer (RawData map_address
,
279 FileChannelImpl ch
= new FileChannelImpl ();
280 ch
.map_address
= map_address
;
281 ch
.length
= (int) length
;
282 ch
.buf
= new MappedByteBufferImpl (ch
);
287 * msync with the disk
289 public void force (boolean metaData
) throws IOException
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
)
304 throw new IllegalArgumentException ();
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
);
316 return target
.write (buffer
);
319 public long transferFrom (ReadableByteChannel src
, long position
, long count
)
324 throw new IllegalArgumentException ();
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
);
336 return write (buffer
, position
);
339 public FileLock
lock (long position
, long size
, boolean shared
)
344 throw new IllegalArgumentException ();
347 throw new ClosedChannelException ();
350 file_obj
instanceof FileOutputStream
)
351 throw new NonReadableChannelException ();
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
)
365 throw new IllegalArgumentException ();
368 throw new ClosedChannelException ();
370 throw new Error ("Not implemented");
373 public long position ()
377 throw new ClosedChannelException ();
379 return implPosition ();
382 public FileChannel
position (long newPosition
)
386 throw new IllegalArgumentException ();
389 throw new ClosedChannelException ();
391 return implPosition (newPosition
);
394 public FileChannel
truncate (long size
)
398 throw new IllegalArgumentException ();
401 throw new ClosedChannelException ();
403 if (file_obj
instanceof FileInputStream
)
404 throw new NonWritableChannelException ();
406 return implTruncate (size
);