View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.codec.delimited;
    21
    22  import org.apache.mina.codec.IoBuffer;
    23  import org.apache.mina.codec.ProtocolDecoder;
    24
    25  /**
    26   *
    27   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    28   */
    29  public class SizePrefixedDecoder<OUT> implements ProtocolDecoder<IoBuffer, OUT, SizePrefixedDecoder.MutableInt> {
    30
    31      /**
    32       * A mutable {@link Integer} wrapper.
    33       *
    34       * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    35       *
    36       */
    37      protected static final class MutableInt {
    38
    39          private Integer value = null;
    40
    41          /**
    42           * Private constructor to avoid use of this class from other places.
    43           */
    44          private MutableInt() {
    45
    46          }
    47
    48          /**
    49           *
    50           * Gets the value as a Integer instance.
    51           *
    52           * @return the value as a Integer.
    53           */
    54          public Integer getValue() {
    55              return value;
    56          }
    57
    58          /**
    59           * Returns the existence (or not) of an integer in this mutable.
    60           *
    61           * @return true if it contains a value, false otherwise.
    62           */
    63          public boolean isDefined() {
    64              return value != null;
    65          }
    66
    67          /**
    68           * Remove the value.
    69           */
    70          public void reset() {
    71              value = null;
    72          }
    73
    74          /**
    75           * Set the value.
    76           *
    77           * @param value
    78           *            the value to set
    79           */
    80          public void setValue(Integer value) {
    81              this.value = value;
    82          }
    83      }
    84
    85      private final IoBufferDecoder<Integer> sizeDecoder;
    86
    87      private final IoBufferDecoder<OUT> payloadDecoder;
    88
    89      public SizePrefixedDecoder(IoBufferDecoder<Integer> sizeDecoder, IoBufferDecoder<OUT> payloadDecoder) {
    90          super();
    91          this.sizeDecoder = sizeDecoder;
    92          this.payloadDecoder = payloadDecoder;
    93      }
    94
    95      @Override
    96      public MutableInt createDecoderState() {
    97
    98          return new MutableInt();
    99      }
    100
    101     @Override
    102     public OUT decode(IoBuffer input, MutableInt nextBlockSize) {
    103         OUT output = null;
    104
    105         if (nextBlockSize.getValue() == null) {
    106             nextBlockSize.setValue(sizeDecoder.decode(input));
    107         }
    108
    109         if (nextBlockSize.isDefined() && (input.remaining() >= nextBlockSize.getValue())) {
    110             IoBuffer buffer = input.slice();
    111             buffer.limit(buffer.position() + nextBlockSize.getValue());
    112
    113             output = payloadDecoder.decode(buffer);
    114             nextBlockSize.reset();
    115         }
    116
    117         return output;
    118     }
    119
    120     @Override
    121     public void finishDecode(MutableInt context) {
    122         //
    123     }
    124 }