/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.harmony.nio.internal; import java.io.FileDescriptor; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.Pipe; import java.nio.channels.ServerSocketChannel; import java.nio.channels.spi.SelectorProvider; import org.apache.harmony.luni.platform.FileDescriptorHandler; /* * default implementation of Pipe * */ final class PipeImpl extends Pipe { private SinkChannelImpl sink; private SourceChannelImpl source; private int serverPort; public PipeImpl() throws IOException { super(); try { sink = new SinkChannelImpl(SelectorProvider.provider()); source = new SourceChannelImpl(SelectorProvider.provider()); sink.finishConnect(); source.accept(); source.closeServer(); } catch(IOException ioe){ reset(); throw ioe; } catch(RuntimeException e){ reset(); throw e; } } private void reset(){ if(sink != null){ try { sink.close(); } catch (Exception e) { } } if(source != null){ try { source.closeServer(); } catch (Exception e) { } try { source.close(); } catch (Exception e) { } } } /* * @see java.nio.channels.Pipe#sink() */ public SinkChannel sink() { return sink; } /* * @see java.nio.channels.Pipe#source() */ public SourceChannel source() { return source; } /* * default implementation of SourceChannel */ private class SourceChannelImpl extends Pipe.SourceChannel implements FileDescriptorHandler { private SocketChannelImpl sourceSocket; private ServerSocketChannel sourceServer; /* * constructor */ protected SourceChannelImpl(SelectorProvider provider) throws IOException { super(provider); sourceServer = provider.openServerSocketChannel(); sourceServer.socket().bind( new InetSocketAddress(InetAddress.getLocalHost(), 0)); serverPort = sourceServer.socket().getLocalPort(); } void closeServer() throws IOException { sourceServer.close(); } void accept() throws IOException { sourceSocket = (SocketChannelImpl) sourceServer.accept(); } protected void implCloseSelectableChannel() throws IOException { sourceSocket.close(); } protected void implConfigureBlocking(boolean blockingMode) throws IOException { sourceSocket.configureBlocking(blockingMode); } public int read(ByteBuffer buffer) throws IOException { return sourceSocket.read(buffer); } public long read(ByteBuffer[] buffers) throws IOException { return read(buffers, 0, buffers.length); } public long read(ByteBuffer[] buffers, int offset, int length) throws IOException { return sourceSocket.read(buffers, offset, length); } public FileDescriptor getFD() { return sourceSocket.getFD(); } } /* * default implementation of SinkChannel */ private class SinkChannelImpl extends Pipe.SinkChannel implements FileDescriptorHandler { private SocketChannelImpl sinkSocket; protected SinkChannelImpl(SelectorProvider provider) throws IOException { super(provider); sinkSocket = (SocketChannelImpl) provider.openSocketChannel(); } public boolean finishConnect() throws IOException { return sinkSocket.connect(new InetSocketAddress(InetAddress .getLocalHost(), serverPort)); } protected void implCloseSelectableChannel() throws IOException { sinkSocket.close(); } protected void implConfigureBlocking(boolean blockingMode) throws IOException { sinkSocket.configureBlocking(blockingMode); } public int write(ByteBuffer buffer) throws IOException { return sinkSocket.write(buffer); } public long write(ByteBuffer[] buffers) throws IOException { return write(buffers, 0, buffers.length); } public long write(ByteBuffer[] buffers, int offset, int length) throws IOException { return sinkSocket.write(buffers, offset, length); } public FileDescriptor getFD() { return sinkSocket.getFD(); } } }