1 /* SocketChannelImpl.java --
2 Copyright (C) 2002, 2003, 2004 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)
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., 51 Franklin Street, Fifth Floor, Boston, MA
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
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. */
41 import gnu
.java
.net
.PlainSocketImpl
;
43 import java
.io
.IOException
;
44 import java
.io
.InputStream
;
45 import java
.io
.OutputStream
;
46 import java
.net
.InetSocketAddress
;
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
.SelectionKey
;
57 import java
.nio
.channels
.Selector
;
58 import java
.nio
.channels
.SocketChannel
;
59 import java
.nio
.channels
.UnresolvedAddressException
;
60 import java
.nio
.channels
.UnsupportedAddressTypeException
;
61 import java
.nio
.channels
.spi
.SelectorProvider
;
63 public final class SocketChannelImpl
extends SocketChannel
65 private PlainSocketImpl impl
;
66 private NIOSocket socket
;
67 private boolean connectionPending
;
69 SocketChannelImpl (SelectorProvider provider
)
73 impl
= new PlainSocketImpl();
74 socket
= new NIOSocket (impl
, this);
75 configureBlocking(true);
78 SocketChannelImpl (SelectorProvider provider
,
83 this.impl
= socket
.getPlainSocketImpl();
87 public void finalizer()
101 PlainSocketImpl
getPlainSocketImpl()
106 protected void implCloseSelectableChannel () throws IOException
111 protected void implConfigureBlocking (boolean blocking
) throws IOException
113 socket
.setSoTimeout (blocking ?
0 : NIOConstants
.DEFAULT_TIMEOUT
);
116 public boolean connect (SocketAddress remote
) throws IOException
119 throw new ClosedChannelException();
122 throw new AlreadyConnectedException();
124 if (connectionPending
)
125 throw new ConnectionPendingException();
127 if (!(remote
instanceof InetSocketAddress
))
128 throw new UnsupportedAddressTypeException();
130 if (((InetSocketAddress
) remote
).isUnresolved())
131 throw new UnresolvedAddressException();
135 socket
.getPlainSocketImpl().setInChannelOperation(true);
136 // indicate that a channel is initiating the accept operation
137 // so that the socket ignores the fact that we might be in
138 // non-blocking mode.
142 // Do blocking connect.
143 socket
.connect (remote
);
147 // Do non-blocking connect.
150 socket
.connect (remote
, NIOConstants
.DEFAULT_TIMEOUT
);
153 catch (SocketTimeoutException e
)
155 connectionPending
= true;
161 socket
.getPlainSocketImpl().setInChannelOperation(false);
165 public boolean finishConnect ()
169 throw new ClosedChannelException();
171 if (!isConnected() && !connectionPending
)
172 throw new NoConnectionPendingException();
177 // FIXME: Handle blocking/non-blocking mode.
179 Selector selector
= provider().openSelector();
180 register(selector
, SelectionKey
.OP_CONNECT
);
184 selector
.select(); // blocking until channel is connected.
185 connectionPending
= false;
189 int ready
= selector
.selectNow(); // non-blocking
192 connectionPending
= false;
199 public boolean isConnected ()
201 return socket
.isConnected();
204 public boolean isConnectionPending ()
206 return connectionPending
;
209 public Socket
socket ()
214 public int read(ByteBuffer dst
) throws IOException
217 throw new NotYetConnectedException();
221 InputStream input
= socket
.getInputStream();
222 int available
= input
.available();
223 int len
= dst
.capacity() - dst
.position();
225 if ((! isBlocking()) && available
== 0)
230 offset
= dst
.arrayOffset() + dst
.position();
235 data
= new byte [len
];
239 boolean completed
= false;
244 socket
.getPlainSocketImpl().setInChannelOperation(true);
245 readBytes
= input
.read (data
, offset
, len
);
251 socket
.getPlainSocketImpl().setInChannelOperation(false);
257 dst
.position (dst
.position() + readBytes
);
261 dst
.put (data
, offset
, readBytes
);
267 public long read (ByteBuffer
[] dsts
, int offset
, int length
)
271 throw new NotYetConnectedException();
274 || (offset
> dsts
.length
)
276 || (length
> (dsts
.length
- offset
)))
277 throw new IndexOutOfBoundsException();
281 for (int index
= offset
; index
< length
; index
++)
282 readBytes
+= read (dsts
[index
]);
287 public int write (ByteBuffer src
)
291 throw new NotYetConnectedException();
295 int len
= src
.remaining();
299 data
= new byte [len
];
300 src
.get (data
, 0, len
);
304 offset
= src
.arrayOffset() + src
.position();
308 OutputStream output
= socket
.getOutputStream();
309 boolean completed
= false;
314 socket
.getPlainSocketImpl().setInChannelOperation(true);
315 output
.write (data
, offset
, len
);
321 socket
.getPlainSocketImpl().setInChannelOperation(false);
326 src
.position (src
.position() + len
);
332 public long write (ByteBuffer
[] srcs
, int offset
, int length
)
336 throw new NotYetConnectedException();
339 || (offset
> srcs
.length
)
341 || (length
> (srcs
.length
- offset
)))
342 throw new IndexOutOfBoundsException();
344 long writtenBytes
= 0;
346 for (int index
= offset
; index
< length
; index
++)
347 writtenBytes
+= write (srcs
[index
]);