/src/swift-nio/Sources/NIOCore/IOData.swift
Line | Count | Source (jump to first uncovered line) |
1 | | //===----------------------------------------------------------------------===// |
2 | | // |
3 | | // This source file is part of the SwiftNIO open source project |
4 | | // |
5 | | // Copyright (c) 2017-2024 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 | | /// `IOData` unifies standard SwiftNIO types that are raw bytes of data; currently `ByteBuffer` and `FileRegion`. |
16 | | /// |
17 | | /// - warning: `IOData` is a legacy API, please avoid using it as much as possible. |
18 | | /// |
19 | | /// Many `ChannelHandler`s receive or emit bytes and in most cases this can be either a `ByteBuffer` or a `FileRegion` |
20 | | /// from disk. To still form a well-typed `ChannelPipeline` such handlers should receive and emit value of type `IOData`. |
21 | | public enum IOData: Sendable { |
22 | | /// A `ByteBuffer`. |
23 | | case byteBuffer(ByteBuffer) |
24 | | |
25 | | /// A `FileRegion`. |
26 | | /// |
27 | | /// - warning: `IOData.fileRegion` is a legacy API, please avoid using it. It cannot work with TLS and `FileRegion` |
28 | | /// and the underlying `NIOFileHandle` objects are very difficult to hold correctly. |
29 | | /// |
30 | | /// Sending a `FileRegion` through the `ChannelPipeline` using `write` can be useful because some `Channel`s can |
31 | | /// use `sendfile` to send a `FileRegion` more efficiently. |
32 | | case fileRegion(FileRegion) |
33 | | } |
34 | | |
35 | | /// `IOData` objects are comparable just like the values they wrap. |
36 | | extension IOData: Equatable {} |
37 | | |
38 | | /// `IOData` provide a number of readable bytes. |
39 | | extension IOData { |
40 | | /// Returns the number of readable bytes in this `IOData`. |
41 | 0 | public var readableBytes: Int { |
42 | 0 | switch self { |
43 | 0 | case .byteBuffer(let buf): |
44 | 0 | return buf.readableBytes |
45 | 0 | case .fileRegion(let region): |
46 | 0 | return region.readableBytes |
47 | 0 | } |
48 | 0 | } |
49 | | |
50 | | /// Move the readerIndex forward by `offset`. |
51 | 0 | public mutating func moveReaderIndex(forwardBy: Int) { |
52 | 0 | switch self { |
53 | 0 | case .byteBuffer(var buffer): |
54 | 0 | buffer.moveReaderIndex(forwardBy: forwardBy) |
55 | 0 | self = .byteBuffer(buffer) |
56 | 0 | case .fileRegion(var fileRegion): |
57 | 0 | fileRegion.moveReaderIndex(forwardBy: forwardBy) |
58 | 0 | self = .fileRegion(fileRegion) |
59 | 0 | } |
60 | 0 | } |
61 | | } |
62 | | |
63 | | extension IOData: CustomStringConvertible { |
64 | 0 | public var description: String { |
65 | 0 | switch self { |
66 | 0 | case .byteBuffer(let byteBuffer): |
67 | 0 | return "IOData { \(byteBuffer) }" |
68 | 0 | case .fileRegion(let fileRegion): |
69 | 0 | return "IOData { \(fileRegion) }" |
70 | 0 | } |
71 | 0 | } |
72 | | } |