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 java.util.Queue;
23
24 import org.apache.mina.core.buffer.IoBuffer;
25 import org.apache.mina.core.session.IoSession;
26 import org.apache.mina.filter.codec.ProtocolDecoder;
27 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
28 import org.apache.mina.util.CircularQueue;
29
30
31
32
33
34
35
36
37
38
39
40
41 public class DecodingStateProtocolDecoder implements ProtocolDecoder {
42 private final DecodingState state;
43 private final Queue<IoBuffer> undecodedBuffers = new CircularQueue<IoBuffer>();
44 private IoSession session;
45
46
47
48
49
50
51
52
53 public DecodingStateProtocolDecoder(DecodingState state) {
54 if (state == null) {
55 throw new NullPointerException("state");
56 }
57 this.state = state;
58 }
59
60
61
62
63 public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
64 throws Exception {
65 if (this.session == null) {
66 this.session = session;
67 } else if (this.session != session) {
68 throw new IllegalStateException(
69 getClass().getSimpleName() + " is a stateful decoder. " +
70 "You have to create one per session.");
71 }
72
73 undecodedBuffers.offer(in);
74 for (;;) {
75 IoBuffer b = undecodedBuffers.peek();
76 if (b == null) {
77 break;
78 }
79
80 int oldRemaining = b.remaining();
81 state.decode(b, out);
82 int newRemaining = b.remaining();
83 if (newRemaining != 0) {
84 if (oldRemaining == newRemaining) {
85 throw new IllegalStateException(
86 DecodingState.class.getSimpleName() + " must " +
87 "consume at least one byte per decode().");
88 }
89 } else {
90 undecodedBuffers.poll();
91 }
92 }
93 }
94
95
96
97
98 public void finishDecode(IoSession session, ProtocolDecoderOutput out)
99 throws Exception {
100 state.finishDecode(out);
101 }
102
103
104
105
106 public void dispose(IoSession session) throws Exception {}
107 }