151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 2519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.nio.ch; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.ByteBuffer; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.channels.*; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.channels.spi.*; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass SinkChannelImpl 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extends Pipe.SinkChannel 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implements SelChImpl 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Used to make native read and write calls 40519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera private static final NativeDispatcher nd = new FileDispatcherImpl(); 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The file descriptor associated with this channel 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileDescriptor fd; 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // fd value needed for dev/poll. This value will remain valid 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // even after the value in the file descriptor object has been set to -1 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int fdVal; 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ID of native thread doing write, for signalling 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile long thread = 0; 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by current reading thread 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object lock = new Object(); 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by any thread that modifies the state fields declared below 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // DO NOT invoke a blocking I/O operation while holding this lock! 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object stateLock = new Object(); 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- The following fields are protected by stateLock 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Channel state 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_UNINITIALIZED = -1; 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_INUSE = 0; 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_KILLED = 1; 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile int state = ST_UNINITIALIZED; 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- End of fields protected by stateLock 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileDescriptor getFD() { 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fd; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getFDVal() { 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fdVal; 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SinkChannelImpl(SelectorProvider sp, FileDescriptor fd) { 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(sp); 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = fd; 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fdVal = IOUtil.fdVal(fd); 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.state = ST_INUSE; 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void implCloseSelectableChannel() throws IOException { 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state != ST_KILLED) 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.preClose(fd); 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long th = thread; 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (th != 0) 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NativeThread.signal(th); 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isRegistered()) 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski kill(); 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void kill() throws IOException { 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_KILLED) 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_UNINITIALIZED) { 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_KILLED; 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert !isOpen() && !isRegistered(); 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.close(fd); 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_KILLED; 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void implConfigureBlocking(boolean block) throws IOException { 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IOUtil.configureBlocking(fd, block); 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateReadyOps(int ops, int initialOps, 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SelectionKeyImpl sk) { 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int intOps = sk.nioInterestOps();// Do this just once, it synchronizes 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int oldOps = sk.nioReadyOps(); 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int newOps = initialOps; 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if ((ops & Net.POLLNVAL) != 0) 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new Error("POLLNVAL detected"); 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 124519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) { 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps = intOps; 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.nioReadyOps(newOps); 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (newOps & ~oldOps) != 0; 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 130519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (((ops & Net.POLLOUT) != 0) && 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((intOps & SelectionKey.OP_WRITE) != 0)) 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps |= SelectionKey.OP_WRITE; 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.nioReadyOps(newOps); 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (newOps & ~oldOps) != 0; 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) { 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return translateReadyOps(ops, sk.nioReadyOps(), sk); 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) { 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return translateReadyOps(ops, 0, sk); 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) { 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ops == SelectionKey.OP_WRITE) 148519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera ops = Net.POLLOUT; 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.selector.putEventOps(sk, ops); 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void ensureOpen() throws IOException { 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int write(ByteBuffer src) throws IOException { 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski thread = NativeThread.current(); 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.write(fd, src, -1, nd); 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski thread = 0; 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long write(ByteBuffer[] srcs) throws IOException { 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (srcs == null) 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lock) { 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = 0; 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski thread = NativeThread.current(); 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.write(fd, srcs, nd); 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski thread = 0; 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long write(ByteBuffer[] srcs, int offset, int length) 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return write(Util.subsequence(srcs, offset, length)); 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 209