diff options
Diffstat (limited to 'app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server')
-rw-r--r-- | app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt new file mode 100644 index 0000000..d7e5aed --- /dev/null +++ b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt @@ -0,0 +1,119 @@ +package xyz.brysonsteck.serverfordummies.server + +import java.io.*; +import java.net.*; +import java.util.*; + +class Download: Runnable { + public enum class Status { + DOWNLOADING, PAUSED, COMPLETE, CANCELLED, ERROR + } + public var size: Int + public var downloaded: Int + public var contentLength: Int + public var status: Status + + private final val MAX_BUFFER_SIZE: Number = 1024 + + private var url: URL + private var dir: String + + constructor (url: URL, dir: String) { + this.url = url + this.dir = dir + size = -1 + downloaded = 0 + status = Status.DOWNLOADING + contentLength = 1 + } + + public fun start() { + val thread = Thread(this) + thread.start() + } + + private fun getFilename(url: URL): String { + val filename = url.getFile() + return filename.substring(filename.lastIndexOf('/') + 1) + } + + override fun run() { + var stream: InputStream? = null + var file: RandomAccessFile? = null + + try { + // Open connection to URL. + var connection = url.openConnection() as HttpURLConnection; + + // Specify what portion of file to download. + connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); + + // Connect to server. + connection.connect(); + + // Make sure response code is in the 200 range. + if (connection.responseCode / 100 != 2) { + status = Status.ERROR + } + + // Check for valid content length. + contentLength = connection.getContentLength(); + if (contentLength < 1) { + status = Status.ERROR + } + + /* Set the size for this download if it + hasn't been already set. */ + if (size == -1) { + size = contentLength; + } + + // Open file and seek to the end of it. + file = RandomAccessFile(dir + getFilename(url), "rw"); + file.seek(downloaded.toLong()); + + stream = connection.getInputStream(); + while (status == Status.DOWNLOADING) { + /* Size buffer according to how much of the + file is left to download. */ + val buffer: ByteArray; + if (size - downloaded > MAX_BUFFER_SIZE as Int) { + buffer = ByteArray(MAX_BUFFER_SIZE) + } else { + buffer = ByteArray(size - downloaded); + } + + // Read from server into buffer. + val read = stream.read(buffer); + if (read == -1) + break; + + // Write buffer to file. + file.write(buffer, 0, read); + downloaded += read; + } + + /* Change status to complete if this point was + reached because downloading has finished. */ + if (status == Status.DOWNLOADING) { + status = Status.COMPLETE; + } + } catch (e: Exception) { + status = Status.ERROR + } finally { + // Close file. + if (file != null) { + try { + file.close(); + } catch (e: Exception) {} + } + + // Close connection to server. + if (stream != null) { + try { + stream.close(); + } catch (e: Exception) {} + } + } + } +} |