View Javadoc

1   /*
2    *  Copyright 2006 Simon Raess
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package net.sf.beep4j.internal;
17  
18  import java.nio.ByteBuffer;
19  import java.nio.charset.Charset;
20  
21  import net.sf.beep4j.ProtocolException;
22  
23  /**
24   * ParseState that expects a valid trailer. A BEEP trailer consists of
25   * the following character sequence:
26   * 
27   * <pre>
28   *   END&lt;CR>&lt;LF>
29   * </pre>
30   * 
31   * If the characters at the current position do not consist of that sequence
32   * then the BEEP peers have lost synchronization.
33   * 
34   * @author Simon Raess
35   */
36  final class TrailerState implements ParseState {
37  	
38  	private static final String TRAILER = "END\r\n";
39  
40  	private ByteBuffer tmp = ByteBuffer.allocate(5);
41  	
42  	public boolean process(ByteBuffer buffer, ParseStateContext context) {
43  		if (tmp.capacity() - tmp.remaining() + buffer.remaining() >= 5) {
44  			int remaining = tmp.remaining();
45  			
46  			// get the next five characters encoded in US-ASCII
47  			Charset charset = Charset.forName("US-ASCII");
48  			ByteBuffer copy = buffer.asReadOnlyBuffer();
49  			copy.limit(copy.position() + remaining);
50  			tmp.put(copy);
51  			tmp.flip();
52  			
53  			String trailer = charset.decode(tmp).toString();
54  				
55  			if (!TRAILER.equals(trailer)) {
56  				throw new ProtocolException("expected 'END\\r\\n' (was '" + trailer + "'");
57  			}
58  			
59  			// move the position past the header
60  			buffer.position(buffer.position() + remaining);
61  			
62  			// and clear the temporary buffer
63  			tmp.clear();
64  			
65  			context.handleTrailer();
66  			return buffer.hasRemaining();
67  			
68  		} else {
69  			tmp.put(buffer);
70  		}
71  
72  		return false;
73  	}
74  }