1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.codec.statemachine;
21
22 import org.apache.mina.core.buffer.IoBuffer;
23 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
24
25
26
27
28
29
30
31 public abstract class ConsumeToDynamicTerminatorDecodingState implements DecodingState {
32
33 private IoBuffer buffer;
34
35
36
37
38 @Override
39 public DecodingState decode(IoBuffer in, ProtocolDecoderOutput out) throws Exception {
40 int beginPos = in.position();
41 int terminatorPos = -1;
42 int limit = in.limit();
43
44 for (int i = beginPos; i < limit; i++) {
45 byte b = in.get(i);
46 if (isTerminator(b)) {
47 terminatorPos = i;
48 break;
49 }
50 }
51
52 if (terminatorPos >= 0) {
53 IoBuffer product;
54
55 if (beginPos < terminatorPos) {
56 in.limit(terminatorPos);
57
58 if (buffer == null) {
59 product = in.slice();
60 } else {
61 buffer.put(in);
62 product = buffer.flip();
63 buffer = null;
64 }
65
66 in.limit(limit);
67 } else {
68
69 if (buffer == null) {
70 product = IoBuffer.allocate(0);
71 } else {
72 product = buffer.flip();
73 buffer = null;
74 }
75 }
76 in.position(terminatorPos + 1);
77 return finishDecode(product, out);
78 }
79
80 if (buffer == null) {
81 buffer = IoBuffer.allocate(in.remaining());
82 buffer.setAutoExpand(true);
83 }
84 buffer.put(in);
85 return this;
86 }
87
88
89
90
91 @Override
92 public DecodingState finishDecode(ProtocolDecoderOutput out) throws Exception {
93 IoBuffer product;
94
95 if (buffer == null) {
96 product = IoBuffer.allocate(0);
97 } else {
98 product = buffer.flip();
99 buffer = null;
100 }
101 return finishDecode(product, out);
102 }
103
104
105
106
107
108
109
110
111 protected abstract boolean isTerminator(byte b);
112
113
114
115
116
117
118
119
120
121
122
123
124 protected abstract DecodingState finishDecode(IoBuffer product, ProtocolDecoderOutput out) throws Exception;
125 }