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 }