1 /***
2 *
3 * Copyright 2004 Hiram Chirino
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18
19 package org.activeio.net;
20
21 import java.io.IOException;
22 import java.net.SocketTimeoutException;
23 import java.nio.ByteBuffer;
24 import java.nio.channels.SocketChannel;
25
26 import org.activeio.Packet;
27 import org.activeio.SynchChannel;
28 import org.activeio.SynchChannelServer;
29 import org.activeio.Packet.ByteSequence;
30 import org.activeio.packet.ByteBufferPacket;
31 import org.activeio.packet.EOSPacket;
32 import org.activeio.packet.EmptyPacket;
33
34 /***
35 * A {@see org.activeio.SynchChannel} implementation that uses a {@see java.nio.channels.SocketChannel}
36 * to talk to the network.
37 *
38 * Using a SocketChannelSynchChannel should be more efficient than using a SocketSynchChannel since
39 * direct ByteBuffer can be used to reduce the jvm overhead needed to copy byte[]s.
40 *
41 * @version $Revision$
42 */
43 final public class NIOSynchChannel extends NIOBaseChannel implements SynchChannel {
44
45 private ByteBuffer inputByteBuffer;
46
47
48 protected NIOSynchChannel(SocketChannel socketChannel) throws IOException {
49 this(socketChannel, true );
50 }
51
52 protected NIOSynchChannel(SocketChannel socketChannel, boolean useDirect) throws IOException {
53 super(socketChannel, useDirect);
54 }
55
56 public Packet read(long timeout) throws IOException {
57 try {
58
59 if( timeout==SynchChannelServer.WAIT_FOREVER_TIMEOUT )
60 setSoTimeout( 0 );
61 else if( timeout==SynchChannelServer.NO_WAIT_TIMEOUT )
62 setSoTimeout( 1 );
63 else
64 setSoTimeout( (int)timeout );
65
66 if( inputByteBuffer==null || !inputByteBuffer.hasRemaining() ) {
67 inputByteBuffer = allocateBuffer();
68 }
69
70 int size = socketChannel.read(inputByteBuffer);
71 if( size == -1 )
72 return EOSPacket.EOS_PACKET;
73 if( size == 0 )
74 return EmptyPacket.EMPTY_PACKET;
75
76 ByteBuffer remaining = inputByteBuffer.slice();
77 Packet data = new ByteBufferPacket(((ByteBuffer)inputByteBuffer.flip()).slice());
78
79
80 inputByteBuffer = remaining;
81 return data;
82
83 } catch (SocketTimeoutException e) {
84 return null;
85 }
86 }
87
88 public void write(Packet packet) throws IOException {
89 ByteBuffer data;
90 if( packet.getClass()==ByteBufferPacket.class ) {
91 data = ((ByteBufferPacket)packet).getByteBuffer();
92 } else {
93 ByteSequence sequence = packet.asByteSequence();
94 data = ByteBuffer.wrap(sequence.getData(), sequence.getOffset(), sequence.getLength());
95 }
96 socketChannel.write( data );
97 }
98
99 public void start() throws IOException {
100 }
101
102 public void stop(long timeout) throws IOException {
103 }
104
105 }