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<CR><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 }