import net.InMessage import net.OutMessage import java.math.BigInteger /** * This class holds information about a single QID. */ class QID { /** * Does the QID represent a directory? */ val isDirectory get() = getIsDirectory() /** * Does the QID represent an append-only file? */ val isAppendOnly get() = getIsAppendOnly() /** * Does the QID represent an exclusive-use file? */ val isExclusive get() = getIsExclusive() /** * Does the QID represent a temporary file? */ val isTemporary get() = getIsTemporary() /** * The QID type. */ val type: UByte /** * The QID file version. */ val version: UInt /** * The QID path. */ val path: ULong /** * Constructor for a QID with separate fields. See the `stat(5)` manual page for more information about [type], * [version], and [path]. * * @param type The QID type. * @param version The QID file version. * @param path The QID path. */ constructor(type: UByte, version: UInt, path: ULong) { this.type = type this.version = version this.path = path } /** * Constructor for raw QID data. Only the first 13 elements are read. * * @param raw The raw QID data. * @throws IllegalArgumentException if [raw] does not have at least 13 elements. */ constructor(raw: List) { require(raw.size >= 13) this.type = raw.first() val rawVersion = raw.slice(1..4) val rawPath = raw.slice(5..12) this.version = InMessage.convInteger(rawVersion, 0, rawVersion.size).toInt().toUInt() this.path = InMessage.convInteger(rawPath, 0, rawPath.size).toLong().toULong() } /** * Check bit values in [type]. In case of multiple bits, the method returns true if at least one of them is 1. * * @param bits A byte whose bits set to 1 are checked. */ private fun checkTypeBits(bits: UByte): Boolean { return this.type.and(bits) != 0u.toUByte() } private fun getIsDirectory(): Boolean { return checkTypeBits(0x80u) } private fun getIsAppendOnly(): Boolean { return checkTypeBits(0x40u) } private fun getIsExclusive(): Boolean { return checkTypeBits(0x20u) } private fun getIsTemporary(): Boolean { return checkTypeBits(0x04u) } fun toRaw(): List { var bytes: List = emptyList() bytes += this.type bytes += OutMessage.convIntegerToBytes(BigInteger(this.version.toString()), 4u) bytes += OutMessage.convIntegerToBytes(BigInteger(this.path.toString()), 8u) return bytes } }