Skip to content

Commit

Permalink
[NIOFileSystem] Provide an API to specify allowing unlimited sized reads
Browse files Browse the repository at this point in the history
Motivation:

As described in issue [apple#2877](apple#2877), there is no API available to specify allowing a read of unlimited size.

Modifications:

- Add a new `public static` property, `unlimited`, to `ByteCount` representing an unlimited amount of bytes.
- Adapt `ReadableFileHandleProtocol.readToEnd(fromAbsoluteOffset:maximumSizeAllowed:)` to work with `maximumSizeAllowed` being `ByteCount.unlimited`.

Result:

An API to specify allowing a read of an unlimited size will be available.
  • Loading branch information
clintonpi committed Oct 10, 2024
1 parent 611fa09 commit bdaecb6
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Sources/NIOFileSystem/ByteCount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ extension ByteCount {

return ByteCount(bytes: Int64(byteBufferMaxIndex))
}

/// A ``ByteCount`` for an unlimited amount of bytes.
public static var unlimited: ByteCount {
ByteCount(bytes: .max)
}
}

extension ByteCount: AdditiveArithmetic {
Expand Down
5 changes: 5 additions & 0 deletions Sources/NIOFileSystem/FileHandleProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,11 @@ extension ReadableFileHandleProtocol {
fromAbsoluteOffset offset: Int64 = 0,
maximumSizeAllowed: ByteCount
) async throws -> ByteBuffer {
var maximumSizeAllowed = maximumSizeAllowed
if maximumSizeAllowed == .unlimited {
maximumSizeAllowed = .byteBufferCapacity
}

let info = try await self.info()
let fileSize = Int64(info.size)
let readSize = max(Int(fileSize - offset), 0)
Expand Down
10 changes: 10 additions & 0 deletions Tests/NIOFileSystemIntegrationTests/FileSystemTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1818,6 +1818,16 @@ extension FileSystemTests {
}
}
}

func testReadWithUnlimitedMaximumSizeAllowed() async throws {
let path = try await self.fs.temporaryFilePath()

try await self.fs.withFileHandle(forReadingAndWritingAt: path) { fileHandle in
await XCTAssertNoThrowAsync(
try await fileHandle.readToEnd(maximumSizeAllowed: .unlimited)
)
}
}
}

#if !canImport(Darwin) && swift(<5.9.2)
Expand Down
12 changes: 12 additions & 0 deletions Tests/NIOFileSystemIntegrationTests/XCTestExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,16 @@ func XCTAssertThrowsFileSystemErrorAsync<R>(
}
}
}

func XCTAssertNoThrowAsync<T>(
_ expression: @autoclosure () async throws -> T,
file: StaticString = #file,
line: UInt = #line
) async {
do {
_ = try await expression()
} catch {
XCTFail("Expression did throw: \(error)", file: file, line: line)
}
}
#endif
5 changes: 5 additions & 0 deletions Tests/NIOFileSystemTests/ByteCountTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ class ByteCountTests: XCTestCase {
XCTAssertEqual(byteCount.bytes, 10_737_418_240)
}

func testByteCountUnlimited() {
let byteCount = ByteCount.unlimited
XCTAssertEqual(byteCount.bytes, .max)
}

func testByteCountEquality() {
let byteCount1 = ByteCount.bytes(10)
let byteCount2 = ByteCount.bytes(20)
Expand Down

0 comments on commit bdaecb6

Please sign in to comment.