summaryrefslogtreecommitdiff
path: root/lib/src/main/kotlin/FilePermissions.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/FilePermissions.kt
parent1e50cf9c224d03896f176f3718ff80ef1659e9c2 (diff)
switch to multi-module project structure
Diffstat (limited to 'lib/src/main/kotlin/FilePermissions.kt')
-rw-r--r--lib/src/main/kotlin/FilePermissions.kt92
1 files changed, 92 insertions, 0 deletions
diff --git a/lib/src/main/kotlin/FilePermissions.kt b/lib/src/main/kotlin/FilePermissions.kt
new file mode 100644
index 0000000..84a7944
--- /dev/null
+++ b/lib/src/main/kotlin/FilePermissions.kt
@@ -0,0 +1,92 @@
+/**
+ * The permissions of a newly created file.
+ */
+class FilePermissions {
+
+ /**
+ * The permissions for the file's owning user.
+ */
+ val userPerms: Permissions
+
+ /**
+ * The permissions for the file's owning group.
+ */
+ val groupPerms: Permissions
+
+ /**
+ * The permissions for everyone else.
+ */
+ val elsePerms: Permissions
+
+ /**
+ * Is the file a directory? If not, it's a regular file.
+ */
+ val isDirectory: Boolean
+
+ private val DMDIR: UInt = 0x80000000u
+
+ /**
+ * Constructor for file permissions with separate fields.
+ *
+ * @param userPerms The permissions for the file's owning user.
+ * @param groupPerms The permissions for the file's owning group.
+ * @param elsePerms The permissions for everyone else.
+ * @param isDirectory Is the file a directory? If not, it's a regular file.
+ */
+ constructor(userPerms: Permissions, groupPerms: Permissions, elsePerms: Permissions, isDirectory: Boolean) {
+ this.userPerms = userPerms
+ this.groupPerms = groupPerms
+ this.elsePerms = elsePerms
+ this.isDirectory = isDirectory
+ }
+
+ /**
+ * Constructor for raw file permission data. Only the first 4 elements are read.
+ *
+ * @param raw The raw file permission data.
+ * @throws IllegalArgumentException if [raw] does not have at least 4 elements.
+ */
+ constructor(raw: List<UByte>) {
+ require(raw.size >= 4)
+ val raw = raw.slice(0..4)
+ val dirValue = raw[0].toUInt().xor(this.DMDIR)
+ this.isDirectory = dirValue > 0u
+ this.userPerms = Permissions.fromByte(raw[1])
+ this.groupPerms = Permissions.fromByte(raw[2])
+ this.elsePerms = Permissions.fromByte(raw[3])
+ }
+
+ enum class Permissions(val bits: UByte) {
+ READ(0x4u),
+ WRITE(0x2u),
+ EXECUTE(0x1u),
+ READ_WRITE(READ.bits.or(WRITE.bits)),
+ READ_EXECUTE(READ.bits.or(EXECUTE.bits)),
+ WRITE_EXECUTE(WRITE.bits.or(EXECUTE.bits)),
+ READ_WRITE_EXECUTE(READ.bits.or(WRITE.bits.or(EXECUTE.bits)));
+
+ companion object {
+ /**
+ * Obtain a [Permissions] instance by matching its value.
+ *
+ * @throws NoSuchElementException if no such element has the provided value.
+ */
+ fun fromByte(bits: UByte) = Permissions.entries.first { it.bits == bits }
+ }
+ }
+
+ /**
+ * Turn the permissions described by the [FilePermissions] fields into a permission integer (4 bytes).
+ */
+ fun toPermissionInt(): UInt {
+ val permFileds = listOf(userPerms, groupPerms, elsePerms)
+ val perms: UInt = 0u
+ for (i in 0..permFileds.size) {
+ perms.or(permFileds[i].bits.toUInt().shl(8 * (permFileds.size - 1 - i)))
+ }
+ if (isDirectory) {
+ perms.or(this.DMDIR)
+ }
+ return perms
+ }
+} \ No newline at end of file