PacketAggregatingSynchChannel xref

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  package org.activeio.filter;
    18
    19  import java.io.IOException;
    20  import java.util.LinkedList;
    21
    22  import org.activeio.FilterSynchChannel;
    23  import org.activeio.Packet;
    24  import org.activeio.SynchChannel;
    25
    26  /***
    27   * This PacketAggregatingSynchChannel can be used when the client is sending a
    28   * 'record' style packet down the channel stack and needs receiving end to
    29   * receive the same 'record' packets.
    30   *
    31   * This is very usefull since in general, a channel does not garantee that a
    32   * Packet that is sent down will not be fragmented or combined with other Packet
    33   * objects.
    34   *
    35   * This {@see org.activeio.SynchChannel} adds a 4 byte header
    36   * to each packet that is sent down.
    37   *
    38   * @version $Revision$
    39   */
    40  final public class PacketAggregatingSynchChannel extends FilterSynchChannel {
    41
    42      private final LinkedList assembledPackets = new LinkedList();
    43      private final PacketAggregator aggregator = new PacketAggregator() {
    44          protected void packetAssembled(Packet packet) {
    45              assembledPackets.addLast(packet);
    46          }
    47      };
    48
    49      /***
    50       * @param next
    51       */
    52      public PacketAggregatingSynchChannel(SynchChannel next) {
    53          super(next);
    54      }
    55
    56      public Packet read(long timeout) throws IOException {
    57          long start = System.currentTimeMillis();
    58          if( assembledPackets.isEmpty() ) {
    59              while( true ) {
    60
    61  	            Packet packet = getNext().read(timeout);
    62  	            if( packet==null ) {
    63                      return null;
    64  	            }
    65
    66  	            aggregator.addRawPacket(packet);
    67
    68  	            // Should we try to get more packets?
    69  	            if( assembledPackets.isEmpty() ) {
    70  	                if( timeout == WAIT_FOREVER_TIMEOUT )
    71  	                    continue;
    72
    73  	                timeout = Math.max(0, timeout-(System.currentTimeMillis()-start));
    74  	                if( timeout != 0 )
    75  	                    continue;
    76
    77  	                return null;
    78  	            } else {
    79  	                return (Packet) assembledPackets.removeFirst();
    80  	            }
    81              }
    82
    83          } else {
    84              return (Packet) assembledPackets.removeFirst();
    85          }
    86
    87      }
    88
    89      public void write(Packet packet) throws IOException {
    90          getNext().write(aggregator.getHeader(packet));
    91          getNext().write(packet);
    92      }
    93  }