summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-10 15:29:15 +0000
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-10 15:29:15 +0000
commitc7170b512880b20295e4465b47396f204ffc5e4c (patch)
tree646cdab02ba1d8f9d139076c9d00ebdb47e1d4a4
parente2704f585052faa726100494c24d27eb87b07d72 (diff)
downloadgcc-c7170b512880b20295e4465b47396f204ffc5e4c.tar.gz
2005-03-09 Andrew Haley <aph@redhat.com>
* gnu/java/nio/channels/FileChannelImpl.java (smallTransferFrom): New. (smallTransferTo): New. (transferFrom): Loop around smallTransferFrom, copying pageSize bytes each time. (transferTo): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96240 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libjava/ChangeLog9
-rw-r--r--libjava/gnu/java/nio/channels/FileChannelImpl.java100
2 files changed, 97 insertions, 12 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index e55087ceddb..f62317fe454 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,12 @@
+2005-03-09 Andrew Haley <aph@redhat.com>
+
+ * gnu/java/nio/channels/FileChannelImpl.java (smallTransferFrom):
+ New.
+ (smallTransferTo): New.
+ (transferFrom): Loop around smallTransferFrom, copying pageSize
+ bytes each time.
+ (transferTo): Likewise.
+
2005-03-09 David Daney <ddaney@avtrex.com>
PR libgcj/20389
diff --git a/libjava/gnu/java/nio/channels/FileChannelImpl.java b/libjava/gnu/java/nio/channels/FileChannelImpl.java
index 887d1dcc396..e5b02e9fdb3 100644
--- a/libjava/gnu/java/nio/channels/FileChannelImpl.java
+++ b/libjava/gnu/java/nio/channels/FileChannelImpl.java
@@ -282,7 +282,30 @@ public final class FileChannelImpl extends FileChannel
throw new ClosedChannelException ();
}
- public long transferTo (long position, long count, WritableByteChannel target)
+ // like transferTo, but with a count of less than 2Gbytes
+ private int smallTransferTo (long position, int count,
+ WritableByteChannel target)
+ throws IOException
+ {
+ ByteBuffer buffer;
+ try
+ {
+ // Try to use a mapped buffer if we can. If this fails for
+ // any reason we'll fall back to using a ByteBuffer.
+ buffer = map (MapMode.READ_ONLY, position, count);
+ }
+ catch (IOException e)
+ {
+ buffer = ByteBuffer.allocate (count);
+ read (buffer, position);
+ buffer.flip();
+ }
+
+ return target.write (buffer);
+ }
+
+ public long transferTo (long position, long count,
+ WritableByteChannel target)
throws IOException
{
if (position < 0
@@ -295,14 +318,57 @@ public final class FileChannelImpl extends FileChannel
if ((mode & READ) == 0)
throw new NonReadableChannelException ();
- // XXX: count needs to be casted from long to int. Dataloss ?
- ByteBuffer buffer = ByteBuffer.allocate ((int) count);
- read (buffer, position);
- buffer.flip();
- return target.write (buffer);
+ final int pageSize = 65536;
+ long total = 0;
+
+ while (count > 0)
+ {
+ int transferred
+ = smallTransferTo (position, (int)Math.min (count, pageSize),
+ target);
+ if (transferred < 0)
+ break;
+ total += transferred;
+ position += transferred;
+ count -= transferred;
+ }
+
+ return total;
}
- public long transferFrom (ReadableByteChannel src, long position, long count)
+ // like transferFrom, but with a count of less than 2Gbytes
+ private int smallTransferFrom (ReadableByteChannel src, long position,
+ int count)
+ throws IOException
+ {
+ ByteBuffer buffer = null;
+
+ if (src instanceof FileChannel)
+ {
+ try
+ {
+ // Try to use a mapped buffer if we can. If this fails
+ // for any reason we'll fall back to using a ByteBuffer.
+ buffer = ((FileChannel)src).map (MapMode.READ_ONLY, position,
+ count);
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ if (buffer == null)
+ {
+ buffer = ByteBuffer.allocate ((int) count);
+ src.read (buffer);
+ buffer.flip();
+ }
+
+ return write (buffer, position);
+ }
+
+ public long transferFrom (ReadableByteChannel src, long position,
+ long count)
throws IOException
{
if (position < 0
@@ -315,11 +381,21 @@ public final class FileChannelImpl extends FileChannel
if ((mode & WRITE) == 0)
throw new NonWritableChannelException ();
- // XXX: count needs to be casted from long to int. Dataloss ?
- ByteBuffer buffer = ByteBuffer.allocate ((int) count);
- src.read (buffer);
- buffer.flip();
- return write (buffer, position);
+ final int pageSize = 65536;
+ long total = 0;
+
+ while (count > 0)
+ {
+ int transferred = smallTransferFrom (src, position,
+ (int)Math.min (count, pageSize));
+ if (transferred < 0)
+ break;
+ total += transferred;
+ position += transferred;
+ count -= transferred;
+ }
+
+ return total;
}
public FileLock tryLock (long position, long size, boolean shared)