|
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.
|