summaryrefslogtreecommitdiff
path: root/lib/src/main/kotlin/QID.kt
diff options
context:
space:
mode:
authorEdoardo La Greca2025-08-18 21:09:11 +0200
committerEdoardo La Greca2025-08-18 21:09:11 +0200
commit7341ead2aade10ea1b833e94275277658741883a (patch)
tree46495f24c54278d50aa0da5046822fbe502f3f14 /lib/src/main/kotlin/QID.kt
parent1e50cf9c224d03896f176f3718ff80ef1659e9c2 (diff)
switch to multi-module project structure
Diffstat (limited to 'lib/src/main/kotlin/QID.kt')
-rw-r--r--lib/src/main/kotlin/QID.kt105
1 files changed, 105 insertions, 0 deletions
diff --git a/lib/src/main/kotlin/QID.kt b/lib/src/main/kotlin/QID.kt
new file mode 100644
index 0000000..4d0bd6a
--- /dev/null
+++ b/lib/src/main/kotlin/QID.kt
@@ -0,0 +1,105 @@
+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<UByte>) {
+ 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<UByte> {
+ var bytes: List<UByte> = emptyList()
+ bytes += this.type
+ bytes += OutMessage.convIntegerToBytes(BigInteger(this.version.toString()), 4u)
+ bytes += OutMessage.convIntegerToBytes(BigInteger(this.path.toString()), 8u)
+ return bytes
+ }
+} \ No newline at end of file