From ff559fd198d827de652e57b64e41bc85eccd537b Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Wed, 10 Apr 2013 06:46:27 +0200 Subject: [PATCH] Add DCC receiver. --- .../java/net/pterodactylus/irc/DccReceiver.java | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/main/java/net/pterodactylus/irc/DccReceiver.java diff --git a/src/main/java/net/pterodactylus/irc/DccReceiver.java b/src/main/java/net/pterodactylus/irc/DccReceiver.java new file mode 100644 index 0000000..39f236c --- /dev/null +++ b/src/main/java/net/pterodactylus/irc/DccReceiver.java @@ -0,0 +1,144 @@ +/* + * XdccDownloader - DccReceiver.java - Copyright © 2013 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.irc; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.pterodactylus.irc.event.DccSendReceived; + +import com.google.common.util.concurrent.AbstractExecutionThreadService; + +/** + * Service that receives a file offered by a {@link DccSendReceived}. + * + * @author David ‘Bombe’ Roden + */ +public class DccReceiver extends AbstractExecutionThreadService { + + /** The logger. */ + private static final Logger logger = Logger.getLogger(DccReceiver.class.getName()); + + /** The address to connect to. */ + private final InetAddress inetAddress; + + /** The port number to connect to. */ + private final int port; + + /** The name of the file being offered. */ + private final String filename; + + /** The size of the file being offered. */ + private final long size; + + /** The output stream to write the file to. */ + private final OutputStream outputStream; + + /** The number of bytes already written. */ + private long progress; + + /** + * Creates a new DCC receiver. + * + * @param inetAddress + * The address to connect to + * @param port + * The port number to connect to + * @param filename + * The name of the file being downloaded + * @param size + * The size of the file being downloaded, or {@code -1} if the size is not + * known + * @param outputStream + * The output stream to write the file to + */ + public DccReceiver(InetAddress inetAddress, int port, String filename, long size, OutputStream outputStream) { + this.inetAddress = inetAddress; + this.port = port; + this.filename = filename; + this.size = size; + this.outputStream = outputStream; + } + + // + // ACCESSORS + // + + /** + * Returns the name of the file being downloaded. The name is not used by the + * DCC receiver, it only serves as a kind of identifier. + * + * @return The name of the file being downloaded + */ + public String filename() { + return filename; + } + + /** + * Returns the size of the file being downloaded. If the size of the file is + * not known, {@code -1} is returned. + * + * @return The size of the file being downloaded, or {@code -1} if the size is + * not known + */ + public long size() { + return size; + } + + /** + * Returns the number of bytes that have already been downloaded. + * + * @return The number of bytes that have already been downloaded + */ + public long progress() { + return progress; + } + + // + // ABSTRACTEXECUTIONTHREADSERVICE METHODS + // + + @Override + protected void run() throws Exception { + Socket socket = null; + try { + socket = new Socket(inetAddress, port); + InputStream socketInputStream = socket.getInputStream(); + byte[] buffer = new byte[65536]; + while (true) { + int r = socketInputStream.read(buffer); + if (r == -1) { + /* yay, eof! */ + break; + } + outputStream.write(buffer, 0, r); + progress += r; + } + } catch (IOException ioe1) { + logger.log(Level.WARNING, "I/O error while receiving DCC!", ioe1); + } finally { + socket.close(); + } + } + +} -- 2.7.4