2003-12-02 Michael Koch <konqueror@gmx.de>
[official-gcc.git] / libjava / gnu / java / nio / SocketChannelImpl.java
blob46c0d8c0fae48d5270d47b2b0415713f050390b6
1 /* SocketChannelImpl.java --
2 Copyright (C) 2002, 2003 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.java.nio;
41 import java.io.InputStream;
42 import java.io.IOException;
43 import java.io.OutputStream;
44 import java.net.InetAddress;
45 import java.net.InetSocketAddress;
46 import gnu.java.net.PlainSocketImpl;
47 import java.net.Socket;
48 import java.net.SocketAddress;
49 import java.net.SocketTimeoutException;
50 import java.nio.ByteBuffer;
51 import java.nio.channels.AlreadyConnectedException;
52 import java.nio.channels.ClosedChannelException;
53 import java.nio.channels.ConnectionPendingException;
54 import java.nio.channels.NoConnectionPendingException;
55 import java.nio.channels.NotYetConnectedException;
56 import java.nio.channels.UnresolvedAddressException;
57 import java.nio.channels.UnsupportedAddressTypeException;
58 import java.nio.channels.SocketChannel;
59 import java.nio.channels.Selector;
60 import java.nio.channels.SelectionKey;
61 import java.nio.channels.spi.SelectorProvider;
62 import gnu.classpath.Configuration;
64 public final class SocketChannelImpl extends SocketChannel
66 private PlainSocketImpl impl;
67 private NIOSocket socket;
68 private boolean blocking = true;
69 private boolean connectionPending;
71 SocketChannelImpl (SelectorProvider provider)
72 throws IOException
74 super (provider);
75 impl = new PlainSocketImpl();
76 socket = new NIOSocket (impl, this);
79 SocketChannelImpl (SelectorProvider provider,
80 NIOSocket socket)
81 throws IOException
83 super (provider);
84 this.impl = socket.getPlainSocketImpl();
85 this.socket = socket;
88 public void finalizer()
90 if (isConnected())
92 try
94 close ();
96 catch (Exception e)
102 PlainSocketImpl getPlainSocketImpl()
104 return impl;
107 int getNativeFD()
109 return socket.getPlainSocketImpl().getNativeFD();
112 protected void implCloseSelectableChannel () throws IOException
114 socket.close();
117 protected void implConfigureBlocking (boolean blocking) throws IOException
119 socket.setSoTimeout (blocking ? 0 : NIOConstants.DEFAULT_TIMEOUT);
120 this.blocking = blocking;
123 public boolean connect (SocketAddress remote) throws IOException
125 if (!isOpen())
126 throw new ClosedChannelException();
128 if (isConnected())
129 throw new AlreadyConnectedException();
131 if (connectionPending)
132 throw new ConnectionPendingException();
134 if (!(remote instanceof InetSocketAddress))
135 throw new UnsupportedAddressTypeException();
137 if (((InetSocketAddress) remote).isUnresolved())
138 throw new UnresolvedAddressException();
140 if (blocking)
142 // Do blocking connect.
143 socket.connect (remote);
144 return true;
147 // Do non-blocking connect.
150 socket.connect (remote, NIOConstants.DEFAULT_TIMEOUT);
151 return true;
153 catch (SocketTimeoutException e)
155 connectionPending = true;
156 return false;
160 public boolean finishConnect ()
161 throws IOException
163 if (!isOpen())
164 throw new ClosedChannelException();
166 if (!connectionPending)
167 throw new NoConnectionPendingException();
169 if (isConnected())
170 return true;
172 // FIXME: Handle blocking/non-blocking mode.
174 Selector selector = provider().openSelector();
175 register (selector, SelectionKey.OP_CONNECT);
177 if (isBlocking())
179 selector.select(); // blocking until channel is connected.
180 connectionPending = false;
181 return true;
184 int ready = selector.selectNow(); // non-blocking
185 if (ready == 1)
187 connectionPending = false;
188 return true;
191 return false;
194 public boolean isConnected ()
196 return socket.isConnected();
199 public boolean isConnectionPending ()
201 return connectionPending;
204 public Socket socket ()
206 return socket;
209 public int read (ByteBuffer dst) throws IOException
211 if (!isConnected())
212 throw new NotYetConnectedException();
214 byte[] data;
215 int offset = 0;
216 InputStream input = socket.getInputStream();
217 int available = input.available();
218 int len = dst.remaining();
220 if (available == 0)
221 return 0;
223 if (len > available)
224 len = available;
226 if (dst.hasArray())
228 offset = dst.arrayOffset() + dst.position();
229 data = dst.array();
231 else
233 data = new byte [len];
236 int readBytes = 0;
237 boolean completed = false;
241 begin();
242 readBytes = input.read (data, offset, len);
243 completed = true;
245 finally
247 end (completed);
250 if (readBytes > 0)
251 if (dst.hasArray())
253 dst.position (dst.position() + readBytes);
255 else
257 dst.put (data, offset, len);
260 return readBytes;
263 public long read (ByteBuffer[] dsts, int offset, int length)
264 throws IOException
266 if (!isConnected())
267 throw new NotYetConnectedException();
269 if ((offset < 0)
270 || (offset > dsts.length)
271 || (length < 0)
272 || (length > (dsts.length - offset)))
273 throw new IndexOutOfBoundsException();
275 long readBytes = 0;
277 for (int index = offset; index < length; index++)
278 readBytes += read (dsts [index]);
280 return readBytes;
283 public int write (ByteBuffer src)
284 throws IOException
286 if (!isConnected())
287 throw new NotYetConnectedException();
289 byte[] data;
290 int offset = 0;
291 int len = src.remaining();
293 if (!src.hasArray())
295 data = new byte [len];
296 src.get (data, 0, len);
298 else
300 offset = src.arrayOffset() + src.position();
301 data = src.array();
304 System.out.println ("INTERNAL: writing to socket outputstream");
306 OutputStream output = socket.getOutputStream();
307 output.write (data, offset, len);
309 if (src.hasArray())
311 src.position (src.position() + len);
314 return len;
317 public long write (ByteBuffer[] srcs, int offset, int length)
318 throws IOException
320 if (!isConnected())
321 throw new NotYetConnectedException();
323 if ((offset < 0)
324 || (offset > srcs.length)
325 || (length < 0)
326 || (length > (srcs.length - offset)))
327 throw new IndexOutOfBoundsException();
329 long writtenBytes = 0;
331 for (int index = offset; index < length; index++)
332 writtenBytes += write (srcs [index]);
334 return writtenBytes;