import java.io.InputStream import java.io.OutputStream import java.net.Socket import kotlin.math.min /* TODO: - add TLS support */ /** * An implementation of [NetworkPacketTransporter] written using the [java.net] package. */ class NetworkPacketTransporterJavaNet : NetworkPacketTransporter { /** * The connection's socket. */ private val socket: Socket = Socket(address, port.toInt()) /** * The connection's input stream. */ private val inStream: InputStream = this.socket.inputStream /** * The connection's output stream. */ private val outStream: OutputStream = this.socket.outputStream constructor(address: String, port: UShort) : super(address, port) constructor(fullAddress: String) : super(fullAddress) override fun close() { if (this.socket.isClosed) { return } this.socket.close() } override fun transmit(payload: Array) { val bytes = ByteArray(payload.size) { i -> payload[i].toByte() } this.outStream.write(bytes) } /* override fun receiveUntil(untilByte: UByte): Array { var stop = false val payload: Array = MutableList(0, { 0 }) while (!stop) { val b = this.inStream.readNBytes(1)[0] if (b == untilByte) { stop = true continue } else { payload.add(b) } } return payload } */ override fun receive(length: ULong): Array { var length = length val intMax = Int.MAX_VALUE.toULong() val bytes: MutableList = MutableList(0) { 0 } // readNBytes only takes Int values, so it must be called multiple times if the length is greater than Int's // maximum value while (length > 0u) { // the min function ensures that the value passed to readNBytes never exceeds Int's maximum value while also // switching to the length variable when its value eventually becomes less than Int's maximum value, which // avoids writing duplicated readNBytes calls in the code val lenMin = min(length, intMax) bytes += this.inStream.readNBytes(lenMin.toInt()).toMutableList() length -= intMax } return Array(bytes.size) { i -> bytes[i].toUByte() } } }