From: <hag...@us...> - 2006-12-14 10:17:18
|
Revision: 2919 http://jnode.svn.sourceforge.net/jnode/?rev=2919&view=rev Author: hagar-wize Date: 2006-12-14 02:17:15 -0800 (Thu, 14 Dec 2006) Log Message: ----------- Classpath patches Modified Paths: -------------- trunk/core/src/classpath/gnu/gnu/java/net/PlainDatagramSocketImpl.java trunk/core/src/classpath/gnu/gnu/java/net/PlainSocketImpl.java trunk/core/src/classpath/gnu/gnu/java/nio/charset/ISO_8859_1.java trunk/core/src/classpath/gnu/gnu/java/nio/charset/US_ASCII.java trunk/core/src/classpath/gnu/gnu/java/nio/charset/iconv/IconvEncoder.java Modified: trunk/core/src/classpath/gnu/gnu/java/net/PlainDatagramSocketImpl.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/net/PlainDatagramSocketImpl.java 2006-12-14 10:15:31 UTC (rev 2918) +++ trunk/core/src/classpath/gnu/gnu/java/net/PlainDatagramSocketImpl.java 2006-12-14 10:17:15 UTC (rev 2919) @@ -1,5 +1,5 @@ /* PlainDatagramSocketImpl.java -- Default DatagramSocket implementation - Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,7 +38,10 @@ package gnu.java.net; +import gnu.java.nio.VMChannel; + import java.io.IOException; +import java.io.InterruptedIOException; import java.net.DatagramPacket; import java.net.DatagramSocketImpl; import java.net.InetAddress; @@ -46,8 +49,8 @@ import java.net.NetworkInterface; import java.net.SocketAddress; import java.net.SocketException; -import java.net.SocketOptions; -import gnu.classpath.Configuration; +import java.net.SocketTimeoutException; +import java.nio.ByteBuffer; /** * Written using on-line Java Platform 1.2 API Specification, as well @@ -65,17 +68,12 @@ */ public final class PlainDatagramSocketImpl extends DatagramSocketImpl { - // @vm-specific removed System.loadLibrary - + private final VMChannel channel; + /** - * Option id for the IP_TTL (time to live) value. + * The platform-specific socket implementation. */ - private static final int IP_TTL = 0x1E61; // 7777 - - /** - * This is the actual underlying file descriptor - */ - int native_fd = -1; + private final VMPlainSocketImpl impl; /** * Lock object to serialize threads wanting to receive @@ -90,24 +88,26 @@ /** * Default do nothing constructor */ - public PlainDatagramSocketImpl() + public PlainDatagramSocketImpl() throws IOException { + channel = new VMChannel(); + impl = new VMPlainSocketImpl(channel); } - protected void finalize() throws Throwable + /*protected void finalize() throws Throwable { synchronized (this) { - if (native_fd != -1) + if (channel.getState().isValid()) close(); } super.finalize(); - } + }*/ - public int getNativeFD() + /*public int getNativeFD() { return native_fd; - } + }*/ /** * Binds this socket to a particular port and interface @@ -120,9 +120,20 @@ protected synchronized void bind(int port, InetAddress addr) throws SocketException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + try + { + impl.bind(new InetSocketAddress(addr, port)); + } + catch (SocketException se) + { + throw se; + } + catch (IOException ioe) + { + SocketException se = new SocketException(); + se.initCause(ioe); + throw se; + } } /** @@ -130,13 +141,58 @@ * * @exception SocketException If an error occurs */ - protected synchronized void create() throws SocketException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + protected synchronized void create() throws SocketException + { + try + { + channel.initSocket(false); + } + catch (SocketException se) + { + throw se; + } + catch (IOException ioe) + { + SocketException se = new SocketException(); + se.initCause(ioe); + throw se; + } } /** + * Connects to the remote address and port specified as arguments. + * + * @param addr The remote address to connect to + * @param port The remote port to connect to + * + * @exception SocketException If an error occurs + */ + protected void connect(InetAddress addr, int port) throws SocketException + { + channel.connect(new InetSocketAddress(addr, port), 0); + } + + /** + * Disconnects the socket. + * + * @since 1.4 + */ + protected void disconnect() + { + synchronized (this) + { + try + { + if (channel.getState().isValid()) + channel.disconnect(); + } + catch (IOException ioe) + { + } + } + } + + /** * Sets the Time to Live value for the socket * * @param ttl The new TTL value @@ -145,7 +201,7 @@ */ protected synchronized void setTimeToLive(int ttl) throws IOException { - setOption(IP_TTL, new Integer(ttl)); + impl.setTimeToLive(ttl); } /** @@ -157,48 +213,60 @@ */ protected synchronized int getTimeToLive() throws IOException { - Object obj = getOption(IP_TTL); + return impl.getTimeToLive(); + } - if (! (obj instanceof Integer)) - throw new IOException("Internal Error"); + protected int getLocalPort() + { + if (channel == null) + return -1; - return ((Integer) obj).intValue(); + try + { + InetSocketAddress local = channel.getLocalAddress(); + if (local == null) + return -1; + return local.getPort(); + } + catch (IOException ioe) + { + return -1; + } } /** * Sends a packet of data to a remote host * - * @param addr The address to send to - * @param port The port to send to - * @param buf The buffer to send - * @param offset The offset of the data in the buffer to send - * @param len The length of the data to send - * - * @exception IOException If an error occurs - */ - private void sendto (InetAddress addr, int port, - byte[] buf, int offset, int len) - throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); - } - - /** - * Sends a packet of data to a remote host - * * @param packet The packet to send * * @exception IOException If an error occurs */ protected void send(DatagramPacket packet) throws IOException { - synchronized(SEND_LOCK) + synchronized (SEND_LOCK) { - sendto(packet.getAddress(), packet.getPort(), packet.getData(), - packet.getOffset(), packet.getLength()); + ByteBuffer buf = ByteBuffer.wrap(packet.getData(), + packet.getOffset(), + packet.getLength()); + InetAddress remote = packet.getAddress(); + int port = packet.getPort(); + if (remote == null) + throw new NullPointerException(); + if (port <= 0) + throw new SocketException("invalid port " + port); + while (true) + { + try + { + channel.send(buf, new InetSocketAddress(remote, port)); + break; + } + catch (InterruptedIOException ioe) + { + // Ignore; interrupted system call. + } + } } - } /** @@ -211,63 +279,123 @@ protected void receive(DatagramPacket packet) throws IOException { - synchronized(RECEIVE_LOCK) - { - receive0(packet); - } + synchronized(RECEIVE_LOCK) + { + ByteBuffer buf = ByteBuffer.wrap(packet.getData(), + packet.getOffset(), + packet.getLength()); + SocketAddress addr = null; + while (true) + { + try + { + addr = channel.receive(buf); + break; + } + catch (SocketTimeoutException ste) + { + throw ste; + } + catch (InterruptedIOException iioe) + { + // Ignore. Loop. + } + } + if (addr != null) + packet.setSocketAddress(addr); + packet.setLength(buf.position() - packet.getOffset()); + } } - /** - * Native call to receive a UDP packet from the network - * - * @param packet The packet to fill in with the data received - * - * @exception IOException IOException If an error occurs - */ - private void receive0(DatagramPacket packet) throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); - } /** * Sets the value of an option on the socket * - * @param option_id The identifier of the option to set - * @param val The value of the option to set + * @param optionId The identifier of the option to set + * @param value The value of the option to set * * @exception SocketException If an error occurs */ - public synchronized void setOption(int option_id, Object val) - throws SocketException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + public synchronized void setOption(int optionId, Object value) + throws SocketException + { + switch (optionId) + { + case IP_MULTICAST_IF: + case IP_MULTICAST_IF2: + impl.setMulticastInterface(optionId, (InetAddress) value); + break; + + case IP_MULTICAST_LOOP: + case SO_BROADCAST: + case SO_KEEPALIVE: + case SO_OOBINLINE: + case TCP_NODELAY: + case IP_TOS: + case SO_LINGER: + case SO_RCVBUF: + case SO_SNDBUF: + case SO_TIMEOUT: + case SO_REUSEADDR: + impl.setOption(optionId, value); + return; + + default: + throw new SocketException("cannot set option " + optionId); + } } /** * Retrieves the value of an option on the socket * - * @param option_id The identifier of the option to retrieve + * @param optionId The identifier of the option to retrieve * * @return The value of the option * * @exception SocketException If an error occurs */ - public synchronized Object getOption(int option_id) - throws SocketException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + public synchronized Object getOption(int optionId) + throws SocketException + { + if (optionId == SO_BINDADDR) + { + try + { + InetSocketAddress local = channel.getLocalAddress(); + if (local == null) + return null; + return local.getAddress(); + } + catch (SocketException se) + { + throw se; + } + catch (IOException ioe) + { + SocketException se = new SocketException(); + se.initCause(ioe); + throw se; + } + } + if (optionId == IP_MULTICAST_IF || optionId == IP_MULTICAST_IF2) + return impl.getMulticastInterface(optionId); + + return impl.getOption(optionId); } /** * Closes the socket */ - protected synchronized void close() { - // @vm-specific no natives - //TODO implement me - throw new RuntimeException("Not implemented"); + protected synchronized void close() + { + try + { + if (channel.getState().isValid()) + channel.close(); + } + catch (IOException ioe) + { + } } /** @@ -305,9 +433,9 @@ * * @exception IOException If an error occurs */ - protected synchronized void join(InetAddress addr) throws IOException { - // @vm-specific no natives - throw new SocketException("Not implemented"); + protected synchronized void join(InetAddress addr) throws IOException + { + impl.join(addr); } /** @@ -317,10 +445,9 @@ * * @exception IOException If an error occurs */ - protected synchronized void leave(InetAddress addr) throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + protected synchronized void leave(InetAddress addr) throws IOException + { + impl.leave(addr); } /** @@ -338,14 +465,22 @@ } public void joinGroup(SocketAddress address, NetworkInterface netIf) + throws IOException { - throw new InternalError - ("PlainDatagramSocketImpl::joinGroup is not implemented"); + if (address == null) + throw new NullPointerException(); + if (!(address instanceof InetSocketAddress)) + throw new SocketException("unknown address type"); + impl.joinGroup((InetSocketAddress) address, netIf); } public void leaveGroup(SocketAddress address, NetworkInterface netIf) + throws IOException { - throw new InternalError - ("PlainDatagramSocketImpl::leaveGroup is not implemented"); + if (address == null) + throw new NullPointerException(); + if (!(address instanceof InetSocketAddress)) + throw new SocketException("unknown address type"); + impl.leaveGroup((InetSocketAddress) address, netIf); } } Modified: trunk/core/src/classpath/gnu/gnu/java/net/PlainSocketImpl.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/net/PlainSocketImpl.java 2006-12-14 10:15:31 UTC (rev 2918) +++ trunk/core/src/classpath/gnu/gnu/java/net/PlainSocketImpl.java 2006-12-14 10:17:15 UTC (rev 2919) @@ -39,16 +39,20 @@ package gnu.java.net; +import gnu.java.nio.SocketChannelImpl; +import gnu.java.nio.VMChannel; + import java.io.InputStream; import java.io.IOException; +import java.io.InterruptedIOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.SocketException; import java.net.SocketImpl; -import java.net.SocketOptions; -import gnu.classpath.Configuration; +import java.net.SocketTimeoutException; +import java.nio.ByteBuffer; /** * Written using on-line Java Platform 1.2 API Specification, as well @@ -66,25 +70,13 @@ * @author Nic Ferrier (nfe...@ta...) * @author Aaron M. Renn (ar...@ur...) */ -public final class PlainSocketImpl extends SocketImpl +public class PlainSocketImpl extends SocketImpl { - // Static initializer to load native library. - static - { - if (Configuration.INIT_LOAD_LIBRARY) - { - System.loadLibrary("javanet"); - } - } /** - * The OS file handle representing the socket. - * This is used for reads and writes to/from the socket and - * to close it. - * - * When the socket is closed this is reset to -1. + * The underlying plain socket VM implementation. */ - int native_fd = -1; + protected VMPlainSocketImpl impl; /** * A cached copy of the in stream for reading from the socket. @@ -101,8 +93,14 @@ * is being invoked on this socket. */ private boolean inChannelOperation; - + /** + * The socket channel we use for IO operation. Package-private for + * use by inner classes. + */ + SocketChannelImpl channel; + + /** * Indicates whether we should ignore whether any associated * channel is set to non-blocking mode. Certain operations * throw an <code>IllegalBlockingModeException</code> if the @@ -124,48 +122,44 @@ } /** - * Default do nothing constructor + * Default do nothing constructor. */ public PlainSocketImpl() { + this.impl = new VMPlainSocketImpl(); } - - protected void finalize() throws Throwable - { - synchronized (this) - { - if (native_fd != -1) - try - { - close(); - } - catch (IOException ex) - { - } - } - super.finalize(); - } - public int getNativeFD() - { - return native_fd; - } - /** * Sets the specified option on a socket to the passed in object. For * options that take an integer argument, the passed in object is an * Integer. The option_id parameter is one of the defined constants in * this interface. * - * @param option_id The identifier of the option - * @param val The value to set the option to + * @param optionId The identifier of the option + * @param value The value to set the option to * - * @exception SocketException If an error occurs + * @throws SocketException if an error occurs */ - public void setOption(int optID, Object value) throws SocketException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + public void setOption(int optionId, Object value) throws SocketException + { + switch (optionId) + { + case SO_LINGER: + case IP_MULTICAST_LOOP: + case SO_BROADCAST: + case SO_KEEPALIVE: + case SO_OOBINLINE: + case TCP_NODELAY: + case IP_TOS: + case SO_RCVBUF: + case SO_SNDBUF: + case SO_TIMEOUT: + case SO_REUSEADDR: + impl.setOption(optionId, value); + return; + default: + throw new SocketException("Unrecognized TCP option: " + optionId); + } } /** @@ -173,133 +167,144 @@ * will be an Integer for options that have integer values. The option_id * is one of the defined constants in this interface. * - * @param option_id The option identifier + * @param optionId the option identifier * - * @return The current value of the option + * @return the current value of the option * - * @exception SocketException If an error occurs + * @throws SocketException if an error occurs */ - public Object getOption(int optID) throws SocketException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + public Object getOption(int optionId) throws SocketException + { + if (optionId == SO_BINDADDR) + { + try + { + return channel.getVMChannel().getLocalAddress().getAddress(); + } + catch (IOException ioe) + { + SocketException se = new SocketException(); + se.initCause(ioe); + throw se; + } + } + + // This filters options which are invalid for TCP. + switch (optionId) + { + case SO_LINGER: + case IP_MULTICAST_LOOP: + case SO_BROADCAST: + case SO_KEEPALIVE: + case SO_OOBINLINE: + case TCP_NODELAY: + case IP_TOS: + case SO_RCVBUF: + case SO_SNDBUF: + case SO_TIMEOUT: + case SO_REUSEADDR: + return impl.getOption(optionId); + default: + throw new SocketException("Unrecognized TCP option: " + optionId); + } + } - /** - * Flushes the input stream and closes it. If you read from the input stream - * after calling this method a <code>IOException</code> will be thrown. - * - * @throws IOException if an error occurs - */ - public void shutdownInput() + public void shutdownInput() throws IOException { - // @vm-specific no natives - //TODO implement me - throw new InternalError ("PlainSocketImpl::shutdownInput not implemented"); + impl.shutdownInput(); } - /** - * Flushes the output stream and closes it. If you write to the output stream - * after calling this method a <code>IOException</code> will be thrown. - * - * @throws IOException if an error occurs - */ public void shutdownOutput() throws IOException { - // @vm-specific no natives - //TODO implement me - throw new InternalError ("PlainSocketImpl::shutdownOutput not implemented"); + impl.shutdownOutput(); } /** * Creates a new socket that is not bound to any local address/port and - * is not connected to any remote address/port. This will be created as - * a stream socket if the stream parameter is true, or a datagram socket - * if the stream parameter is false. + * is not connected to any remote address/port. The stream parameter will be + * ignored since PlainSocketImpl always is a stream socket. Datagram sockets + * are handled by PlainDatagramSocketImpl. * - * @param stream true for a stream socket, false for a datagram socket + * @param stream <code>true</code> for stream sockets, <code>false</code> for + * datagram sockets */ - protected synchronized void create(boolean stream) throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + protected synchronized void create(boolean stream) throws IOException + { + channel = new SocketChannelImpl(false); + VMChannel vmchannel = channel.getVMChannel(); + vmchannel.initSocket(stream); + channel.configureBlocking(true); + impl.getState().setChannelFD(vmchannel.getState()); } /** * Connects to the remote hostname and port specified as arguments. * - * @param hostname The remote hostname to connect to - * @param port The remote port to connect to + * @param hostname the remote hostname to connect to + * @param port the remote port to connect to * - * @exception IOException If an error occurs + * @throws IOException If an error occurs */ - protected synchronized void connect(String host, int port) throws IOException + protected synchronized void connect(String hostname, int port) + throws IOException { - connect(InetAddress.getByName(host), port); + connect(InetAddress.getByName(hostname), port); } /** * Connects to the remote address and port specified as arguments. * - * @param addr The remote address to connect to - * @param port The remote port to connect to + * @param addr the remote address to connect to + * @param port the remote port to connect to * - * @exception IOException If an error occurs + * @throws IOException If an error occurs */ - protected void connect(InetAddress addr, int port) throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + protected void connect(InetAddress addr, int port) throws IOException + { + connect(new InetSocketAddress(addr, port), 0); } /** * Connects to the remote socket address with a specified timeout. * - * @param timeout The timeout to use for this connect, 0 means infinite. + * @param address the remote address to connect to + * @param timeout the timeout to use for this connect, 0 means infinite. * - * @exception IOException If an error occurs + * @throws IOException If an error occurs */ - protected synchronized void connect(SocketAddress address, int timeout) throws IOException + protected synchronized void connect(SocketAddress address, int timeout) + throws IOException { - InetSocketAddress sockAddr = (InetSocketAddress) address; - InetAddress addr = sockAddr.getAddress(); - - if (addr == null) - throw new IllegalArgumentException("address is unresolved: " + sockAddr); - - int port = sockAddr.getPort(); + if (channel == null) + create(true); + boolean connected = channel.connect(address, timeout); + if (!connected) + throw new SocketTimeoutException("connect timed out"); - if (timeout < 0) - throw new IllegalArgumentException("negative timeout"); - - Object oldTimeoutObj = null; - - try - { - oldTimeoutObj = this.getOption (SocketOptions.SO_TIMEOUT); - this.setOption (SocketOptions.SO_TIMEOUT, new Integer (timeout)); - connect (addr, port); - } - finally - { - if (oldTimeoutObj != null) - this.setOption (SocketOptions.SO_TIMEOUT, oldTimeoutObj); - } + // Using the given SocketAddress is important to preserve + // hostnames given by the caller. + InetSocketAddress addr = (InetSocketAddress) address; + this.address = addr.getAddress(); + this.port = addr.getPort(); } /** * Binds to the specified port on the specified addr. Note that this addr * must represent a local IP address. **** How bind to INADDR_ANY? **** * - * @param addr The address to bind to - * @param port The port number to bind to + * @param addr the address to bind to + * @param port the port number to bind to * - * @exception IOException If an error occurs + * @throws IOException if an error occurs */ protected synchronized void bind(InetAddress addr, int port) - throws IOException { - // @vm-specific no natives - throw new SocketException("Not implemented"); + throws IOException + { + if (channel == null) + create(true); + impl.bind(new InetSocketAddress(addr, port)); + localport = channel.getVMChannel().getLocalAddress().getPort(); } /** @@ -310,13 +315,12 @@ * * @param queuelen The length of the pending connection queue * - * @exception IOException If an error occurs + * @throws IOException If an error occurs */ protected synchronized void listen(int queuelen) - throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + throws IOException + { + impl.listen(queuelen); } /** @@ -326,78 +330,64 @@ * @param impl The SocketImpl object to accept this connection. */ protected synchronized void accept(SocketImpl impl) - throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + throws IOException + { + if (channel == null) + create(true); + if (!(impl instanceof PlainSocketImpl)) + throw new IOException("incompatible SocketImpl: " + + impl.getClass().getName()); + PlainSocketImpl that = (PlainSocketImpl) impl; + VMChannel c = channel.getVMChannel().accept(); + that.impl.getState().setChannelFD(c.getState()); + that.channel = new SocketChannelImpl(c); + that.setOption(SO_REUSEADDR, Boolean.TRUE); + // Reset the inherited timeout. + that.setOption(SO_TIMEOUT, Integer.valueOf(0)); + } /** * Returns the number of bytes that the caller can read from this socket * without blocking. * - * @return The number of readable bytes before blocking + * @return the number of readable bytes before blocking * - * @exception IOException If an error occurs + * @throws IOException if an error occurs */ - protected int available() throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + protected int available() throws IOException + { + if (channel == null) + throw new SocketException("not connected"); + return channel.getVMChannel().available(); } /** * Closes the socket. This will cause any InputStream or OutputStream * objects for this Socket to be closed as well. + * * <p> * Note that if the SO_LINGER option is set on this socket, then the * operation could block. + * </p> * - * @exception IOException If an error occurs + * @throws IOException if an error occurs */ - protected void close() throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); + protected void close() throws IOException + { + if (impl.getState().isValid()) + impl.close(); + + address = null; + port = -1; } - public void sendUrgentData(int data) + public void sendUrgentData(int data) throws IOException { - throw new InternalError ("PlainSocketImpl::sendUrgentData not implemented"); + impl.sendUrgentData(data); } /** - * Internal method used by SocketInputStream for reading data from - * the connection. Reads up to len bytes of data into the buffer - * buf starting at offset bytes into the buffer. - * - * @return The actual number of bytes read or -1 if end of stream. - * - * @exception IOException If an error occurs - */ - protected int read(byte[] buf, int offset, int len) - throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); - - } - - /** - * Internal method used by SocketOuputStream for writing data to - * the connection. Writes up to len bytes of data from the buffer - * buf starting at offset bytes into the buffer. - * - * @exception IOException If an error occurs - */ - protected void write(byte[] buf, int offset, int len) - throws IOException { - // @vm-specific no natives - //TODO implement me - throw new SocketException("Not implemented"); - } - - /** * Returns an InputStream object for reading from this socket. This will * be an instance of SocketInputStream. * @@ -409,7 +399,7 @@ { if (in == null) in = new SocketInputStream(); - + return in; } @@ -425,15 +415,104 @@ { if (out == null) out = new SocketOutputStream(); - + return out; } + + public VMChannel getVMChannel() + { + if (channel == null) + return null; + return channel.getVMChannel(); + } + /* (non-Javadoc) + * @see java.net.SocketImpl#getInetAddress() + */ + protected InetAddress getInetAddress() + { + if (channel == null) + return null; + + try + { + InetSocketAddress remote = channel.getVMChannel().getPeerAddress(); + if (remote == null) + return null; + // To mimic behavior of the RI the InetAddress instance which was + // used to establish the connection is returned instead of one that + // was created by the native layer (this preserves exact hostnames). + if (address != null) + return address; + + return remote.getAddress(); + } + catch (IOException ioe) + { + return null; + } + } + + /* (non-Javadoc) + * @see java.net.SocketImpl#getLocalPort() + */ + protected int getLocalPort() + { + if (channel == null) + return -1; + try + { + InetSocketAddress local = channel.getVMChannel().getLocalAddress(); + if (local == null) + return -1; + return local.getPort(); + } + catch (IOException ioe) + { + return -1; + } + } + + public InetSocketAddress getLocalAddress() + { + if (channel == null) + return null; + try + { + return channel.getVMChannel().getLocalAddress(); + } + catch (IOException ioe) + { + return null; + } + } + + /* (non-Javadoc) + * @see java.net.SocketImpl#getPort() + */ + protected int getPort() + { + if (channel == null) + return -1; + + try + { + InetSocketAddress remote = channel.getVMChannel().getPeerAddress(); + if (remote == null) + return -1; + return remote.getPort(); + } + catch (IOException ioe) + { + return -1; + } + } + /** * This class contains an implementation of <code>InputStream</code> for * sockets. It in an internal only class used by <code>PlainSocketImpl</code>. * - * @author Nic Ferrier (nfe...@ta...) + * @author Nic Ferrier <nfe...@ta...> */ final class SocketInputStream extends InputStream @@ -465,13 +544,23 @@ */ public int read() throws IOException { - byte buf[] = new byte [1]; - int bytes_read = read(buf, 0, 1); - - if (bytes_read == -1) - return -1; - - return buf[0] & 0xFF; + if (channel == null) + throw new SocketException("not connected"); + while (true) + { + try + { + return channel.getVMChannel().read(); + } + catch (SocketTimeoutException ste) + { + throw ste; + } + catch (InterruptedIOException iioe) + { + // Ignore; NIO may throw this; net io shouldn't + } + } } /** @@ -488,12 +577,24 @@ */ public int read (byte[] buf, int offset, int len) throws IOException { - int bytes_read = PlainSocketImpl.this.read (buf, offset, len); - - if (bytes_read == 0) - return -1; - - return bytes_read; + if (channel == null) + throw new SocketException("not connected"); + ByteBuffer b = ByteBuffer.wrap(buf, offset, len); + while (true) + { + try + { + return channel.read(b); + } + catch (SocketTimeoutException ste) + { + throw ste; + } + catch (InterruptedIOException iioe) + { + // Ignored; NIO may throw this; net IO not. + } + } } } @@ -503,7 +604,7 @@ * <code>getOutputStream method</code>. It expects only to be used in that * context. * - * @author Nic Ferrier (nfe...@ta...) + * @author Nic Ferrier <nfe...@ta...> */ final class SocketOutputStream extends OutputStream @@ -529,8 +630,20 @@ */ public void write(int b) throws IOException { - byte buf[] = { (byte) b }; - write(buf, 0, 1); + if (channel == null) + throw new SocketException("not connected"); + while (true) + { + try + { + channel.getVMChannel().write(b); + return; + } + catch (InterruptedIOException iioe) + { + // Ignored. + } + } } /** @@ -545,7 +658,21 @@ */ public void write (byte[] buf, int offset, int len) throws IOException { - PlainSocketImpl.this.write (buf, offset, len); + if (channel == null) + throw new SocketException("not connected"); + ByteBuffer b = ByteBuffer.wrap(buf, offset, len); + while (b.hasRemaining()) + { + try + { + if (channel.write(b) == -1) + throw new IOException("channel has been closed"); + } + catch (InterruptedIOException iioe) + { + // Ignored. + } + } } } } Modified: trunk/core/src/classpath/gnu/gnu/java/nio/charset/ISO_8859_1.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/nio/charset/ISO_8859_1.java 2006-12-14 10:15:31 UTC (rev 2918) +++ trunk/core/src/classpath/gnu/gnu/java/nio/charset/ISO_8859_1.java 2006-12-14 10:17:15 UTC (rev 2919) @@ -128,6 +128,19 @@ super (cs, 1.0f, 1.0f); } + public boolean canEncode(char c) + { + return c <= 0xff; + } + + public boolean canEncode(CharSequence cs) + { + for (int i = 0; i < cs.length(); ++i) + if (! canEncode(cs.charAt(i))) + return false; + return true; + } + protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out) { // TODO: Optimize this in the case in.hasArray() / out.hasArray() Modified: trunk/core/src/classpath/gnu/gnu/java/nio/charset/US_ASCII.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/nio/charset/US_ASCII.java 2006-12-14 10:15:31 UTC (rev 2918) +++ trunk/core/src/classpath/gnu/gnu/java/nio/charset/US_ASCII.java 2006-12-14 10:17:15 UTC (rev 2919) @@ -134,6 +134,19 @@ super (cs, 1.0f, 1.0f); } + public boolean canEncode(char c) + { + return c <= 0x7f; + } + + public boolean canEncode(CharSequence cs) + { + for (int i = 0; i < cs.length(); ++i) + if (! canEncode(cs.charAt(i))) + return false; + return true; + } + protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out) { // TODO: Optimize this in the case in.hasArray() / out.hasArray() @@ -141,7 +154,7 @@ { char c = in.get (); - if (c > Byte.MAX_VALUE) + if (c > 0x7f) { in.position (in.position () - 1); return CoderResult.unmappableForLength (1); Modified: trunk/core/src/classpath/gnu/gnu/java/nio/charset/iconv/IconvEncoder.java =================================================================== --- trunk/core/src/classpath/gnu/gnu/java/nio/charset/iconv/IconvEncoder.java 2006-12-14 10:15:31 UTC (rev 2918) +++ trunk/core/src/classpath/gnu/gnu/java/nio/charset/iconv/IconvEncoder.java 2006-12-14 10:17:15 UTC (rev 2919) @@ -43,7 +43,6 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |