01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one
03: * or more contributor license agreements. See the NOTICE file
04: * distributed with this work for additional information
05: * regarding copyright ownership. The ASF licenses this file
06: * to you under the Apache License, Version 2.0 (the
07: * "License"); you may not use this file except in compliance
08: * with the License. You may obtain a copy of the License at
09: *
10: * http://www.apache.org/licenses/LICENSE-2.0
11: *
12: * Unless required by applicable law or agreed to in writing,
13: * software distributed under the License is distributed on an
14: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15: * KIND, either express or implied. See the License for the
16: * specific language governing permissions and limitations
17: * under the License.
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.ProtocolDecoderException;
24: import org.apache.mina.filter.codec.ProtocolDecoderOutput;
25:
26: /**
27: * Decodes a single <code>CRLF</code>.
28: * If it is found, the bytes are consumed and <code>Boolean.TRUE</code>
29: * is provided as the product. Otherwise, read bytes are pushed back
30: * to the stream, and <code>Boolean.FALSE</code> is provided as the
31: * product.
32: * Note that if we find a CR but do not find a following LF, we raise
33: * an error.
34: *
35: * @author The Apache MINA Project (dev@mina.apache.org)
36: * @version $Rev: 601994 $, $Date: 2007-12-06 21:58:00 -0700 (Thu, 06 Dec 2007) $
37: */
38: public abstract class CrLfDecodingState implements DecodingState {
39: /**
40: * Carriage return character
41: */
42: private static final byte CR = 13;
43:
44: /**
45: * Line feed character
46: */
47: private static final byte LF = 10;
48:
49: private boolean hasCR;
50:
51: public DecodingState decode(IoBuffer in, ProtocolDecoderOutput out)
52: throws Exception {
53: boolean found = false;
54: boolean finished = false;
55: while (in.hasRemaining()) {
56: byte b = in.get();
57: if (!hasCR) {
58: if (b == CR) {
59: hasCR = true;
60: } else {
61: if (b == LF) {
62: found = true;
63: } else {
64: in.position(in.position() - 1);
65: found = false;
66: }
67: finished = true;
68: break;
69: }
70: } else {
71: if (b == LF) {
72: found = true;
73: finished = true;
74: break;
75: } else {
76: throw new ProtocolDecoderException(
77: "Expected LF after CR but was: "
78: + (b & 0xff));
79: }
80: }
81: }
82:
83: if (finished) {
84: hasCR = false;
85: return finishDecode(found, out);
86: } else {
87: return this ;
88: }
89: }
90:
91: public DecodingState finishDecode(ProtocolDecoderOutput out)
92: throws Exception {
93: return finishDecode(false, out);
94: }
95:
96: protected abstract DecodingState finishDecode(boolean foundCRLF,
97: ProtocolDecoderOutput out) throws Exception;
98: }
|