diff options
-rw-r--r-- | src/main/kotlin/OutMessage.kt | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/main/kotlin/OutMessage.kt b/src/main/kotlin/OutMessage.kt index dcb3705..61805cb 100644 --- a/src/main/kotlin/OutMessage.kt +++ b/src/main/kotlin/OutMessage.kt @@ -4,9 +4,9 @@ import kotlin.math.pow /** * An outgoing 9P 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]. - * Calling [write] when these conditions are not met throws an exception. + * Important note: the field names in [fieldValuesInt], [fieldValuesStr], and [fieldValuesRaw] (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]. Calling [write] when these conditions are not met throws an exception. * * @param type The 9P message type. * @param tag The tag given to the message. @@ -14,12 +14,13 @@ import kotlin.math.pow * @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. */ -class OutMessage(val type: NinePMessageType, val tag: UShort, val fieldNames: List<String>, val fieldValuesInt: Map<String, BigInteger>, val fieldValuesStr: Map<String, String>, val maxSize: UInt) { +class OutMessage(val type: NinePMessageType, val tag: UShort, val fieldNames: List<String>, val fieldValuesInt: Map<String, BigInteger>, val fieldValuesStr: Map<String, String>, val fieldValuesRaw: Map<String, Array<UByte>>, val maxSize: UInt) { /** * Intersection between [fieldNames] and [fieldValuesInt]. In other words: the amount of integer fields that are * going to be used when writing the message. */ private val insecInts = fieldNames.intersect(fieldValuesInt.keys) + /** * Intersection between [fieldNames] and [fieldValuesStr]. In other words: the amount of string fields that are * going to be used when writing the message. @@ -27,6 +28,12 @@ class OutMessage(val type: NinePMessageType, val tag: UShort, val fieldNames: Li private val insecStrs = fieldNames.intersect(fieldValuesStr.keys) /** + * Intersection between [fieldNames] and [fieldValuesRaw]. In other words: the raw fields that are going to be used + * when writing the message. + */ + private val insecRaws = fieldNames.intersect(fieldValuesRaw.keys) + + /** * Send the message using the given networking API. * * @param tl The networking API. @@ -35,7 +42,7 @@ class OutMessage(val type: NinePMessageType, val tag: UShort, val fieldNames: Li */ fun write(tl: TransportLayer) { // check that names in fieldNames exist as keys in either fieldValuesInt or fieldValuesStr but not both - require(insecInts.size == fieldNames.size - insecStrs.size) + require(fieldNames.size == insecInts.size + insecStrs.size + insecRaws.size) val totalSize = size() if (totalSize > this.maxSize) { @@ -46,8 +53,10 @@ class OutMessage(val type: NinePMessageType, val tag: UShort, val fieldNames: Li for (field in fieldNames) { if (field in insecInts) { writeInteger(tl, fieldValuesInt[field]!!) - } else { + } else if (field in insecStrs) { writeString(tl, fieldValuesStr[field]!!) + } else { + tl.transmit(fieldValuesRaw[field]!!) } } } @@ -99,6 +108,6 @@ class OutMessage(val type: NinePMessageType, val tag: UShort, val fieldNames: Li * Calculate the expected size of the message. */ fun size(): UInt { - return 4u + 1u + 2u + this.insecInts.sumOf { this.fieldValuesInt[it]!!.bitLength().toUInt() } + this.insecStrs.sumOf { 2u + this.fieldValuesStr[it]!!.length.toUInt() } + return 4u + 1u + 2u + this.insecInts.sumOf { this.fieldValuesInt[it]!!.bitLength().toUInt() } + this.insecStrs.sumOf { 2u + this.fieldValuesStr[it]!!.length.toUInt() } + this.insecRaws.sumOf { this.fieldValuesRaw[it]!!.size.toUInt() } } }
\ No newline at end of file |