diff --git a/Sources/NIOFileSystem/ByteCount.swift b/Sources/NIOFileSystem/ByteCount.swift index f6b957700d..276b1f8eee 100644 --- a/Sources/NIOFileSystem/ByteCount.swift +++ b/Sources/NIOFileSystem/ByteCount.swift @@ -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 { diff --git a/Sources/NIOFileSystem/FileHandleProtocol.swift b/Sources/NIOFileSystem/FileHandleProtocol.swift index b8d2791c4c..b99136eb20 100644 --- a/Sources/NIOFileSystem/FileHandleProtocol.swift +++ b/Sources/NIOFileSystem/FileHandleProtocol.swift @@ -335,6 +335,7 @@ extension ReadableFileHandleProtocol { fromAbsoluteOffset offset: Int64 = 0, maximumSizeAllowed: ByteCount ) async throws -> ByteBuffer { + let maximumSizeAllowed = maximumSizeAllowed == .unlimited ? .byteBufferCapacity : maximumSizeAllowed let info = try await self.info() let fileSize = Int64(info.size) let readSize = max(Int(fileSize - offset), 0) diff --git a/Tests/NIOFileSystemIntegrationTests/FileSystemTests.swift b/Tests/NIOFileSystemIntegrationTests/FileSystemTests.swift index f0e6aee74a..409ef26cef 100644 --- a/Tests/NIOFileSystemIntegrationTests/FileSystemTests.swift +++ b/Tests/NIOFileSystemIntegrationTests/FileSystemTests.swift @@ -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) diff --git a/Tests/NIOFileSystemIntegrationTests/XCTestExtensions.swift b/Tests/NIOFileSystemIntegrationTests/XCTestExtensions.swift index 008eedd306..2c46e5b844 100644 --- a/Tests/NIOFileSystemIntegrationTests/XCTestExtensions.swift +++ b/Tests/NIOFileSystemIntegrationTests/XCTestExtensions.swift @@ -69,4 +69,16 @@ func XCTAssertThrowsFileSystemErrorAsync( } } } + +func XCTAssertNoThrowAsync( + _ 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 diff --git a/Tests/NIOFileSystemTests/ByteCountTests.swift b/Tests/NIOFileSystemTests/ByteCountTests.swift index 6a5c6297a1..f1a67387da 100644 --- a/Tests/NIOFileSystemTests/ByteCountTests.swift +++ b/Tests/NIOFileSystemTests/ByteCountTests.swift @@ -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)