Add DCC receiver.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 10 Apr 2013 04:46:27 +0000 (06:46 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 10 Apr 2013 04:46:27 +0000 (06:46 +0200)
src/main/java/net/pterodactylus/irc/DccReceiver.java [new file with mode: 0644]

diff --git a/src/main/java/net/pterodactylus/irc/DccReceiver.java b/src/main/java/net/pterodactylus/irc/DccReceiver.java
new file mode 100644 (file)
index 0000000..39f236c
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+
+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 <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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();
+               }
+       }
+
+}