Skip to content

Commit 4569c69

Browse files
authored
add the NFS3 protocol (#155)
* 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
1 parent cc1e527 commit 4569c69

36 files changed

+4581
-2
lines changed

Package.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,20 @@ var targets: [PackageDescription.Target] = [
109109
"NIOSOCKS",
110110
.product(name: "NIOCore", package: "swift-nio"),
111111
.product(name: "NIOEmbedded", package: "swift-nio"),
112-
])
112+
]),
113+
.target(
114+
name: "NIONFS3",
115+
dependencies: [
116+
.product(name: "NIOCore", package: "swift-nio"),
117+
]),
118+
.testTarget(
119+
name: "NIONFS3Tests",
120+
dependencies: [
121+
"NIONFS3",
122+
.product(name: "NIOCore", package: "swift-nio"),
123+
.product(name: "NIOEmbedded", package: "swift-nio"),
124+
.product(name: "NIOTestUtils", package: "swift-nio"),
125+
]),
113126
]
114127

115128
let package = Package(

[email protected]

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,19 @@ var targets: [PackageDescription.Target] = [
109109
"NIOSOCKS",
110110
.product(name: "NIOCore", package: "swift-nio"),
111111
.product(name: "NIOEmbedded", package: "swift-nio"),
112-
])
112+
]),
113+
.target(
114+
name: "NIONFS3",
115+
dependencies: [
116+
.product(name: "NIOCore", package: "swift-nio"),
117+
]),
118+
.testTarget(
119+
name: "NIONFS3Tests",
120+
dependencies: [
121+
"NIONFS3",
122+
.product(name: "NIOCore", package: "swift-nio"),
123+
.product(name: "NIOTestUtils", package: "swift-nio"),
124+
]),
113125
]
114126

