1 /* FileChannelImpl.java --
2 Copyright (C) 2002, 2004, 2005 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 gnu
.java
.nio
.channels
;
41 import gnu
.classpath
.Configuration
;
42 import gnu
.java
.nio
.FileLockImpl
;
44 import java
.io
.FileNotFoundException
;
45 import java
.io
.IOException
;
46 import java
.nio
.ByteBuffer
;
47 import java
.nio
.MappedByteBuffer
;
48 import java
.nio
.channels
.ClosedChannelException
;
49 import java
.nio
.channels
.FileChannel
;
50 import java
.nio
.channels
.FileLock
;
51 import java
.nio
.channels
.NonReadableChannelException
;
52 import java
.nio
.channels
.NonWritableChannelException
;
53 import java
.nio
.channels
.ReadableByteChannel
;
54 import java
.nio
.channels
.WritableByteChannel
;
57 * This file is not user visible !
58 * But alas, Java does not have a concept of friendly packages
59 * so this class is public.
60 * Instances of this class are created by invoking getChannel
61 * Upon a Input/Output/RandomAccessFile object.
63 public final class FileChannelImpl
extends FileChannel
65 // These are mode values for open().
66 public static final int READ
= 1;
67 public static final int WRITE
= 2;
68 public static final int APPEND
= 4;
70 // EXCL is used only when making a temp file.
71 public static final int EXCL
= 8;
72 public static final int SYNC
= 16;
73 public static final int DSYNC
= 32;
75 private static native void init();
79 if (Configuration
.INIT_LOAD_LIBRARY
)
81 System
.loadLibrary("javanio");
88 * This is the actual native file descriptor value
90 // System's notion of file descriptor. It might seem redundant to
91 // initialize this given that it is reassigned in the constructors.
92 // However, this is necessary because if open() throws an exception
93 // we want to make sure this has the value -1. This is the most
94 // efficient way to accomplish that.
100 public FileChannelImpl ()
104 /* Open a file. MODE is a combination of the above mode flags. */
105 public FileChannelImpl (String path
, int mode
) throws FileNotFoundException
107 fd
= open (path
, mode
);
111 /* Used by init() (native code) */
112 FileChannelImpl (int fd
, int mode
)
118 public static FileChannelImpl in
;
119 public static FileChannelImpl out
;
120 public static FileChannelImpl err
;
122 private native int open (String path
, int mode
) throws FileNotFoundException
;
124 public native int available () throws IOException
;
125 private native long implPosition () throws IOException
;
126 private native void seek (long newPosition
) throws IOException
;
127 private native void implTruncate (long size
) throws IOException
;
129 public native void unlock (long pos
, long len
) throws IOException
;
131 public native long size () throws IOException
;
133 protected native void implCloseChannel() throws IOException
;
136 * Makes sure the Channel is properly closed.
138 protected void finalize() throws IOException
143 public int read (ByteBuffer dst
) throws IOException
146 byte[] buffer
= new byte [dst
.remaining ()];
148 result
= read (buffer
, 0, buffer
.length
);
151 dst
.put (buffer
, 0, result
);
156 public int read (ByteBuffer dst
, long position
)
160 throw new IllegalArgumentException ();
161 long oldPosition
= implPosition ();
163 int result
= read(dst
);
164 position (oldPosition
);
169 public native int read ()
172 public native int read (byte[] buffer
, int offset
, int length
)
175 public long read (ByteBuffer
[] dsts
, int offset
, int length
)
180 for (int i
= offset
; i
< offset
+ length
; i
++)
182 result
+= read (dsts
[i
]);
188 public int write (ByteBuffer src
) throws IOException
190 int len
= src
.remaining ();
193 byte[] buffer
= src
.array();
194 write(buffer
, src
.arrayOffset() + src
.position(), len
);
195 src
.position(src
.position() + len
);
199 // Use a more efficient native method! FIXME!
200 byte[] buffer
= new byte [len
];
201 src
.get (buffer
, 0, len
);
202 write (buffer
, 0, len
);
207 public int write (ByteBuffer src
, long position
)
211 throw new IllegalArgumentException ();
214 throw new ClosedChannelException ();
216 if ((mode
& WRITE
) == 0)
217 throw new NonWritableChannelException ();
222 oldPosition
= implPosition ();
230 public native void write (byte[] buffer
, int offset
, int length
)
233 public native void write (int b
) throws IOException
;
235 public long write(ByteBuffer
[] srcs
, int offset
, int length
)
240 for (int i
= offset
;i
< offset
+ length
;i
++)
242 result
+= write (srcs
[i
]);
248 public native MappedByteBuffer
mapImpl (char mode
, long position
, int size
)
251 public MappedByteBuffer
map (FileChannel
.MapMode mode
,
252 long position
, long size
)
256 if (mode
== MapMode
.READ_ONLY
)
259 if ((this.mode
& READ
) == 0)
260 throw new NonReadableChannelException();
262 else if (mode
== MapMode
.READ_WRITE
|| mode
== MapMode
.PRIVATE
)
264 nmode
= mode
== MapMode
.READ_WRITE ?
'+' : 'c';
265 if ((this.mode
& (READ
|WRITE
)) != (READ
|WRITE
))
266 throw new NonWritableChannelException();
269 throw new IllegalArgumentException ();
271 if (position
< 0 || size
< 0 || size
> Integer
.MAX_VALUE
)
272 throw new IllegalArgumentException ();
273 return mapImpl(nmode
, position
, (int) size
);
277 * msync with the disk
279 public void force (boolean metaData
) throws IOException
282 throw new ClosedChannelException ();
285 public long transferTo (long position
, long count
, WritableByteChannel target
)
290 throw new IllegalArgumentException ();
293 throw new ClosedChannelException ();
295 if ((mode
& READ
) == 0)
296 throw new NonReadableChannelException ();
298 // XXX: count needs to be casted from long to int. Dataloss ?
299 ByteBuffer buffer
= ByteBuffer
.allocate ((int) count
);
300 read (buffer
, position
);
302 return target
.write (buffer
);
305 public long transferFrom (ReadableByteChannel src
, long position
, long count
)
310 throw new IllegalArgumentException ();
313 throw new ClosedChannelException ();
315 if ((mode
& WRITE
) == 0)
316 throw new NonWritableChannelException ();
318 // XXX: count needs to be casted from long to int. Dataloss ?
319 ByteBuffer buffer
= ByteBuffer
.allocate ((int) count
);
322 return write (buffer
, position
);
325 public FileLock
tryLock (long position
, long size
, boolean shared
)
330 throw new IllegalArgumentException ();
333 throw new ClosedChannelException ();
335 if (shared
&& (mode
& READ
) == 0)
336 throw new NonReadableChannelException ();
338 if (!shared
&& (mode
& WRITE
) == 0)
339 throw new NonWritableChannelException ();
341 boolean completed
= false;
346 lock(position
, size
, shared
, true);
348 return new FileLockImpl(this, position
, size
, shared
);
356 /** Try to acquire a lock at the given position and size.
357 * On success return true.
358 * If wait as specified, block until we can get it.
359 * Otherwise return false.
361 private native boolean lock(long position
, long size
,
362 boolean shared
, boolean wait
) throws IOException
;
364 public FileLock
lock (long position
, long size
, boolean shared
)
369 throw new IllegalArgumentException ();
372 throw new ClosedChannelException ();
374 boolean completed
= false;
378 boolean lockable
= lock(position
, size
, shared
, false);
381 ?
new FileLockImpl(this, position
, size
, shared
)
390 public long position ()
394 throw new ClosedChannelException ();
396 return implPosition ();
399 public FileChannel
position (long newPosition
)
403 throw new IllegalArgumentException ();
406 throw new ClosedChannelException ();
408 // FIXME note semantics if seeking beyond eof.
409 // We should seek lazily - only on a write.
414 public FileChannel
truncate (long size
)
418 throw new IllegalArgumentException ();
421 throw new ClosedChannelException ();
423 if ((mode
& WRITE
) == 0)
424 throw new NonWritableChannelException ();