View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
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.ProtocolDecoderOutput;
24  
25  /**
26   * Consumes until a fixed (ASCII) character is reached.
27   * The terminator is skipped.
28   *
29   * @author The Apache MINA Project (dev@mina.apache.org)
30   * @version $Rev: 601994 $, $Date: 2007-12-06 21:58:00 -0700 (Thu, 06 Dec 2007) $
31   */
32  public abstract class ConsumeToTerminatorDecodingState implements DecodingState {
33  
34      private final byte terminator;
35  
36      private IoBuffer buffer;
37  
38      /**
39       * @param terminator  The terminator character
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                  // When input contained only terminator rather than actual data...
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          // When input contained only terminator rather than actual data...
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 }