From 17ebfcd99d6d429dd4f0053794e8102fed1af251 Mon Sep 17 00:00:00 2001 From: Clinton Nkwocha <32041805+clintonpi@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:25:17 +0100 Subject: [PATCH] [NIOFileSystem] Provide an API to specify allowing unlimited sized reads (#2914) Motivation: As described in issue [#2877](https://github.com/apple/swift-nio/issues/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. --- Sources/NIOFileSystem/ByteCount.swift | 5 +++++ Sources/NIOFileSystem/FileHandleProtocol.swift | 1 + .../FileSystemTests.swift | 10 ++++++++++ .../XCTestExtensions.swift | 12 ++++++++++++ Tests/NIOFileSystemTests/ByteCountTests.swift | 5 +++++ 5 files changed, 33 insertions(+) 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)