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 ConsumeToTerminatorDecodingState implements DecodingState {
33
34 private final byte terminator;
35
36 private IoBuffer buffer;
37
38
39
40
41 public ConsumeToTerminatorDecodingState(byte terminator) {
42 this.terminator = terminator;
43 }
44
45 public DecodingState decode(IoBuffer in, ProtocolDecoderOutput out)
46 throws Exception {
47 int terminatorPos = in.indexOf(terminator);
48
49 if (terminatorPos >= 0) {
50 int limit = in.limit();
51 IoBuffer product;
52
53 if (in.position() < terminatorPos) {
54 in.limit(terminatorPos);
55
56 if (buffer == null) {
57 product = in.slice();
58 } else {
59 buffer.put(in);
60 product = buffer.flip();
61 buffer = null;
62 }
63
64 in.limit(limit);
65 } else {
66
67 if (buffer == null) {
68 product = IoBuffer.allocate(0);
69 } else {
70 product = buffer.flip();
71 buffer = null;
72 }
73 }
74 in.position(terminatorPos + 1);
75 return finishDecode(product, out);
76 } else {
77 if (buffer == null) {
78 buffer = IoBuffer.allocate(in.remaining());
79 buffer.setAutoExpand(true);
80 }
81 buffer.put(in);
82 return this;
83 }
84 }
85
86 public DecodingState finishDecode(ProtocolDecoderOutput out)
87 throws Exception {
88 IoBuffer product;
89
90 if (buffer == null) {
91 product = IoBuffer.allocate(0);
92 } else {
93 product = buffer.flip();
94 buffer = null;
95 }
96 return finishDecode(product, out);
97 }
98
99 protected abstract DecodingState finishDecode(IoBuffer product,
100 ProtocolDecoderOutput out) throws Exception;
101 }