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.common.IoBuffer;
23 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
24
25
26
27
28
29
30
31
32 public abstract class ConsumeToDynamicTerminatorDecodingState implements
33 DecodingState {
34
35 private IoBuffer buffer;
36
37
38
39
40 public ConsumeToDynamicTerminatorDecodingState() {
41 }
42
43 public DecodingState decode(IoBuffer in, ProtocolDecoderOutput out)
44 throws Exception {
45 int beginPos = in.position();
46 int terminatorPos = -1;
47 int limit = in.limit();
48
49 for (int i = beginPos; i < limit; i++) {
50 byte b = in.get(i);
51 if (isTerminator(b)) {
52 terminatorPos = i;
53 break;
54 }
55 }
56
57 if (terminatorPos >= 0) {
58 IoBuffer product;
59
60 if (beginPos < terminatorPos) {
61 in.limit(terminatorPos);
62
63 if (buffer == null) {
64 product = in.slice();
65 } else {
66 buffer.put(in);
67 product = buffer.flip();
68 buffer = null;
69 }
70
71 in.limit(limit);
72 } else {
73
74 if (buffer == null) {
75 product = IoBuffer.allocate(0);
76 } else {
77 product = buffer.flip();
78 buffer = null;
79 }
80 }
81 in.position(terminatorPos + 1);
82 return finishDecode(product, out);
83 } else {
84 if (buffer == null) {
85 buffer = IoBuffer.allocate(in.remaining());
86 buffer.setAutoExpand(true);
87 }
88 buffer.put(in);
89 return this;
90 }
91 }
92
93 public DecodingState finishDecode(ProtocolDecoderOutput out)
94 throws Exception {
95 IoBuffer product;
96
97 if (buffer == null) {
98 product = IoBuffer.allocate(0);
99 } else {
100 product = buffer.flip();
101 buffer = null;
102 }
103 return finishDecode(product, out);
104 }
105
106 protected abstract boolean isTerminator(byte b);
107
108 protected abstract DecodingState finishDecode(IoBuffer product,
109 ProtocolDecoderOutput out) throws Exception;
110 }