import kotlin.random.Random /** * Generate tags for 9P messages. */ class TagGenerator(val method: TagGenerationMethod, val initial: UShort) { private var current: UShort = initial private val rng: Random = Random(initial.toInt()) private val randomReturned: Set = emptySet() private val generationFunctions: Map UShort> = mapOf( TagGenerationMethod.INCREMENTAL to this::generateIncremental, TagGenerationMethod.RANDOM to this::generateRandom, TagGenerationMethod.RANDOM_CHECKED to this::generateRandomChecked ) /** * How are tags generated? */ enum class TagGenerationMethod { /** * Return the initial value on the first generation. Increment the value on each generation. */ INCREMENTAL, /** * Use the initial value as a seed and generate random values from it. */ RANDOM, /** * Same as [RANDOM], but checks are added to avoid generating the same value twice. */ RANDOM_CHECKED, } /** * Generate a new tag. */ fun generate(): UShort { return this.generationFunctions.getValue(method).invoke() } private fun generateIncremental(): UShort { val tmp = this.current this.current++ return tmp } private fun generateRandom(): UShort { return this.rng.nextBits(16).toUShort() } private fun generateRandomChecked(): UShort { var v: UShort do { v = generateRandom() } while (v in randomReturned) randomReturned.plus(v) return v } }