001: /* Licensed to the Apache Software Foundation (ASF) under one or more
002: * contributor license agreements. See the NOTICE file distributed with
003: * this work for additional information regarding copyright ownership.
004: * The ASF licenses this file to You under the Apache License, Version 2.0
005: * (the "License"); you may not use this file except in compliance with
006: * the License. You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.harmony.nio.internal;
018:
019: import java.io.FileDescriptor;
020: import java.io.IOException;
021: import java.net.InetAddress;
022: import java.net.InetSocketAddress;
023: import java.nio.ByteBuffer;
024: import java.nio.channels.Pipe;
025: import java.nio.channels.ServerSocketChannel;
026: import java.nio.channels.spi.SelectorProvider;
027:
028: import org.apache.harmony.luni.platform.FileDescriptorHandler;
029:
030: /*
031: * default implementation of Pipe
032: *
033: */
034:
035: final class PipeImpl extends Pipe {
036:
037: private SinkChannelImpl sink;
038:
039: private SourceChannelImpl source;
040:
041: private int serverPort;
042:
043: public PipeImpl() throws IOException {
044: super ();
045: try {
046: sink = new SinkChannelImpl(SelectorProvider.provider());
047: source = new SourceChannelImpl(SelectorProvider.provider());
048: sink.finishConnect();
049: source.accept();
050: source.closeServer();
051: } catch (IOException ioe) {
052: reset();
053: throw ioe;
054: } catch (RuntimeException e) {
055: reset();
056: throw e;
057: }
058: }
059:
060: private void reset() {
061: if (sink != null) {
062: try {
063: sink.close();
064: } catch (Exception e) {
065: }
066: }
067: if (source != null) {
068: try {
069: source.closeServer();
070: } catch (Exception e) {
071: }
072: try {
073: source.close();
074: } catch (Exception e) {
075: }
076: }
077: }
078:
079: /*
080: * @see java.nio.channels.Pipe#sink()
081: */
082: public SinkChannel sink() {
083: return sink;
084: }
085:
086: /*
087: * @see java.nio.channels.Pipe#source()
088: */
089: public SourceChannel source() {
090: return source;
091: }
092:
093: /*
094: * default implementation of SourceChannel
095: */
096: private class SourceChannelImpl extends Pipe.SourceChannel
097: implements FileDescriptorHandler {
098:
099: private SocketChannelImpl sourceSocket;
100:
101: private ServerSocketChannel sourceServer;
102:
103: /*
104: * constructor
105: */
106: protected SourceChannelImpl(SelectorProvider provider)
107: throws IOException {
108: super (provider);
109: sourceServer = provider.openServerSocketChannel();
110: sourceServer.socket()
111: .bind(
112: new InetSocketAddress(InetAddress
113: .getLocalHost(), 0));
114: serverPort = sourceServer.socket().getLocalPort();
115: }
116:
117: void closeServer() throws IOException {
118: sourceServer.close();
119: }
120:
121: void accept() throws IOException {
122: sourceSocket = (SocketChannelImpl) sourceServer.accept();
123: }
124:
125: protected void implCloseSelectableChannel() throws IOException {
126: sourceSocket.close();
127: }
128:
129: protected void implConfigureBlocking(boolean blockingMode)
130: throws IOException {
131: sourceSocket.configureBlocking(blockingMode);
132: }
133:
134: public int read(ByteBuffer buffer) throws IOException {
135: return sourceSocket.read(buffer);
136: }
137:
138: public long read(ByteBuffer[] buffers) throws IOException {
139: return read(buffers, 0, buffers.length);
140: }
141:
142: public long read(ByteBuffer[] buffers, int offset, int length)
143: throws IOException {
144: return sourceSocket.read(buffers, offset, length);
145: }
146:
147: public FileDescriptor getFD() {
148: return sourceSocket.getFD();
149: }
150: }
151:
152: /*
153: * default implementation of SinkChannel
154: */
155: private class SinkChannelImpl extends Pipe.SinkChannel implements
156: FileDescriptorHandler {
157:
158: private SocketChannelImpl sinkSocket;
159:
160: protected SinkChannelImpl(SelectorProvider provider)
161: throws IOException {
162: super (provider);
163: sinkSocket = (SocketChannelImpl) provider
164: .openSocketChannel();
165: }
166:
167: public boolean finishConnect() throws IOException {
168: return sinkSocket.connect(new InetSocketAddress(InetAddress
169: .getLocalHost(), serverPort));
170: }
171:
172: protected void implCloseSelectableChannel() throws IOException {
173: sinkSocket.close();
174: }
175:
176: protected void implConfigureBlocking(boolean blockingMode)
177: throws IOException {
178: sinkSocket.configureBlocking(blockingMode);
179: }
180:
181: public int write(ByteBuffer buffer) throws IOException {
182: return sinkSocket.write(buffer);
183: }
184:
185: public long write(ByteBuffer[] buffers) throws IOException {
186: return write(buffers, 0, buffers.length);
187: }
188:
189: public long write(ByteBuffer[] buffers, int offset, int length)
190: throws IOException {
191: return sinkSocket.write(buffers, offset, length);
192: }
193:
194: public FileDescriptor getFD() {
195: return sinkSocket.getFD();
196: }
197: }
198: }
|