Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / gnu / java / nio / channels / FileChannelImpl.java
blob6059b5692a58c08ac78efa3df93ed5bcc6e8dde1
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)
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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 gnu.java.nio.channels;
41 import gnu.classpath.Configuration;
42 import gnu.java.nio.FileLockImpl;
44 import java.io.File;
45 import java.io.FileNotFoundException;
46 import java.io.IOException;
47 import java.nio.ByteBuffer;
48 import java.nio.MappedByteBuffer;
49 import java.nio.channels.ClosedChannelException;
50 import java.nio.channels.FileChannel;
51 import java.nio.channels.FileLock;
52 import java.nio.channels.NonReadableChannelException;
53 import java.nio.channels.NonWritableChannelException;
54 import java.nio.channels.ReadableByteChannel;
55 import java.nio.channels.WritableByteChannel;
57 /**
58 * This file is not user visible !
59 * But alas, Java does not have a concept of friendly packages
60 * so this class is public.
61 * Instances of this class are created by invoking getChannel
62 * Upon a Input/Output/RandomAccessFile object.
64 public final class FileChannelImpl extends FileChannel
66 // These are mode values for open().
67 public static final int READ = 1;
68 public static final int WRITE = 2;
69 public static final int APPEND = 4;
71 // EXCL is used only when making a temp file.
72 public static final int EXCL = 8;
73 public static final int SYNC = 16;
74 public static final int DSYNC = 32;
76 private static native void init();
78 static
80 if (Configuration.INIT_LOAD_LIBRARY)
82 System.loadLibrary("javanio");
85 init();
88 /**
89 * This is the actual native file descriptor value
91 // System's notion of file descriptor. It might seem redundant to
92 // initialize this given that it is reassigned in the constructors.
93 // However, this is necessary because if open() throws an exception
94 // we want to make sure this has the value -1. This is the most
95 // efficient way to accomplish that.
96 private int fd = -1;
98 private long pos;
99 private int mode;
101 public FileChannelImpl ()
105 /* Open a file. MODE is a combination of the above mode flags. */
106 public FileChannelImpl (File file, int mode) throws FileNotFoundException
108 final String path = file.getPath();
109 fd = open (path, mode);
110 this.mode = mode;
112 // First open the file and then check if it is a a directory
113 // to avoid race condition.
114 if (file.isDirectory())
116 try
118 close();
120 catch (IOException e)
122 /* ignore it */
125 throw new FileNotFoundException(path + " is a directory");
129 /* Used by init() (native code) */
130 FileChannelImpl (int fd, int mode)
132 this.fd = fd;
133 this.mode = mode;
136 public static FileChannelImpl in;
137 public static FileChannelImpl out;
138 public static FileChannelImpl err;
140 private native int open (String path, int mode) throws FileNotFoundException;
142 public native int available () throws IOException;
143 private native long implPosition () throws IOException;
144 private native void seek (long newPosition) throws IOException;
145 private native void implTruncate (long size) throws IOException;
147 public native void unlock (long pos, long len) throws IOException;
149 public native long size () throws IOException;
151 protected native void implCloseChannel() throws IOException;
154 * Makes sure the Channel is properly closed.
156 protected void finalize() throws IOException
158 this.close();
161 public int read (ByteBuffer dst) throws IOException
163 int result;
164 byte[] buffer = new byte [dst.remaining ()];
166 result = read (buffer, 0, buffer.length);
168 if (result > 0)
169 dst.put (buffer, 0, result);
171 return result;
174 public int read (ByteBuffer dst, long position)
175 throws IOException
177 if (position < 0)
178 throw new IllegalArgumentException ();
179 long oldPosition = implPosition ();
180 position (position);
181 int result = read(dst);
182 position (oldPosition);
184 return result;
187 public native int read ()
188 throws IOException;
190 public native int read (byte[] buffer, int offset, int length)
191 throws IOException;
193 public long read (ByteBuffer[] dsts, int offset, int length)
194 throws IOException
196 long result = 0;
198 for (int i = offset; i < offset + length; i++)
200 result += read (dsts [i]);
203 return result;
206 public int write (ByteBuffer src) throws IOException
208 int len = src.remaining ();
209 if (src.hasArray())
211 byte[] buffer = src.array();
212 write(buffer, src.arrayOffset() + src.position(), len);
213 src.position(src.position() + len);
215 else
217 // Use a more efficient native method! FIXME!
218 byte[] buffer = new byte [len];
219 src.get (buffer, 0, len);
220 write (buffer, 0, len);
222 return len;
225 public int write (ByteBuffer src, long position)
226 throws IOException
228 if (position < 0)
229 throw new IllegalArgumentException ();
231 if (!isOpen ())
232 throw new ClosedChannelException ();
234 if ((mode & WRITE) == 0)
235 throw new NonWritableChannelException ();
237 int result;
238 long oldPosition;
240 oldPosition = implPosition ();
241 seek (position);
242 result = write(src);
243 seek (oldPosition);
245 return result;
248 public native void write (byte[] buffer, int offset, int length)
249 throws IOException;
251 public native void write (int b) throws IOException;
253 public long write(ByteBuffer[] srcs, int offset, int length)
254 throws IOException
256 long result = 0;
258 for (int i = offset;i < offset + length;i++)
260 result += write (srcs[i]);
263 return result;
266 public native MappedByteBuffer mapImpl (char mode, long position, int size)
267 throws IOException;
269 public MappedByteBuffer map (FileChannel.MapMode mode,
270 long position, long size)
271 throws IOException
273 char nmode = 0;
274 if (mode == MapMode.READ_ONLY)
276 nmode = 'r';
277 if ((this.mode & READ) == 0)
278 throw new NonReadableChannelException();
280 else if (mode == MapMode.READ_WRITE || mode == MapMode.PRIVATE)
282 nmode = mode == MapMode.READ_WRITE ? '+' : 'c';
283 if ((this.mode & (READ|WRITE)) != (READ|WRITE))
284 throw new NonWritableChannelException();
286 else
287 throw new IllegalArgumentException ();
289 if (position < 0 || size < 0 || size > Integer.MAX_VALUE)
290 throw new IllegalArgumentException ();
291 return mapImpl(nmode, position, (int) size);
295 * msync with the disk
297 public void force (boolean metaData) throws IOException
299 if (!isOpen ())
300 throw new ClosedChannelException ();
303 // like transferTo, but with a count of less than 2Gbytes
304 private int smallTransferTo (long position, int count,
305 WritableByteChannel target)
306 throws IOException
308 ByteBuffer buffer;
311 // Try to use a mapped buffer if we can. If this fails for
312 // any reason we'll fall back to using a ByteBuffer.
313 buffer = map (MapMode.READ_ONLY, position, count);
315 catch (IOException e)
317 buffer = ByteBuffer.allocate (count);
318 read (buffer, position);
319 buffer.flip();
322 return target.write (buffer);
325 public long transferTo (long position, long count,
326 WritableByteChannel target)
327 throws IOException
329 if (position < 0
330 || count < 0)
331 throw new IllegalArgumentException ();
333 if (!isOpen ())
334 throw new ClosedChannelException ();
336 if ((mode & READ) == 0)
337 throw new NonReadableChannelException ();
339 final int pageSize = 65536;
340 long total = 0;
342 while (count > 0)
344 int transferred
345 = smallTransferTo (position, (int)Math.min (count, pageSize),
346 target);
347 if (transferred < 0)
348 break;
349 total += transferred;
350 position += transferred;
351 count -= transferred;
354 return total;
357 // like transferFrom, but with a count of less than 2Gbytes
358 private int smallTransferFrom (ReadableByteChannel src, long position,
359 int count)
360 throws IOException
362 ByteBuffer buffer = null;
364 if (src instanceof FileChannel)
368 // Try to use a mapped buffer if we can. If this fails
369 // for any reason we'll fall back to using a ByteBuffer.
370 buffer = ((FileChannel)src).map (MapMode.READ_ONLY, position,
371 count);
373 catch (IOException e)
378 if (buffer == null)
380 buffer = ByteBuffer.allocate ((int) count);
381 src.read (buffer);
382 buffer.flip();
385 return write (buffer, position);
388 public long transferFrom (ReadableByteChannel src, long position,
389 long count)
390 throws IOException
392 if (position < 0
393 || count < 0)
394 throw new IllegalArgumentException ();
396 if (!isOpen ())
397 throw new ClosedChannelException ();
399 if ((mode & WRITE) == 0)
400 throw new NonWritableChannelException ();
402 final int pageSize = 65536;
403 long total = 0;
405 while (count > 0)
407 int transferred = smallTransferFrom (src, position,
408 (int)Math.min (count, pageSize));
409 if (transferred < 0)
410 break;
411 total += transferred;
412 position += transferred;
413 count -= transferred;
416 return total;
419 public FileLock tryLock (long position, long size, boolean shared)
420 throws IOException
422 if (position < 0
423 || size < 0)
424 throw new IllegalArgumentException ();
426 if (!isOpen ())
427 throw new ClosedChannelException ();
429 if (shared && (mode & READ) == 0)
430 throw new NonReadableChannelException ();
432 if (!shared && (mode & WRITE) == 0)
433 throw new NonWritableChannelException ();
435 boolean completed = false;
439 begin();
440 boolean lockable = lock(position, size, shared, false);
441 completed = true;
442 return (lockable
443 ? new FileLockImpl(this, position, size, shared)
444 : null);
446 finally
448 end(completed);
452 /** Try to acquire a lock at the given position and size.
453 * On success return true.
454 * If wait as specified, block until we can get it.
455 * Otherwise return false.
457 private native boolean lock(long position, long size,
458 boolean shared, boolean wait) throws IOException;
460 public FileLock lock (long position, long size, boolean shared)
461 throws IOException
463 if (position < 0
464 || size < 0)
465 throw new IllegalArgumentException ();
467 if (!isOpen ())
468 throw new ClosedChannelException ();
470 boolean completed = false;
474 boolean lockable = lock(position, size, shared, true);
475 completed = true;
476 return (lockable
477 ? new FileLockImpl(this, position, size, shared)
478 : null);
480 finally
482 end(completed);
486 public long position ()
487 throws IOException
489 if (!isOpen ())
490 throw new ClosedChannelException ();
492 return implPosition ();
495 public FileChannel position (long newPosition)
496 throws IOException
498 if (newPosition < 0)
499 throw new IllegalArgumentException ();
501 if (!isOpen ())
502 throw new ClosedChannelException ();
504 // FIXME note semantics if seeking beyond eof.
505 // We should seek lazily - only on a write.
506 seek (newPosition);
507 return this;
510 public FileChannel truncate (long size)
511 throws IOException
513 if (size < 0)
514 throw new IllegalArgumentException ();
516 if (!isOpen ())
517 throw new ClosedChannelException ();
519 if ((mode & WRITE) == 0)
520 throw new NonWritableChannelException ();
522 if (size < size ())
523 implTruncate (size);
525 return this;