diff options
Diffstat (limited to 'lib/src/main/kotlin/ProtocolTranslator.kt')
-rw-r--r-- | lib/src/main/kotlin/ProtocolTranslator.kt | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/lib/src/main/kotlin/ProtocolTranslator.kt b/lib/src/main/kotlin/ProtocolTranslator.kt new file mode 100644 index 0000000..fee52f4 --- /dev/null +++ b/lib/src/main/kotlin/ProtocolTranslator.kt @@ -0,0 +1,167 @@ +/* +TODO: + - add arguments to methods + - switch from returned strings to exceptions +*/ + +/** + * The [ProtocolTranslator] interface provides methods that coincide 1:1 with each request type in the 9P protocol. + * Every method that can fail, that is, every request that can receive a response with `Rerror` type instead of the same + * type as itself, returns a non-null `String` that contains the error message received in the response. + * + * Tags and the `msize` value are supposed to be managed internally by the implementing class. + * + * When compared to 9P's formal message descriptions, like those which can be read in Plan 9's manual pages, some of the + * methods might lack parameters. Those which can be inferred from the existing parameters are purposefully omitted. An + * example is [walk], which omits `nwname` because it can be obtained by calculating the size of `wname`. + * + * Trivia: comments for each method are taken from each message type's manual page in section 5. + */ +interface ProtocolTranslator { + /** + * Negotiate protocol version. + * + * This must be the first message sent on the 9P connection and no other requests can be issued until a response has + * been received. + * + * @param msize The maximum length, in bytes, that the client will ever generate or expect to receive in a single + * 9P message. + * @param version Should be "9P2000", which is the only defined value. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + * @throws except.MsizeValueTooBigException if the received `msize` value is bigger than what the client requested. + * @throws except.UnknownVersionException if the version negotiation failed. + */ + fun version(msize: UInt, version: String) + + /** + * Perform authentication. + */ + fun auth(afid: UInt, uname: String, aname: String) + + /** + * Abort a message. + * + * @param oldtag The tag of the message that needs to be purged. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun flush(oldtag: UShort) + + /** + * Establish a connection. + * + * @param fid FID that represents the root directory of the desired file tree. + * @param afid A FID previously established by an auth message. + * @param uname A user identifier. + * @param aname The desired file tree to access. + * @return The QID of the file tree's root. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun attach(fid: UInt, afid: UInt, uname: String, aname: String): QID + + /** + * Descend a directory hierarchy. + * + * @param fid The existing FID. It must represent a directory. + * @param newfid The proposed FID, which is going to be associated with the result of walking the hierarchy. It must + * be not in use, unless it is the same as [fid]. + * @param wname The successive path name elements which describe the file to walk to. + * @return The QID of each path element that has been walked through. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + * @throws except.UnaccessibleFileException if [wname] contains one or more path elements that do not exist. + */ + fun walk(fid: UInt, newfid: UInt, wname: List<String>): List<QID> + + /** + * Prepare an FID for I/O on an existing file. + * + * @param fid The FID of the file to open. + * @param mode The mode in which the file is opened. + * @return A pair of: (1) the returned QID, and (2) a value called `iounit` that indicates, if non-zero, the maximum + * number of bytes that are guaranteed to be read from or written to the file without breaking the I/O transfer into + * multiple 9P messages. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun open(fid: UInt, mode: FileMode): Pair<QID, UInt> + + /** + * Prepare an FID for I/O on a new file. + * + * @param fid The FID of the directory that is going to contain the file. The specified directory requires write + * permission. + * @param name The file name. + * @param perm The permissions of the new file. + * @param mode The open mode after successful creation. + * @return A pair of: (1) the QID of the newly created file, and (2) a value called `iounit` that indicates, if + * non-zero, the maximum number of bytes that are guaranteed to be read from or written to the file without breaking + * the I/O transfer into multiple 9P messages. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun create(fid: UInt, name: String, perm: FilePermissions, mode: FileMode): Pair<QID, UInt> + + /** + * Transfer data from file. Due to the negotiated maximum size of 9P messages, called `msize`, one is supposed to + * call this method multiple times, unless the content is smaller than `msize`. + * + * @return The content read with the call just made. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun read(fid: UInt, offset: ULong, count: UInt): Array<UByte> + + /** + * Transfer data to file. Due to the negotiated maximum size of 9P messages, called `msize`, this method is supposed + * to be called multiple times, unless the content is smaller than `msize`. + * + * @param fid The FID to write to. + * @param offset The distance between the beginning of the file and the first written byte. + * @param data The raw bytes that are going to be written. + * @return The amount of bytes written with the call just made. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun write(fid: UInt, offset: ULong, count: UInt, data: Iterable<UByte>): UInt + + /** + * Forget about a FID. + * + * @param fid The FID to forget. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun clunk(fid: UInt) + + /** + * Remove a file from a server. + * + * @param fid The FID of the file to remove. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun remove(fid: UInt) + + /** + * Inquire file attributes. + * + * @param fid The FID of the file to inquire. + * @return All the file attributes of the file associated with [fid]. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun stat(fid: UInt): Stat + + /** + * Change file attributes. + * + * @param fid The FID of the file to set attributes of. + * @param stat The attributes to set. + * @throws except.InvalidMessageException if the received message is invalid. + * @throws except.RErrorException if the received message is an R-error message. + */ + fun wstat(fid: UInt, stat: Stat) +}
\ No newline at end of file |