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.common.IoBuffer;
25 import org.apache.mina.common.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 public class DecodingStateProtocolDecoder implements ProtocolDecoder {
36 private final DecodingState state;
37 private final Queue<IoBuffer> undecodedBuffers = new CircularQueue<IoBuffer>();
38 private IoSession session;
39
40 public DecodingStateProtocolDecoder(DecodingState state) {
41 if (state == null) {
42 throw new NullPointerException("state");
43 }
44 this.state = state;
45 }
46
47 public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
48 throws Exception {
49 if (this.session == null) {
50 this.session = session;
51 } else if (this.session != session) {
52 throw new IllegalStateException(
53 getClass().getSimpleName() + " is a stateful decoder. " +
54 "You have to create one per session.");
55 }
56
57 undecodedBuffers.offer(in);
58 for (;;) {
59 IoBuffer b = undecodedBuffers.peek();
60 if (b == null) {
61 break;
62 }
63
64 int oldRemaining = b.remaining();
65 state.decode(b, out);
66 int newRemaining = b.remaining();
67 if (newRemaining != 0) {
68 if (oldRemaining == newRemaining) {
69 throw new IllegalStateException(
70 DecodingState.class.getSimpleName() + " must " +
71 "consume at least one byte per decode().");
72 }
73 return;
74 } else {
75 undecodedBuffers.poll();
76 }
77 }
78 }
79
80 public void finishDecode(IoSession session, ProtocolDecoderOutput out)
81 throws Exception {
82 state.finishDecode(out);
83 }
84
85 public void dispose(IoSession session) throws Exception {}
86 }