Skip to content

Commit ea0aef6

Browse files
authored
Fix IStreamable with End Of Stream Status (#331)
1 parent 011a801 commit ea0aef6

11 files changed

Lines changed: 17 additions & 77 deletions

File tree

Source/AwsCommonRuntimeKit/crt/ByteBuffer.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,8 @@ extension ByteBuffer: IStreamable {
6969
currentIndex = endIndex
7070
return dataSlice.count
7171
}
72+
73+
public func isEndOfStream() -> Bool {
74+
return self.currentIndex >= self.data.count
75+
}
7276
}

Source/AwsCommonRuntimeKit/http/HTTP2Stream.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class HTTP2Stream: HTTPStream {
3636
throw CommonRunTimeError.crtError(.makeFromLastError())
3737
}
3838
}
39-
39+
4040
/// manualDataWrites must have been enabled during HTTP2Request creation.
4141
/// A write with that has endOfStream set to be true will end the stream and prevent any further write.
4242
///

Source/AwsCommonRuntimeKit/io/Stream.swift

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public protocol IStreamable {
2929
/// Returns `0` if the data is not yet available.
3030
/// Otherwise returns the number of bytes read.
3131
func read(buffer: UnsafeMutableBufferPointer<UInt8>) throws -> Int?
32+
33+
/// Whether the stream has ended. If the read function returns Nil that will also signify end of stream,
34+
/// so if your stream will never know in advance that it's ended and always requires an extra read to know the end, you can always return false from this method.
35+
func isEndOfStream() -> Bool
3236
}
3337

3438
public extension IStreamable {
@@ -50,67 +54,3 @@ public enum StreamSeekType: UInt32 {
5054
case end = 2
5155
}
5256

53-
extension FileHandle: IStreamable {
54-
55-
public func length() throws -> UInt64 {
56-
let length: UInt64
57-
let savedPos: UInt64
58-
if #available(macOS 11, tvOS 13.4, iOS 13.4, watchOS 6.2, *) {
59-
savedPos = try offset()
60-
try seekToEnd()
61-
length = try offset()
62-
} else {
63-
savedPos = offsetInFile
64-
seekToEndOfFile()
65-
length = offsetInFile
66-
}
67-
guard length != savedPos else {
68-
return length
69-
}
70-
try self.seek(toOffset: savedPos)
71-
return length
72-
}
73-
74-
public func seek(offset: Int64, streamSeekType: StreamSeekType) throws {
75-
let targetOffset: UInt64
76-
switch streamSeekType {
77-
case .begin:
78-
guard offset >= 0 else {
79-
throw CommonRunTimeError.crtError(CRTError(code: AWS_IO_STREAM_INVALID_SEEK_POSITION.rawValue))
80-
}
81-
targetOffset = UInt64(offset)
82-
case .end:
83-
guard offset != 0 else {
84-
if #available(macOS 11, tvOS 13.4, iOS 13.4, watchOS 6.2, *) {
85-
try seekToEnd()
86-
} else {
87-
seekToEndOfFile()
88-
}
89-
return
90-
}
91-
let length = try length()
92-
guard offset <= 0, abs(offset) <= length else {
93-
throw CommonRunTimeError.crtError(CRTError(code: AWS_IO_STREAM_INVALID_SEEK_POSITION.rawValue))
94-
}
95-
targetOffset = length - UInt64(abs(offset))
96-
}
97-
try self.seek(toOffset: targetOffset)
98-
}
99-
100-
public func read(buffer: UnsafeMutableBufferPointer<UInt8>) throws -> Int? {
101-
let data: Data?
102-
if #available(macOS 11, tvOS 13.4, iOS 13.4, watchOS 6.2, *) {
103-
data = try self.read(upToCount: buffer.count)
104-
} else {
105-
data = self.readData(ofLength: buffer.count)
106-
}
107-
guard let data = data else {
108-
return nil
109-
}
110-
111-
if !data.isEmpty {
112-
data.copyBytes(to: buffer, from: 0..<data.count)
113-
}
114-
return data.count
115-
}
116-
}

Source/AwsCommonRuntimeKit/io/StreamCore.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ private func doRead(_ stream: UnsafeMutablePointer<aws_input_stream>!,
7979
private func doGetStatus(_ stream: UnsafeMutablePointer<aws_input_stream>!,
8080
_ result: UnsafeMutablePointer<aws_stream_status>!) -> Int32 {
8181
let iStreamCore = Unmanaged<IStreamCore>.fromOpaque(stream.pointee.impl).takeUnretainedValue()
82+
if(!iStreamCore.isEndOfStream) {
83+
iStreamCore.isEndOfStream = iStreamCore.iStreamable.isEndOfStream()
84+
}
8285
result.pointee = aws_stream_status(is_end_of_stream: iStreamCore.isEndOfStream, is_valid: true)
8386
return AWS_OP_SUCCESS
8487
}

Test/AwsCommonRuntimeKitTests/Resources/stream-test.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

Test/AwsCommonRuntimeKitTests/io/StreamTests.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ import Foundation
66

77
class StreamTests: XCBaseTestCase {
88

9-
func testFileStream() throws {
10-
let fileHandle = FileHandle(forReadingAtPath: Bundle.module.path(forResource: "stream-test", ofType: "txt")!)!
11-
let iStreamCore = IStreamCore(iStreamable: fileHandle)
12-
try testStream(iStreamCore: iStreamCore)
13-
}
14-
159
func testByteBufferStream() throws {
1610
let byteBuffer = ByteBuffer(data: "12345678900987654321".data(using: .utf8)!)
1711
let iStreamCore = IStreamCore(iStreamable: byteBuffer)

0 commit comments

Comments
 (0)