115127
let package = Package(
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftNIO open source project
4+
//
5+
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import NIOCore
16+
17+
// MARK: - Mount
18+
public struct MountCallMount: Hashable & Sendable {
19+
public init(dirPath: String) {
20+
self.dirPath = dirPath
21+
}
22+
23+
public var dirPath: String
24+
}
25+
26+
public struct MountReplyMount: Hashable & Sendable {
27+
public init(result: NFS3Result<MountReplyMount.Okay, NFS3Nothing>) {
28+
self.result = result
29+
}
30+
31+
public struct Okay: Hashable & Sendable {
32+
public init(fileHandle: NFS3FileHandle, authFlavors: [RPCAuthFlavor] = [.unix]) {
33+
self.fileHandle = fileHandle
34+
self.authFlavors = authFlavors
35+
}
36+
37+
public var fileHandle: NFS3FileHandle
38+
public var authFlavors: [RPCAuthFlavor] = [.unix]
39+
}
40+
41+
public var result: NFS3Result<Okay, NFS3Nothing>
42+
}
43+
44+
extension ByteBuffer {
45+
public mutating func readNFS3CallMount() throws -> MountCallMount {
46+
let dirPath = try self.readNFS3String()
47+
return MountCallMount(dirPath: dirPath)
48+
}
49+
50+
@discardableResult public mutating func writeNFS3CallMount(_ call: MountCallMount) -> Int {
51+
self.writeNFS3String(call.dirPath)
52+
}
53+
54+
@discardableResult public mutating func writeNFS3ReplyMount(_ reply: MountReplyMount) -> Int {
55+
var bytesWritten = self.writeNFS3ResultStatus(reply.result)
56+
57+
switch reply.result {
58+
case .okay(let reply):
59+
bytesWritten += self.writeNFS3FileHandle(reply.fileHandle)
60+
precondition(reply.authFlavors == [.unix] || reply.authFlavors == [.noAuth],
61+
"Sorry, anything but [.unix] / [.system] / [.noAuth] unimplemented.")
62+
bytesWritten += self.writeInteger(UInt32(reply.authFlavors.count), as: UInt32.self)
63+
for flavor in reply.authFlavors {
64+
bytesWritten += self.writeInteger(flavor.rawValue, as: UInt32.self)
65+
}
66+
case .fail(_, _):
67+
()
68+
}
69+
70+
return bytesWritten
71+
}
72+
73+
public mutating func readNFS3ReplyMount() throws -> MountReplyMount {
74+
let result = try self.readNFS3Result(readOkay: { buffer -> MountReplyMount.Okay in
75+
let fileHandle = try buffer.readNFS3FileHandle()
76+
let authFlavors = try buffer.readNFS3List(readEntry: { buffer in
77+
try buffer.readRPCAuthFlavor()
78+
})
79+
return MountReplyMount.Okay(fileHandle: fileHandle, authFlavors: authFlavors)
80+
81+
},
82+
readFail: { _ in NFS3Nothing() })
83+
return MountReplyMount(result: result)
84+
}
85+
}

Sources/NIONFS3/MountTypes+Null.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftNIO open source project
4+
//
5+
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import NIOCore
16+
17+
// MARK: - Null
18+
public struct MountCallNull: Hashable & Sendable {
19+
public init() {}
20+
}
21+
22+
extension ByteBuffer {
23+
public mutating func readMountCallNull() throws -> MountCallNull {
24+
return MountCallNull()
25+
}
26+
27+
@discardableResult public mutating func writeMountCallNull(_ call: MountCallNull) -> Int {
28+
return 0
29+
}
30+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftNIO open source project
4+
//
5+
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import NIOCore
16+
17+
// MARK: - Unmount
18+
public struct MountCallUnmount: Hashable & Sendable {
19+
public init(dirPath: String) {
20+
self.dirPath = dirPath
21+
}
22+
23+
public var dirPath: String
24+
}
25+
26+
public struct MountReplyUnmount: Hashable & Sendable {
27+
public init() {}
28+
}
29+
30+
extension ByteBuffer {
31+
public mutating func readNFS3CallUnmount() throws -> MountCallUnmount {
32+
let dirPath = try self.readNFS3String()
33+
return MountCallUnmount(dirPath: dirPath)
34+
}
35+
36+
@discardableResult public mutating func writeNFS3CallUnmount(_ call: MountCallUnmount) -> Int {
37+
self.writeNFS3String(call.dirPath)
38+
}
39+
40+
@discardableResult public mutating func writeNFS3ReplyUnmount(_ reply: MountReplyUnmount) -> Int {
41+
return 0
42+
}
43+
44+
public mutating func readNFS3ReplyUnmount() throws -> MountReplyUnmount {
45+
return MountReplyUnmount()
46+
}
47+
}

Sources/NIONFS3/NFSCallDecoder.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftNIO open source project
4+
//
5+
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import NIOCore
16+
17+
public struct NFS3CallDecoder: NIOSingleStepByteToMessageDecoder {
18+
public typealias InboundOut = RPCNFS3Call
19+
20+
public init() {}
21+
22+
public mutating func decode(buffer: inout ByteBuffer) throws -> RPCNFS3Call? {
23+
guard let message = try buffer.readRPCMessage() else {
24+
return nil
25+
}
26+
27+
guard case (.call(let call), var body) = message else {
28+
throw NFS3Error.wrongMessageType(message.0)
29+
}
30+
31+
return try body.readNFS3Call(rpc: call)
32+
}
33+
34+
public mutating func decodeLast(buffer: inout ByteBuffer, seenEOF: Bool) throws -> RPCNFS3Call? {
35+
return try self.decode(buffer: &buffer)
36+
}
37+
}

Sources/NIONFS3/NFSCallEncoder.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftNIO open source project
4+
//
5+
// Copyright (c) 2021-2023 Apple Inc. and the SwiftNIO project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import NIOCore
16+
17+
public struct NFS3CallEncoder: MessageToByteEncoder {
18+
public typealias OutboundIn = RPCNFS3Call
19+
20+
public init() {}
21+
22+
public func encode(data: RPCNFS3Call, out: inout ByteBuffer) throws {
23+
out.writeRPCNFS3Call(data)
24+
}
25+
}

0 commit comments

Comments
 (0)