Skip to content

Commit e618e0f

Browse files
committed
Expose FileOutputByteStream's close API into WritableByteStream protocol
1 parent 8f467d8 commit e618e0f

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

Sources/TSCBasic/WritableByteStream.swift

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ public protocol WritableByteStream: class, TextOutputStream {
5555

5656
/// Flush the stream's buffer.
5757
func flush()
58+
59+
/// Signal that the byte stream will not be used further and should be closed.
60+
func close() throws
61+
}
62+
63+
// Default noop implementation of close to avoid source-breaking downstream dependents with the addition of the close
64+
// API.
65+
public extension WritableByteStream {
66+
func close() throws { }
5867
}
5968

6069
// Public alias to the old name to not introduce API compatibility.
@@ -184,6 +193,14 @@ public class _WritableByteStreamBase: WritableByteStream {
184193
// Do nothing.
185194
}
186195

196+
public final func close() throws {
197+
try closeImpl()
198+
}
199+
200+
@usableFromInline func closeImpl() throws {
201+
fatalError("Subclasses must implement this")
202+
}
203+
187204
@usableFromInline func writeImpl<C: Collection>(_ bytes: C) where C.Iterator.Element == UInt8 {
188205
fatalError("Subclasses must implement this")
189206
}
@@ -320,6 +337,12 @@ public final class ThreadSafeOutputByteStream: WritableByteStream {
320337
stream.writeJSONEscaped(string)
321338
}
322339
}
340+
341+
public func close() throws {
342+
try queue.sync {
343+
try stream.close()
344+
}
345+
}
323346
}
324347

325348
/// Define an output stream operator. We need it to be left associative, so we
@@ -625,19 +648,24 @@ public final class BufferedOutputByteStream: _WritableByteStreamBase {
625648
override final func writeImpl(_ bytes: ArraySlice<UInt8>) {
626649
contents += bytes
627650
}
651+
652+
override final func closeImpl() throws {
653+
// Do nothing. The protocol does not require to stop receiving writes, close only signals that resources could
654+
// be released at this point should we need to.
655+
}
628656
}
629657

630658
/// Represents a stream which is backed to a file. Not for instantiating.
631659
public class FileOutputByteStream: _WritableByteStreamBase {
632660

633-
/// Closes the file flushing any buffered data.
634-
public final func close() throws {
661+
public override final func closeImpl() throws {
635662
flush()
636-
try closeImpl()
663+
try fileCloseImpl()
637664
}
638665

639-
func closeImpl() throws {
640-
fatalError("closeImpl() should be implemented by a subclass")
666+
/// Closes the file flushing any buffered data.
667+
func fileCloseImpl() throws {
668+
fatalError("fileCloseImpl() should be implemented by a subclass")
641669
}
642670
}
643671

@@ -726,7 +754,7 @@ public final class LocalFileOutputByteStream: FileOutputByteStream {
726754
fflush(filePointer)
727755
}
728756

729-
override final func closeImpl() throws {
757+
override final func fileCloseImpl() throws {
730758
defer {
731759
fclose(filePointer)
732760
// If clients called close we shouldn't call fclose again in deinit.

0 commit comments

Comments
 (0)