/* * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package sun.nio.ch; import java.io.FileDescriptor; import java.io.IOException; import java.nio.ByteBuffer; /** * File-descriptor based I/O utilities that are shared by NIO classes. */ class IOUtil { private IOUtil() { } // No instantiation /* * Returns the index of first buffer in bufs with remaining, * or -1 if there is nothing left */ private static int remaining(ByteBuffer[] bufs) { int numBufs = bufs.length; for (int i=0; i 0) { // now update src src.position(pos + n); } return n; } finally { Util.releaseTemporaryDirectBuffer(bb); } } private static int writeFromNativeBuffer(FileDescriptor fd, ByteBuffer bb, long position, NativeDispatcher nd, Object lock) throws IOException { int pos = bb.position(); int lim = bb.limit(); assert (pos <= lim); int rem = (pos <= lim ? lim - pos : 0); int written = 0; if (rem == 0) return 0; if (position != -1) { written = nd.pwrite(fd, ((DirectBuffer)bb).address() + pos, rem, position, lock); } else { written = nd.write(fd, ((DirectBuffer)bb).address() + pos, rem); } if (written > 0) bb.position(pos + written); return written; } static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd) throws IOException { int nextWithRemaining = remaining(bufs); // if all bufs are empty we should return immediately if (nextWithRemaining < 0) return 0; // If some bufs are empty we should skip them if (nextWithRemaining > 0) bufs = skipBufs(bufs, nextWithRemaining); int numBufs = bufs.length; // Create shadow to ensure DirectByteBuffers are used ByteBuffer[] shadow = new ByteBuffer[numBufs]; try { for (int i=0; i= len) { bytesWritten -= len; int newPosition = pos + len; nextBuffer.position(newPosition); } else { // Buffers not completely filled if (bytesWritten > 0) { assert(pos + bytesWritten < (long)Integer.MAX_VALUE); int newPosition = (int)(pos + bytesWritten); nextBuffer.position(newPosition); } break; } } return returnVal; } finally { // return any substituted buffers to cache for (int i=0; i 0) dst.put(bb); return n; } finally { Util.releaseTemporaryDirectBuffer(bb); } } private static int readIntoNativeBuffer(FileDescriptor fd, ByteBuffer bb, long position, NativeDispatcher nd, Object lock) throws IOException { int pos = bb.position(); int lim = bb.limit(); assert (pos <= lim); int rem = (pos <= lim ? lim - pos : 0); if (rem == 0) return 0; int n = 0; if (position != -1) { n = nd.pread(fd, ((DirectBuffer)bb).address() + pos, rem, position, lock); } else { n = nd.read(fd, ((DirectBuffer)bb).address() + pos, rem); } if (n > 0) bb.position(pos + n); return n; } static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd) throws IOException { int nextWithRemaining = remaining(bufs); // if all bufs are empty we should return immediately if (nextWithRemaining < 0) return 0; // If some bufs are empty we should skip them if (nextWithRemaining > 0) bufs = skipBufs(bufs, nextWithRemaining); int numBufs = bufs.length; // Read into the shadow to ensure DirectByteBuffers are used ByteBuffer[] shadow = new ByteBuffer[numBufs]; boolean usingSlowBuffers = false; try { for (int i=0; i= len) { bytesRead -= len; int newPosition = pos + len; nextBuffer.position(newPosition); } else { // Buffers not completely filled if (bytesRead > 0) { assert(pos + bytesRead < (long)Integer.MAX_VALUE); int newPosition = (int)(pos + bytesRead); nextBuffer.position(newPosition); } break; } } // Put results from shadow into the slow buffers if (usingSlowBuffers) { for (int i=0; i