Skip to content

Commit

Permalink
add the NFS3 protocol (#155)
Browse files Browse the repository at this point in the history
* add the NFS3 protocol

* make writes return the amount of bytes written

* nits, docs, removes

* compiler errors on old swifts

* Hashable everything

* delay errors

* remove typealiases

* Sendables

* implicit endiannes

* more changes
  • Loading branch information
weissi authored Mar 21, 2023
1 parent cc1e527 commit 4569c69
Show file tree
Hide file tree
Showing 36 changed files with 4,581 additions and 2 deletions.
15 changes: 14 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,20 @@ var targets: [PackageDescription.Target] = [
"NIOSOCKS",
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOEmbedded", package: "swift-nio"),
])
]),
.target(
name: "NIONFS3",
dependencies: [
.product(name: "NIOCore", package: "swift-nio"),
]),
.testTarget(
name: "NIONFS3Tests",
dependencies: [
"NIONFS3",
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOEmbedded", package: "swift-nio"),
.product(name: "NIOTestUtils", package: "swift-nio"),
]),
]

let package = Package(
Expand Down
14 changes: 13 additions & 1 deletion [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,19 @@ var targets: [PackageDescription.Target] = [
"NIOSOCKS",
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOEmbedded", package: "swift-nio"),
])
]),
.target(
name: "NIONFS3",
dependencies: [
.product(name: "NIOCore", package: "swift-nio"),
]),
.testTarget(
name: "NIONFS3Tests",
dependencies: [
"NIONFS3",
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOTestUtils", package: "swift-nio"),
]),
]

let package = Package(
Expand Down
85 changes: 85 additions & 0 deletions Sources/NIONFS3/MountTypes+Mount.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import NIOCore

// MARK: - Mount
public struct MountCallMount: Hashable & Sendable {
public init(dirPath: String) {
self.dirPath = dirPath
}

public var dirPath: String
}

public struct MountReplyMount: Hashable & Sendable {
public init(result: NFS3Result<MountReplyMount.Okay, NFS3Nothing>) {
self.result = result
}

public struct Okay: Hashable & Sendable {
public init(fileHandle: NFS3FileHandle, authFlavors: [RPCAuthFlavor] = [.unix]) {
self.fileHandle = fileHandle
self.authFlavors = authFlavors
}

public var fileHandle: NFS3FileHandle
public var authFlavors: [RPCAuthFlavor] = [.unix]
}

public var result: NFS3Result<Okay, NFS3Nothing>
}

extension ByteBuffer {
public mutating func readNFS3CallMount() throws -> MountCallMount {
let dirPath = try self.readNFS3String()
return MountCallMount(dirPath: dirPath)
}

@discardableResult public mutating func writeNFS3CallMount(_ call: MountCallMount) -> Int {
self.writeNFS3String(call.dirPath)
}

@discardableResult public mutating func writeNFS3ReplyMount(_ reply: MountReplyMount) -> Int {
var bytesWritten = self.writeNFS3ResultStatus(reply.result)

switch reply.result {
case .okay(let reply):
bytesWritten += self.writeNFS3FileHandle(reply.fileHandle)
precondition(reply.authFlavors == [.unix] || reply.authFlavors == [.noAuth],
"Sorry, anything but [.unix] / [.system] / [.noAuth] unimplemented.")
bytesWritten += self.writeInteger(UInt32(reply.authFlavors.count), as: UInt32.self)
for flavor in reply.authFlavors {
bytesWritten += self.writeInteger(flavor.rawValue, as: UInt32.self)
}
case .fail(_, _):
()
}

return bytesWritten
}

public mutating func readNFS3ReplyMount() throws -> MountReplyMount {
let result = try self.readNFS3Result(readOkay: { buffer -> MountReplyMount.Okay in
let fileHandle = try buffer.readNFS3FileHandle()
let authFlavors = try buffer.readNFS3List(readEntry: { buffer in
try buffer.readRPCAuthFlavor()
})
return MountReplyMount.Okay(fileHandle: fileHandle, authFlavors: authFlavors)

},
readFail: { _ in NFS3Nothing() })
return MountReplyMount(result: result)
}
}
30 changes: 30 additions & 0 deletions Sources/NIONFS3/MountTypes+Null.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import NIOCore

// MARK: - Null
public struct MountCallNull: Hashable & Sendable {
public init() {}
}

extension ByteBuffer {
public mutating func readMountCallNull() throws -> MountCallNull {
return MountCallNull()
}

@discardableResult public mutating func writeMountCallNull(_ call: MountCallNull) -> Int {
return 0
}
}
47 changes: 47 additions & 0 deletions Sources/NIONFS3/MountTypes+Unmount.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import NIOCore

// MARK: - Unmount
public struct MountCallUnmount: Hashable & Sendable {
public init(dirPath: String) {
self.dirPath = dirPath
}

public var dirPath: String
}

public struct MountReplyUnmount: Hashable & Sendable {
public init() {}
}

extension ByteBuffer {
public mutating func readNFS3CallUnmount() throws -> MountCallUnmount {
let dirPath = try self.readNFS3String()
return MountCallUnmount(dirPath: dirPath)
}

@discardableResult public mutating func writeNFS3CallUnmount(_ call: MountCallUnmount) -> Int {
self.writeNFS3String(call.dirPath)
}

@discardableResult public mutating func writeNFS3ReplyUnmount(_ reply: MountReplyUnmount) -> Int {
return 0
}

public mutating func readNFS3ReplyUnmount() throws -> MountReplyUnmount {
return MountReplyUnmount()
}
}
37 changes: 37 additions & 0 deletions Sources/NIONFS3/NFSCallDecoder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import NIOCore

public struct NFS3CallDecoder: NIOSingleStepByteToMessageDecoder {
public typealias InboundOut = RPCNFS3Call

public init() {}

public mutating func decode(buffer: inout ByteBuffer) throws -> RPCNFS3Call? {
guard let message = try buffer.readRPCMessage() else {
return nil
}

guard case (.call(let call), var body) = message else {
throw NFS3Error.wrongMessageType(message.0)
}

return try body.readNFS3Call(rpc: call)
}

public mutating func decodeLast(buffer: inout ByteBuffer, seenEOF: Bool) throws -> RPCNFS3Call? {
return try self.decode(buffer: &buffer)
}
}
25 changes: 25 additions & 0 deletions Sources/NIONFS3/NFSCallEncoder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import NIOCore

public struct NFS3CallEncoder: MessageToByteEncoder {
public typealias OutboundIn = RPCNFS3Call

public init() {}

public func encode(data: RPCNFS3Call, out: inout ByteBuffer) throws {
out.writeRPCNFS3Call(data)
}
}
Loading

0 comments on commit 4569c69

Please sign in to comment.