View Javadoc

    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  //    private Packet data2;
    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              // Keep the remaining buffer around to fill with data.
    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 }