Skip to content

Commit 552cb31

Browse files
committed
[docs] Add documentation for TarReader
1 parent 859178d commit 552cb31

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

Sources/TAR/TarReader.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,29 @@
66
import Foundation
77
import BitByteData
88

9+
/**
10+
A type that allows to iteratively read TAR entries from a container provided by a `FileHandle`.
11+
12+
The `TarReader` may be helpful in reducing the peak memory usage on certain platforms. However, to achieve this either
13+
the `TarReader.process(_:)` function should be used or both the call to `TarReader.read()` and the processing of the
14+
returned entry should be wrapped inside the `autoreleasepool`. Since the `autoreleasepool` is available only on Darwin
15+
platforms, the memory reducing effect may be not as significant on non-Darwin platforms (such as Linux or Windows).
16+
17+
The following code demonstrates an example usage of the `TarReader`:
18+
```swift
19+
let handle: FileHandle = ...
20+
let reader = TarReader(fileHandle: handle)
21+
try reader.process { ... }
22+
...
23+
try handle.close()
24+
```
25+
Note that closing the `FileHandle` remains the responsibility of the caller.
26+
27+
- Important: Due to the API availability limitations of Foundation's `FileHandle`, on certain platforms errors in
28+
`FileHandle` operations may result in unrecoverable runtime failures. As such, it is not recommended to use `TarWriter`
29+
on those platforms. The following platforms are _unaffected_ by this issue: macOS 10.15.4+, iOS 13.4+, watchOS 6.2+,
30+
tvOS 13.4+.
31+
*/
932
public struct TarReader {
1033

1134
private let handle: FileHandle
@@ -14,6 +37,12 @@ public struct TarReader {
1437
private var longLinkName: String?
1538
private var longName: String?
1639

40+
/**
41+
Creates a new instance for reading TAR entries from the provided `fileHandle`.
42+
43+
- Parameter fileHandle: A handle from which the entries will be read. Note that the `TarReader` does not close the
44+
`fileHandle` and this remains the responsibility of the caller.
45+
*/
1746
public init(fileHandle: FileHandle) {
1847
self.handle = fileHandle
1948
self.lastGlobalExtendedHeader = nil
@@ -22,13 +51,38 @@ public struct TarReader {
2251
self.longName = nil
2352
}
2453

54+
/**
55+
Processes the next TAR entry by reading it from the container and calling the provided closure on the result.
56+
57+
On Darwin platforms both the reading and the call to the closure are performed inside the `autoreleasepool` which
58+
allows to reduce the peak memory usage.
59+
60+
If the argument supplied to the closure is `nil` this indicates that the end of the input was reached. After that
61+
the repeated `TarReader.process(_:)` or `TarReader.read()` calls will result in the `DataError.truncated` being
62+
thrown.
63+
64+
- Throws: `DataError.truncated` if the input is truncated. `TarError` is thrown in case of malformed input. Errors
65+
thrown by `FileHandle` operations are also propagated.
66+
*/
2567
public mutating func process<T>(_ transform: (TarEntry?) throws -> T) throws -> T {
2668
return try autoreleasepool {
2769
let entry = try read()
2870
return try transform(entry)
2971
}
3072
}
3173

74+
/**
75+
Reads the next TAR entry from the container.
76+
77+
On Darwin platforms it is recommended to wrap both the call to this function and the follow-up processing inside
78+
the `autoreleasepool` in order to reduce the peak memory usage.
79+
80+
- Throws: `DataError.truncated` if the input is truncated. `TarError` is thrown in case of malformed input. Errors
81+
thrown by `FileHandle` operations are also propagated.
82+
83+
- Returns: The next entry from the container or `nil` if the end of the input has been reached. After that the
84+
repeated `TarReader.process(_:)` or `TarReader.read()` calls will result in the `DataError.truncated` being thrown.
85+
*/
3286
public mutating func read() throws -> TarEntry? {
3387
let headerData = try getData(size: 512)
3488
if headerData.count == 0 {

0 commit comments

Comments
 (0)