summaryrefslogtreecommitdiff
path: root/src/main/kotlin/NinePConnection.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/NinePConnection.kt')
-rw-r--r--src/main/kotlin/NinePConnection.kt76
1 files changed, 2 insertions, 74 deletions
diff --git a/src/main/kotlin/NinePConnection.kt b/src/main/kotlin/NinePConnection.kt
index b23fd1f..7f52ad5 100644
--- a/src/main/kotlin/NinePConnection.kt
+++ b/src/main/kotlin/NinePConnection.kt
@@ -1,6 +1,5 @@
import java.io.IOException
import java.math.BigInteger
-import kotlin.math.pow
/**
* This class represents a 9P connection. It provides a practical implementation with networking to the 9P methods
@@ -118,86 +117,15 @@ class NinePConnection(netPackTrans: NetworkPacketTransporter) : NinePTranslator
return Pair(SizedMessageField(2, tag), error)
}
- /**
- * Write an integer number to the connection.
- *
- * In 9P, binary numbers (non-textual) are specified in little-endian order (least significant byte first).
- *
- * @param value The number's value. [SizedMessageField] defines both its actual value and its size.
- */
- private fun writeInteger(value: SizedMessageField) {
- this.npt.transmit(value.value.toByteArray().toList())
- }
-
- /**
- * Write a string to the connection.
- *
- * In 9P, strings are represented as a 2-byte integer (the string's size) followed by the actual UTF-8 string. The
- * null terminator is forbidden in 9P messages.
- *
- * @param value The string.
- * @throws IllegalArgumentException if the value of the string's size does not fit into 2 bytes.
- */
- private fun writeString(value: String) {
- require(value.length <= 2.0.pow(16.0) - 1)
- writeInteger(SizedMessageField(2, value.length.toBigInteger()))
- this.npt.transmit(value.toByteArray().toList())
- }
-
- /**
- * Write the message size and type.
- *
- * @param size The total message size, including the 4 bytes of this parameter and the type's byte.
- * @param type The 9P message type as a [NinePMessageType] constant.
- */
- private fun writeMessageSizeType(size: Int, type: NinePMessageType) {
- writeInteger(SizedMessageField(4, size.toBigInteger()))
- writeInteger(SizedMessageField(1, type.value.toInt().toBigInteger()))
- }
-
- /**
- * Write a message with the given type, tag, and fields. The message size is calculated automatically.
- *
- * Important note: the field names in [fieldValuesInt] and [fieldValuesStr] (i.e. the keys of their maps) must be
- * mutually exclusive and the union of these two maps' keys must result in a subset of (or a set equal to)
- * [fieldNames].
- *
- * @param type The 9P message type.
- * @param tag The tag given to the message.
- * @param fieldNames The names of the message fields, in the same order they are expected to be sent.
- * @param fieldValuesInt A map of each field name into its value. This map only stores integer values.
- * @param fieldValuesStr A map of each field name into its value. This map only stores string values.
- * @throws IllegalArgumentException if [fieldNames], [fieldValuesInt], and [fieldValuesStr] are incoherent.
- */
- private fun writeMessage(type: NinePMessageType, tag: UShort, fieldNames: List<String>, fieldValuesInt: Map<String, SizedMessageField>, fieldValuesStr: Map<String, String>) {
- // shorthands
- val insecInts = fieldNames.intersect(fieldValuesInt.keys)
- val insecStrs = fieldNames.intersect(fieldValuesStr.keys)
- // check that names in fieldNames exist as keys in either fieldValuesInt or fieldValuesStr but not both
- require(insecInts.size == fieldNames.size - insecStrs.size)
-
- val totalSize = 4 + 1 + 2 + insecInts.sumOf { fieldValuesInt[it]!!.size } + insecStrs.sumOf { 2 + fieldValuesStr[it]!!.length }
-
- writeMessageSizeType(totalSize, type)
- writeInteger(SizedMessageField(2, tag.toInt().toBigInteger()))
- for (field in fieldNames) {
- if (field in insecInts) {
- writeInteger(fieldValuesInt[field]!!)
- } else {
- writeString(fieldValuesStr[field]!!)
- }
- }
- }
-
override fun version(msize: SizedMessageField, version: String): String? {
- writeMessage(NinePMessageType.TVERSION, this.NOTAG, listOf("msize", "version"),
+ NinePMessage(NinePMessageType.TVERSION, this.NOTAG, listOf("msize", "version"),
mapOf(
"msize" to msize
),
mapOf(
"version" to version
)
- )
+ ).write(this.npt)
val se = waitForTag(this.NOTAG)
if (se.second == NinePMessageType.RERROR) {
val error = readError()