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  
20  /**
21   * ParseState responsible to read the payload of a frame.
22   * 
23   * @author Simon Raess
24   */
25  final class PayloadState implements ParseState {
26  	
27  	/**
28  	 * The number of bytes to read.
29  	 */
30  	private int size;
31  	
32  	/**
33  	 * The current position. This number specifies how many bytes
34  	 * have already been read.
35  	 */
36  	private int position;
37  	
38  	/**
39  	 * Holds the read payload.
40  	 */
41  	private ByteBuffer payload;
42  	
43  	/**
44  	 * Creates a new PayloadState that reads exactly <var>payloadSize</var> 
45  	 * bytes from the incoming buffers.
46  	 * 
47  	 * @param payloadSize the number of bytes in the payload
48  	 */
49  	PayloadState(int payloadSize) {
50  		this.position = 0;
51  		this.size = payloadSize;
52  		this.payload = ByteBuffer.allocate(payloadSize);
53  	}
54  	
55  	public final boolean process(ByteBuffer buffer, ParseStateContext context) {
56  		// calculate the number of bytes to be read
57  		int available = buffer.remaining();
58  		int remaining = size - position;
59  		int actual = Math.min(available, remaining);
60  		
61  		// write actual number of bytes to the payload buffer
62  		int limit = buffer.limit();
63  		buffer.limit(buffer.position() + actual);
64  		payload.put(buffer);
65  		buffer.limit(limit);
66  		
67  		// update the position
68  		position += actual;
69  		
70  		// have we read enough?
71  		if (position == size) {
72  			payload.flip();			
73  			context.handlePayload(payload);
74  			return buffer.hasRemaining();
75  		}
76  		
77  		return false;
78  	}
79  	
80  }