1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18ae704b984c10a63883cc366e823d53902d6ac7a9Elliott Hughespackage java.nio; 19f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FileDescriptor; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.ConnectException; 259229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughesimport java.net.Inet4Address; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.InetAddress; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.InetSocketAddress; 288de7cf6bff36093dda9e25a1ab3718720cb54906Elliott Hughesimport java.net.PlainSocketImpl; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.Socket; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.SocketAddress; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.SocketException; 320371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughesimport java.net.SocketUtils; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.UnknownHostException; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.AlreadyConnectedException; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.ClosedChannelException; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.ConnectionPendingException; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.IllegalBlockingModeException; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.NoConnectionPendingException; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.NotYetConnectedException; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.SocketChannel; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.UnresolvedAddressException; 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.UnsupportedAddressTypeException; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.spi.SelectorProvider; 44a1603838fe9e865575c87982e32c6343740e464cElliott Hughesimport java.util.Arrays; 45454a95f6a28855aa3c88d168b15a45bf315efc99Elliott Hughesimport libcore.io.ErrnoException; 46454a95f6a28855aa3c88d168b15a45bf315efc99Elliott Hughesimport libcore.io.Libcore; 470b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughesimport libcore.io.IoBridge; 4899a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughesimport libcore.io.IoUtils; 49454a95f6a28855aa3c88d168b15a45bf315efc99Elliott Hughesimport static libcore.io.OsConstants.*; 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The default implementation class of java.nio.channels.SocketChannel. 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 54d320e321d5567a4ac94b6e5874eda4b1f1189e13Elliott Hughesclass SocketChannelImpl extends SocketChannel implements FileDescriptorChannel { 5549ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private static final int SOCKET_STATUS_UNINITIALIZED = -1; 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 57f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Status before connect. 5849ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private static final int SOCKET_STATUS_UNCONNECTED = 0; 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 60f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Status connection pending. 6149ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private static final int SOCKET_STATUS_PENDING = 1; 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 63f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Status after connection success. 6449ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private static final int SOCKET_STATUS_CONNECTED = 2; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 66f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Status closed. 6749ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private static final int SOCKET_STATUS_CLOSED = 3; 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6949ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private final FileDescriptor fd; 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Our internal Socket. 728cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes private SocketAdapter socket = null; 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The address to be connected. 7549ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private InetSocketAddress connectAddress = null; 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7749ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private InetAddress localAddress = null; 7849ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private int localPort; 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 8049ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private int status = SOCKET_STATUS_UNINITIALIZED; 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 82f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Whether the socket is bound. 8349ff8b8582bca20a1adbda1d957220526332a8caElliott Hughes private volatile boolean isBound = false; 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 855e23b687ef8b3c696d54d1880b454942875665b7Elliott Hughes private final Object readLock = new Object(); 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 875e23b687ef8b3c696d54d1880b454942875665b7Elliott Hughes private final Object writeLock = new Object(); 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 90f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Constructor for creating a connected socket channel. 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 928cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public SocketChannelImpl(SelectorProvider selectorProvider) throws IOException { 93f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson this(selectorProvider, true); 94f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 95f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 96f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /* 97f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Constructor for creating an optionally connected socket channel. 98f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 998cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public SocketChannelImpl(SelectorProvider selectorProvider, boolean connect) throws IOException { 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(selectorProvider); 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = SOCKET_STATUS_UNCONNECTED; 1020b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes fd = (connect ? IoBridge.socket(true) : new FileDescriptor()); 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 1063218082325b6b8713a8ac15731482e3da86a7df9Elliott Hughes * Constructor for use by Pipe.SinkChannel and Pipe.SourceChannel. 1073218082325b6b8713a8ac15731482e3da86a7df9Elliott Hughes */ 1083218082325b6b8713a8ac15731482e3da86a7df9Elliott Hughes public SocketChannelImpl(SelectorProvider selectorProvider, FileDescriptor existingFd) throws IOException { 1093218082325b6b8713a8ac15731482e3da86a7df9Elliott Hughes super(selectorProvider); 1103218082325b6b8713a8ac15731482e3da86a7df9Elliott Hughes status = SOCKET_STATUS_CONNECTED; 1113218082325b6b8713a8ac15731482e3da86a7df9Elliott Hughes fd = existingFd; 1123218082325b6b8713a8ac15731482e3da86a7df9Elliott Hughes } 1133218082325b6b8713a8ac15731482e3da86a7df9Elliott Hughes 1143218082325b6b8713a8ac15731482e3da86a7df9Elliott Hughes /* 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Getting the internal Socket If we have not the socket, we create a new 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one. 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized public Socket socket() { 1208cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes if (socket == null) { 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetAddress addr = null; 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int port = 0; 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (connectAddress != null) { 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project addr = connectAddress.getAddress(); 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project port = connectAddress.getPort(); 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1288cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes socket = new SocketAdapter(new PlainSocketImpl(fd, localPort, addr, port), this); 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (SocketException e) { 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return socket; 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized public boolean isConnected() { 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return status == SOCKET_STATUS_CONNECTED; 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 142f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Status setting used by other class. 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized void setConnected() { 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = SOCKET_STATUS_CONNECTED; 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setBound(boolean flag) { 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isBound = flag; 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized public boolean isConnectionPending() { 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return status == SOCKET_STATUS_PENDING; 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean connect(SocketAddress socketAddress) throws IOException { 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // status must be open and unconnected 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkUnconnected(); 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check the address 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetSocketAddress inetSocketAddress = validateAddress(socketAddress); 164f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson InetAddress normalAddr = inetSocketAddress.getAddress(); 16562e34a21db1cbef5d2cec186ee4f15c5ec39d187Elliott Hughes int port = inetSocketAddress.getPort(); 166f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 167220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes // When connecting, map ANY address to localhost 168f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (normalAddr.isAnyLocalAddress()) { 169f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson normalAddr = InetAddress.getLocalHost(); 170f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean finished = false; 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isBlocking()) { 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1770b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes finished = IoBridge.connect(fd, normalAddr, port); 178d6ecf9222ec65a08e99f15fcc4ec024f0fffd13aElliott Hughes isBound = finished; 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (e instanceof ConnectException && !isBlocking()) { 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = SOCKET_STATUS_PENDING; 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isOpen()) { 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project close(); 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project finished = true; 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isBlocking()) { 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(finished); 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1958cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes initLocalAddressAndPort(); 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project connectAddress = inetSocketAddress; 1978cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes if (socket != null) { 1988cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes socket.socketImpl().initRemoteAddressAndPort(connectAddress.getAddress(), 1998cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes connectAddress.getPort()); 2008cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 2018cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isBlocking()) { 2048cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes status = (finished ? SOCKET_STATUS_CONNECTED : SOCKET_STATUS_UNCONNECTED); 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = SOCKET_STATUS_PENDING; 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return finished; 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2128cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes private void initLocalAddressAndPort() { 2139b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes SocketAddress sa; 2149b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes try { 2159b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes sa = Libcore.os.getsockname(fd); 2169b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes } catch (ErrnoException errnoException) { 2179b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes throw new AssertionError(errnoException); 2189b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes } 2190a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes InetSocketAddress isa = (InetSocketAddress) sa; 2200a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes localAddress = isa.getAddress(); 2210a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes localPort = isa.getPort(); 2228cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes if (socket != null) { 2238cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes socket.socketImpl().initLocalPort(localPort); 2248cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 2258cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 2268cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean finishConnect() throws IOException { 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isOpen()) { 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClosedChannelException(); 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (status == SOCKET_STATUS_CONNECTED) { 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (status != SOCKET_STATUS_PENDING) { 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NoConnectionPendingException(); 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean finished = false; 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 2442bad9bff258de6275bd3847e5e9f3169b0a93c61Elliott Hughes InetAddress inetAddress = connectAddress.getAddress(); 2452bad9bff258de6275bd3847e5e9f3169b0a93c61Elliott Hughes int port = connectAddress.getPort(); 2460b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes finished = IoBridge.isConnected(fd, inetAddress, port, 0, 0); // Return immediately. 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isBound = finished; 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (ConnectException e) { 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isOpen()) { 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project close(); 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project finished = true; 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(finished); 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = (finished ? SOCKET_STATUS_CONNECTED : status); 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isBound = finished; 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return finished; 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2658cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes void finishAccept() { 2668cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes initLocalAddressAndPort(); 2678cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 2688cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 27023ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes public int read(ByteBuffer dst) throws IOException { 271e3b6fa2bf357f2712ab2ee9e8487f157595ea0c7Elliott Hughes dst.checkWritable(); 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpenConnected(); 27323ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes if (!dst.hasRemaining()) { 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 27623ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes return readImpl(dst); 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 280d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes public long read(ByteBuffer[] targets, int offset, int length) throws IOException { 281a1603838fe9e865575c87982e32c6343740e464cElliott Hughes Arrays.checkOffsetAndCount(targets.length, offset, length); 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpenConnected(); 2832620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes int totalCount = FileChannelImpl.calculateTotalRemaining(targets, offset, length, true); 284d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes if (totalCount == 0) { 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] readArray = new byte[totalCount]; 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer readBuffer = ByteBuffer.wrap(readArray); 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int readCount; 29023ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes // read data to readBuffer, and then transfer data from readBuffer to targets. 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project readCount = readImpl(readBuffer); 29223ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes readBuffer.flip(); 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (readCount > 0) { 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int left = readCount; 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = offset; 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // transfer data from readArray to targets 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (left > 0) { 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int putLength = Math.min(targets[index].remaining(), left); 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project targets[index].put(readArray, readCount - left, putLength); 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project index++; 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project left -= putLength; 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return readCount; 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 30723ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes private int readImpl(ByteBuffer dst) throws IOException { 308f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson synchronized (readLock) { 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int readCount = 0; 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isBlocking()) { 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3140b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes readCount = IoBridge.recvfrom(true, fd, dst, 0, null, false); 315a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes if (readCount > 0) { 316a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes dst.position(dst.position() + readCount); 317a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes } 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isBlocking()) { 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(readCount > 0); 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 32323ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes return readCount; 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 32823ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes public int write(ByteBuffer src) throws IOException { 32923ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes if (src == null) { 330d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root throw new NullPointerException("src == null"); 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpenConnected(); 33323ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes if (!src.hasRemaining()) { 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 33623ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes return writeImpl(src); 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 340d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes public long write(ByteBuffer[] sources, int offset, int length) throws IOException { 341a1603838fe9e865575c87982e32c6343740e464cElliott Hughes Arrays.checkOffsetAndCount(sources.length, offset, length); 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkOpenConnected(); 3432620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes int count = FileChannelImpl.calculateTotalRemaining(sources, offset, length, false); 344d85168bd730e513cb0bd561030da3f7ea5044725Elliott Hughes if (count == 0) { 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer writeBuf = ByteBuffer.allocate(count); 348f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson for (int val = offset; val < length + offset; val++) { 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer source = sources[val]; 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int oldPosition = source.position(); 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project writeBuf.put(source); 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project source.position(oldPosition); 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project writeBuf.flip(); 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = writeImpl(writeBuf); 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int val = offset; 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int written = result; 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (result > 0) { 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer source = sources[val]; 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int gap = Math.min(result, source.remaining()); 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project source.position(source.position() + gap); 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project val++; 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result -= gap; 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return written; 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 36823ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes private int writeImpl(ByteBuffer src) throws IOException { 369f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson synchronized (writeLock) { 37023ec09188303a874b3b391f96ae0a29af002bff9Elliott Hughes if (!src.hasRemaining()) { 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int writeCount = 0; 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isBlocking()) { 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project begin(); 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3780b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes writeCount = IoBridge.sendto(fd, src, 0, null, 0); 379a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes if (writeCount > 0) { 380a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes src.position(src.position() + writeCount); 381a28bc96d63595a77fa918da8ccdda50e9eaae95eElliott Hughes } 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isBlocking()) { 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end(writeCount >= 0); 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return writeCount; 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 392f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Status check, open and "connected", when read and write. 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 3942620ff9a08ce7fc6d66b60784b1eecd78eb001baElliott Hughes synchronized private void checkOpenConnected() throws ClosedChannelException { 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isOpen()) { 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClosedChannelException(); 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isConnected()) { 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NotYetConnectedException(); 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 404f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Status check, open and "unconnected", before connection. 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized private void checkUnconnected() throws IOException { 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isOpen()) { 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClosedChannelException(); 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (status == SOCKET_STATUS_CONNECTED) { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new AlreadyConnectedException(); 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (status == SOCKET_STATUS_PENDING) { 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ConnectionPendingException(); 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 419f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Shared by this class and DatagramChannelImpl, to do the address transfer 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and check. 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static InetSocketAddress validateAddress(SocketAddress socketAddress) { 423b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (socketAddress == null) { 424126ab1b546c71137a97cef68cc89267e7f7be634Elliott Hughes throw new IllegalArgumentException("socketAddress == null"); 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(socketAddress instanceof InetSocketAddress)) { 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new UnsupportedAddressTypeException(); 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (inetSocketAddress.isUnresolved()) { 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new UnresolvedAddressException(); 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return inetSocketAddress; 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 437f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Get local address. 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InetAddress getLocalAddress() throws UnknownHostException { 4409229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes return isBound ? localAddress : Inet4Address.ANY; 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 444f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Do really closing action here. 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 447c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson protected synchronized void implCloseSelectableChannel() throws IOException { 448c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson if (status != SOCKET_STATUS_CLOSED) { 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = SOCKET_STATUS_CLOSED; 450c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson if (socket != null && !socket.isClosed()) { 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project socket.close(); 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 4530b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes IoBridge.closeSocket(fd); 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 458a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes @Override protected void implConfigureBlocking(boolean blocking) throws IOException { 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (blockingLock()) { 460a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes IoUtils.setBlocking(fd, blocking); 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 465f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Get the fd. 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public FileDescriptor getFD() { 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return fd; 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 471f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /* 472f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Adapter classes for internal socket. 473f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class SocketAdapter extends Socket { 4758cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes private final SocketChannelImpl channel; 4768cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes private final PlainSocketImpl socketImpl; 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 4788cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes SocketAdapter(PlainSocketImpl socketImpl, SocketChannelImpl channel) throws SocketException { 4798cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes super(socketImpl); 4808cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes this.socketImpl = socketImpl; 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.channel = channel; 4820371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes SocketUtils.setCreated(this); 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 4858cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes PlainSocketImpl socketImpl() { 4868cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes return socketImpl; 4878cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 4888cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SocketChannel getChannel() { 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channel; 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isBound() { 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channel.isBound; 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isConnected() { 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channel.isConnected(); 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InetAddress getLocalAddress() { 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channel.getLocalAddress(); 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (UnknownHostException e) { 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 5148cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public void connect(SocketAddress remoteAddr, int timeout) throws IOException { 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!channel.isBlocking()) { 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalBlockingModeException(); 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isConnected()) { 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new AlreadyConnectedException(); 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.connect(remoteAddr, timeout); 5228cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes channel.initLocalAddressAndPort(); 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (super.isConnected()) { 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channel.setConnected(); 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channel.isBound = super.isBound(); 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void bind(SocketAddress localAddr) throws IOException { 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (channel.isConnected()) { 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new AlreadyConnectedException(); 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (SocketChannelImpl.SOCKET_STATUS_PENDING == channel.status) { 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ConnectionPendingException(); 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.bind(localAddr); 538be0b5bd592bed1edaed2447e7ab1764b93eceaabJesse Wilson channel.initLocalAddressAndPort(); 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channel.isBound = true; 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (channel) { 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (channel.isOpen()) { 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channel.close(); 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.close(); 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channel.status = SocketChannelImpl.SOCKET_STATUS_CLOSED; 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public OutputStream getOutputStream() throws IOException { 55603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes checkOpenAndConnected(); 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isOutputShutdown()) { 55803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new SocketException("Socket output is shutdown"); 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SocketChannelOutputStream(channel); 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InputStream getInputStream() throws IOException { 56503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes checkOpenAndConnected(); 56603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (isInputShutdown()) { 56703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new SocketException("Socket input is shutdown"); 56803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } 56903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return new SocketChannelInputStream(channel); 57003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } 571f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 57203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes private void checkOpenAndConnected() throws SocketException { 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!channel.isOpen()) { 57403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new SocketException("Socket is closed"); 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!channel.isConnected()) { 57703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new SocketException("Socket is not connected"); 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 5803267a46b52d848e1e9e20c226512688f0c50d4c3Jeff Sharkey 5813267a46b52d848e1e9e20c226512688f0c50d4c3Jeff Sharkey @Override 5823267a46b52d848e1e9e20c226512688f0c50d4c3Jeff Sharkey public FileDescriptor getFileDescriptor$() { 5833267a46b52d848e1e9e20c226512688f0c50d4c3Jeff Sharkey return socketImpl.getFD$(); 5843267a46b52d848e1e9e20c226512688f0c50d4c3Jeff Sharkey } 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This output stream delegates all operations to the associated channel. 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Throws an IllegalBlockingModeException if the channel is in non-blocking 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * mode when performing write operations. 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class SocketChannelOutputStream extends OutputStream { 5938cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes private final SocketChannel channel; 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SocketChannelOutputStream(SocketChannel channel) { 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.channel = channel; 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 600f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Closes this stream and channel. 601f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @exception IOException thrown if an error occurs during the close 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channel.close(); 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 610a1603838fe9e865575c87982e32c6343740e464cElliott Hughes public void write(byte[] buffer, int offset, int byteCount) throws IOException { 611a1603838fe9e865575c87982e32c6343740e464cElliott Hughes Arrays.checkOffsetAndCount(buffer.length, offset, byteCount); 612a1603838fe9e865575c87982e32c6343740e464cElliott Hughes ByteBuffer buf = ByteBuffer.wrap(buffer, offset, byteCount); 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!channel.isBlocking()) { 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalBlockingModeException(); 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channel.write(buf); 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void write(int oneByte) throws IOException { 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!channel.isBlocking()) { 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalBlockingModeException(); 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer buffer = ByteBuffer.allocate(1); 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buffer.put(0, (byte) (oneByte & 0xFF)); 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channel.write(buffer); 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This input stream delegates all operations to the associated channel. 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Throws an IllegalBlockingModeException if the channel is in non-blocking 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * mode when performing read operations. 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class SocketChannelInputStream extends InputStream { 6368cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes private final SocketChannel channel; 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SocketChannelInputStream(SocketChannel channel) { 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.channel = channel; 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes this stream and channel. 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project channel.close(); 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!channel.isBlocking()) { 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalBlockingModeException(); 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer buf = ByteBuffer.allocate(1); 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = channel.read(buf); 657fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes return (result == -1) ? result : (buf.get(0) & 0xff); 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 661a1603838fe9e865575c87982e32c6343740e464cElliott Hughes public int read(byte[] buffer, int offset, int byteCount) throws IOException { 662a1603838fe9e865575c87982e32c6343740e464cElliott Hughes Arrays.checkOffsetAndCount(buffer.length, offset, byteCount); 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!channel.isBlocking()) { 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalBlockingModeException(); 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 666a1603838fe9e865575c87982e32c6343740e464cElliott Hughes ByteBuffer buf = ByteBuffer.wrap(buffer, offset, byteCount); 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return channel.read(buf); 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 671