import java.math.BigInteger // TODO: add time conversion methods /** * File attributes. The `type` and `dev` attributes are ignored since they are for kernel use only. Time is measured in * seconds, since the epoch (Jan 1 00:00 1970 GMT). */ class Stat { /** * The FID sent the T-stat message. */ val fid: UInt /** * The QID of the file. */ val qid: QID /** * Permissions and flags. */ val mode: FilePermissions /** * Last acces time. */ val atime: UInt /** * Last modification time. */ val mtime: UInt /** * The length of the file in bytes. */ val length: ULong /** * The file name, which is `/` if the file is the root directory. */ val name: String /** * The owner's name. */ val uid: String /** * The group's name. */ val gid: String /** * The name of the user who last modified the file. */ val muid: String /** * Make an instance of [Stat] from each of its fields. * * @param fid The FID sent the T-stat message. * @param qid The QID of the file. * @param mode Permissions and flags. * @param atime Last acces time. * @param mtime Last modification time. * @param length The length of the file in bytes. * @param name The file name, which is `/` if the file is the root directory. * @param uid The owner's name. * @param gid The group's name. * @param muid The name of the user who last modified the file. */ constructor(fid: UInt, qid: QID, mode: FilePermissions, atime: UInt, mtime: UInt, length: ULong, name: String, uid: String, gid: String, muid: String) { this.fid = fid this.qid = qid this.mode = mode this.atime = atime this.mtime = mtime this.length = length this.name = name this.uid = uid this.gid = gid this.muid = muid } /** * Make an instance of [Stat] from raw data. * * @param fid The FID of the file associated with the stat instance. * @param raw The raw stat data. */ constructor(fid: UInt, raw: List) { var offset = 0 val qid = QID(raw.slice(0..<13)) offset += 13 val mode = FilePermissions(raw.slice(offset+0.. = mutableListOf() for (size in intFielSizes) { intFields.add(InMessage.convInteger(raw, offset, size)) offset += size } val atime = intFields[0].toInt().toUInt() val mtime = intFields[1].toInt().toUInt() val length = intFields[2].toLong().toULong() val strAmount = 4 val strFields: MutableList = mutableListOf() for (i in 0..strAmount) { val str = InMessage.convString(raw, offset) strFields.add(str) offset += str.length } val name = strFields[0] val uid = strFields[1] val gid = strFields[2] val muid = strFields[3] this.fid = fid this.qid = qid this.mode = mode this.atime = atime this.mtime = mtime this.length = length this.name = name this.uid = uid this.gid = gid this.muid = muid } /** * Turn a [Stat] instance into raw data. This leaves out the [fid] field. */ fun toRaw(): List { var bytes: List = emptyList() bytes += this.qid.toRaw() bytes += OutMessage.convIntegerToBytes(BigInteger(this.mode.toPermissionInt().toString()), 4u) bytes += OutMessage.convIntegerToBytes(BigInteger(this.atime.toString()), 4u) bytes += OutMessage.convIntegerToBytes(BigInteger(this.mtime.toString()), 4u) bytes += OutMessage.convIntegerToBytes(BigInteger(this.length.toString()), 8u) bytes += OutMessage.convStringToBytes(this.name) bytes += OutMessage.convStringToBytes(this.uid) bytes += OutMessage.convStringToBytes(this.gid) bytes += OutMessage.convStringToBytes(this.muid) return bytes } }