1 | /* |
2 | * @(#) $Id: AbstractMessageDecoder.java 264677 2005-08-30 02:44:35Z trustin $ |
3 | * |
4 | * Copyright 2004 The Apache Software Foundation |
5 | * |
6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
7 | * you may not use this file except in compliance with the License. |
8 | * 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, software |
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | * See the License for the specific language governing permissions and |
16 | * limitations under the License. |
17 | * |
18 | */ |
19 | package org.apache.mina.examples.sumup.codec; |
20 | |
21 | import org.apache.mina.common.ByteBuffer; |
22 | import org.apache.mina.examples.sumup.message.AbstractMessage; |
23 | import org.apache.mina.protocol.ProtocolDecoderOutput; |
24 | import org.apache.mina.protocol.ProtocolSession; |
25 | import org.apache.mina.protocol.ProtocolViolationException; |
26 | import org.apache.mina.protocol.codec.MessageDecoder; |
27 | import org.apache.mina.protocol.codec.MessageDecoderResult; |
28 | |
29 | /** |
30 | * A {@link MessageDecoder} that decodes message header and forwards |
31 | * the decoding of body to a subclass. |
32 | * |
33 | * @author The Apache Directory Project |
34 | * @version $Rev: 264677 $, $Date: 2005-08-30 11:44:35 +0900 $ |
35 | */ |
36 | public abstract class AbstractMessageDecoder implements MessageDecoder |
37 | { |
38 | private final int type; |
39 | |
40 | private int sequence; |
41 | private boolean readHeader; |
42 | |
43 | protected AbstractMessageDecoder( int type ) |
44 | { |
45 | this.type = type; |
46 | } |
47 | |
48 | public MessageDecoderResult decodable( ProtocolSession session, ByteBuffer in ) |
49 | { |
50 | // Return NEED_DATA if the whole header is not read yet. |
51 | if( in.remaining() < Constants.HEADER_LEN ) |
52 | { |
53 | return MessageDecoderResult.NEED_DATA; |
54 | } |
55 | |
56 | // Return OK if type and bodyLength matches. |
57 | if( type == in.getShort() ) |
58 | { |
59 | return MessageDecoderResult.OK; |
60 | } |
61 | |
62 | // Return NOT_OK if not matches. |
63 | return MessageDecoderResult.NOT_OK; |
64 | } |
65 | |
66 | public MessageDecoderResult decode( ProtocolSession session, ByteBuffer in, ProtocolDecoderOutput out ) throws ProtocolViolationException |
67 | { |
68 | // Try to skip header if not read. |
69 | if( !readHeader ) |
70 | { |
71 | in.getShort(); // Skip 'type'. |
72 | sequence = in.getInt(); // Get 'sequence'. |
73 | readHeader = true; |
74 | } |
75 | |
76 | // Try to decode body |
77 | AbstractMessage m = decodeBody( session, in ); |
78 | // Return NEED_DATA if the body is not fully read. |
79 | if( m == null ) |
80 | { |
81 | return MessageDecoderResult.NEED_DATA; |
82 | } |
83 | else |
84 | { |
85 | readHeader = false; // reset readHeader for the next decode |
86 | } |
87 | m.setSequence( sequence ); |
88 | out.write( m ); |
89 | |
90 | return MessageDecoderResult.OK; |
91 | } |
92 | |
93 | /** |
94 | * @return <tt>null</tt> if the whole body is not read yet |
95 | */ |
96 | protected abstract AbstractMessage decodeBody( ProtocolSession session, ByteBuffer in ); |
97 | } |