55
66import Foundation
77
8+ /**
9+ A type that allows to iteratively create TAR containers with the output being written into a `FileHandle`.
10+
11+ The `TarWriter` may be helpful in reducing the peak memory usage on certain platforms. However, to achieve this both
12+ the creation of TAR entries and the calls to `TarWriter` should be wrapped inside the `autoreleasepool`. Since the
13+ `autoreleasepool` is available only on Darwin platforms, the memory reducing effect may be not as significant on
14+ non-Darwin platforms (such as Linux or Windows).
15+
16+ The following code demonstrates an example usage of the `TarWriter`:
17+ ```swift
18+ let handle: FileHandle = ...
19+ let writer = TarWriter(fileHandle: handle)
20+ try autoreleasepool {
21+ let entry: TarEntry = ...
22+ try writer.append(entry)
23+ }
24+ try writer.finalize()
25+ try handle.close()
26+ ```
27+ Note that `TarWriter.finalize()` must be called after finishing appending entries to the container. However, closing
28+ the `FileHandle` remains the responsibility of the caller.
29+
30+ - Important: Due to the API availability limitations of Foundation's `FileHandle`, on certain platforms errors in
31+ `FileHandle` operations may result in unrecoverable runtime failures. As such, it is not recommended to use `TarWriter`
32+ on those platforms. The following platforms are _unaffected_ by this issue: macOS 10.15.4+, iOS 13.4+, watchOS 6.2+,
33+ tvOS 13.4+.
34+ */
835public struct TarWriter {
936
1037 private let format : TarContainer . Format
@@ -13,6 +40,20 @@ public struct TarWriter {
1340 private var longLinkNameCounter : UInt
1441 private var localPaxHeaderCounter : UInt
1542
43+ /**
44+ Creates a new instance for writing TAR entries using the specified `format` into the provided `fileHandle`.
45+
46+ The `TarWriter` will be forced to use the provided `format`, meaning that certain properties of the `entries` may
47+ be missing from the output data if the chosen format does not support corresponding features. The default `.pax`
48+ format supports the largest set of features. Other (non-PAX) formats should only be used if you have a specific
49+ need for them and you understand limitations of those formats.
50+
51+ - Parameter fileHandle: A handle into which the output will be written. Note that the `TarWriter` does not
52+ close the `fileHandle` and this remains the responsibility of the caller.
53+ - Parameter force: Force the usage of the specified format.
54+
55+ - Important: `TarWriter.finalize()` must be called after all entries have been appended.
56+ */
1657 public init ( fileHandle: FileHandle , force format: TarContainer . Format = . pax) {
1758 self . handle = fileHandle
1859 self . format = format
@@ -21,6 +62,14 @@ public struct TarWriter {
2162 self . localPaxHeaderCounter = 0
2263 }
2364
65+ /**
66+ Adds a new TAR entry at the end of the TAR container.
67+
68+ On Darwin platforms it is recommended to wrap both the initialization of a `TarEntry` and the call to this
69+ function inside the `autoreleasepool` in order to reduce the peak memory usage.
70+
71+ - Throws: Errors from the `FileHandle` operations.
72+ */
2473 public mutating func append( _ entry: TarEntry ) throws {
2574 var out = Data ( )
2675 if format == . gnu {
@@ -70,6 +119,11 @@ public struct TarWriter {
70119 }
71120 }
72121
122+ /**
123+ Finalizes the TAR container by adding an EOF marker.
124+
125+ - Throws: Errors from the `FileHandle` operations.
126+ */
73127 public func finalize( ) throws {
74128 // First, we append two 512-byte blocks consisting of zeros as an EOF marker.
75129 try write ( Data ( count: 1024 ) )
0 commit comments