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 }