2 * jSite2 - FcpConnectionHandler.java -
3 * Copyright © 2008 David Roden
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 package net.pterodactylus.fcp;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.ByteBuffer;
25 import java.nio.charset.Charset;
28 * Handles an FCP connection to a node.
30 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
32 class FcpConnectionHandler implements Runnable {
34 /** The underlying connection. */
35 private final FcpConnection fcpConnection;
37 /** The input stream from the node. */
38 private final InputStream remoteInputStream;
40 /** Whether to stop the connection handler. */
41 private boolean shouldStop;
43 /** Whether the next read line feed should be ignored. */
44 private boolean ignoreNextLinefeed;
47 * Creates a new connection handler that operates on the given connection
50 * @param fcpConnection
51 * The underlying FCP connection
52 * @param remoteInputStream
53 * The input stream from the node
55 public FcpConnectionHandler(FcpConnection fcpConnection, InputStream remoteInputStream) {
56 this.fcpConnection = fcpConnection;
57 this.remoteInputStream = remoteInputStream;
64 FcpMessage fcpMessage = null;
65 Throwable throwable = null;
73 String line = readLine();
74 System.out.println("read line: " + line);
78 if (line.length() == 0) {
82 if (fcpMessage == null) {
83 fcpMessage = new FcpMessage(line);
86 if ("EndMessage".equalsIgnoreCase(line) || "Data".equalsIgnoreCase(line)) {
87 fcpConnection.handleMessage(fcpMessage);
90 int equalSign = line.indexOf('=');
91 if (equalSign == -1) {
92 /* something's fishy! */
95 String field = line.substring(0, equalSign);
96 String value = line.substring(equalSign + 1);
97 assert fcpMessage != null: "fcp message is null";
98 fcpMessage.setField(field, value);
99 } catch (IOException ioe1) {
104 fcpConnection.handleDisconnect(throwable);
108 * Stops the connection handler.
111 synchronized (this) {
121 * Reads bytes from {@link #remoteInputStream} until ‘\r’ or ‘\n’ are
122 * encountered and decodes the read bytes using UTF-8.
124 * @return The decoded line
125 * @throws IOException
126 * if an I/O error occurs
128 private String readLine() throws IOException {
129 byte[] readBytes = new byte[512];
132 int nextByte = remoteInputStream.read();
133 if (nextByte == -1) {
134 if (readIndex == 0) {
139 if (nextByte == 10) {
140 if (!ignoreNextLinefeed) {
144 ignoreNextLinefeed = false;
145 if (nextByte == 13) {
146 ignoreNextLinefeed = true;
149 if (readIndex == readBytes.length) {
150 /* recopy & enlarge array */
151 byte[] newReadBytes = new byte[readBytes.length * 2];
152 System.arraycopy(readBytes, 0, newReadBytes, 0, readBytes.length);
153 readBytes = newReadBytes;
155 readBytes[readIndex++] = (byte) nextByte;
157 ByteBuffer byteBuffer = ByteBuffer.wrap(readBytes, 0, readIndex);
158 return Charset.forName("UTF-8").decode(byteBuffer).toString();