mirror of
https://github.com/apple/swift-nio-extras.git
synced 2025-05-14 17:02:43 +08:00
Merge branch 'main' into public-http1-type-conversion
This commit is contained in:
commit
c99f618599
@ -30,7 +30,7 @@ import NIOCore
|
|||||||
/// | ABC | DEF | GHI |
|
/// | ABC | DEF | GHI |
|
||||||
/// +-----+-----+-----+
|
/// +-----+-----+-----+
|
||||||
///
|
///
|
||||||
public class LineBasedFrameDecoder: ByteToMessageDecoder {
|
public class LineBasedFrameDecoder: ByteToMessageDecoder & NIOSingleStepByteToMessageDecoder {
|
||||||
/// `ByteBuffer` is the expected type passed in.
|
/// `ByteBuffer` is the expected type passed in.
|
||||||
public typealias InboundIn = ByteBuffer
|
public typealias InboundIn = ByteBuffer
|
||||||
/// `ByteBuffer`s will be passed to the next stage.
|
/// `ByteBuffer`s will be passed to the next stage.
|
||||||
@ -57,6 +57,14 @@ public class LineBasedFrameDecoder: ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decode data in the supplied buffer.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - buffer: Buffer containing data to decode.
|
||||||
|
/// - Returns: The decoded object or `nil` if we require more bytes.
|
||||||
|
public func decode(buffer: inout NIOCore.ByteBuffer) throws -> NIOCore.ByteBuffer? {
|
||||||
|
return try self.findNextFrame(buffer: &buffer)
|
||||||
|
}
|
||||||
|
|
||||||
/// Decode all remaining data.
|
/// Decode all remaining data.
|
||||||
/// If it is not possible to consume all the data then ``NIOExtrasErrors/LeftOverBytesError`` is reported via `context.fireErrorCaught`
|
/// If it is not possible to consume all the data then ``NIOExtrasErrors/LeftOverBytesError`` is reported via `context.fireErrorCaught`
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
@ -72,6 +80,20 @@ public class LineBasedFrameDecoder: ByteToMessageDecoder {
|
|||||||
return .needMoreData
|
return .needMoreData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decode all remaining data.
|
||||||
|
/// If it is not possible to consume all the data then ``NIOExtrasErrors/LeftOverBytesError`` is reported via `context.fireErrorCaught`
|
||||||
|
/// - Parameters:
|
||||||
|
/// - buffer: Buffer containing the data to decode.
|
||||||
|
/// - seenEOF: Has end of file been seen.
|
||||||
|
/// - Returns: The decoded object or `nil` if we require more bytes.
|
||||||
|
public func decodeLast(buffer: inout ByteBuffer, seenEOF: Bool) throws -> InboundOut? {
|
||||||
|
let decoded = try self.decode(buffer: &buffer)
|
||||||
|
if buffer.readableBytes > 0 {
|
||||||
|
throw NIOExtrasErrors.LeftOverBytesError(leftOverBytes: buffer)
|
||||||
|
}
|
||||||
|
return decoded
|
||||||
|
}
|
||||||
|
|
||||||
private func findNextFrame(buffer: inout ByteBuffer) throws -> ByteBuffer? {
|
private func findNextFrame(buffer: inout ByteBuffer) throws -> ByteBuffer? {
|
||||||
let view = buffer.readableBytesView.dropFirst(self.lastScanOffset)
|
let view = buffer.readableBytesView.dropFirst(self.lastScanOffset)
|
||||||
// look for the delimiter
|
// look for the delimiter
|
||||||
|
@ -214,4 +214,59 @@ class LineBasedFrameDecoderTest: XCTestCase {
|
|||||||
XCTFail("Unexpected error: \(error)")
|
XCTFail("Unexpected error: \(error)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testBasicSingleStep() {
|
||||||
|
let decoder = LineBasedFrameDecoder()
|
||||||
|
let b2mp = NIOSingleStepByteToMessageProcessor(decoder)
|
||||||
|
var callCount = 0
|
||||||
|
XCTAssertNoThrow(try b2mp.process(buffer: ByteBuffer(string: "1\n\n2\n3\n")) { line in
|
||||||
|
callCount += 1
|
||||||
|
switch callCount {
|
||||||
|
case 1:
|
||||||
|
XCTAssertEqual(ByteBuffer(string: "1"), line)
|
||||||
|
case 2:
|
||||||
|
XCTAssertEqual(ByteBuffer(string: ""), line)
|
||||||
|
case 3:
|
||||||
|
XCTAssertEqual(ByteBuffer(string: "2"), line)
|
||||||
|
case 4:
|
||||||
|
XCTAssertEqual(ByteBuffer(string: "3"), line)
|
||||||
|
default:
|
||||||
|
XCTFail("not expecting call no \(callCount)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBasicSingleStepNoNewlineComingButEOF() {
|
||||||
|
let decoder = LineBasedFrameDecoder()
|
||||||
|
let b2mp = NIOSingleStepByteToMessageProcessor(decoder)
|
||||||
|
XCTAssertNoThrow(try b2mp.process(buffer: ByteBuffer(string: "new newline eva\r")) { line in
|
||||||
|
XCTFail("not taking calls")
|
||||||
|
})
|
||||||
|
XCTAssertThrowsError(try b2mp.finishProcessing(seenEOF: true, { line in
|
||||||
|
XCTFail("not taking calls")
|
||||||
|
})) { error in
|
||||||
|
if let error = error as? NIOExtrasErrors.LeftOverBytesError {
|
||||||
|
XCTAssertEqual(ByteBuffer(string: "new newline eva\r"), error.leftOverBytes)
|
||||||
|
} else {
|
||||||
|
XCTFail("unexpected error: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBasicSingleStepNoNewlineOrEOFComing() {
|
||||||
|
let decoder = LineBasedFrameDecoder()
|
||||||
|
let b2mp = NIOSingleStepByteToMessageProcessor(decoder)
|
||||||
|
XCTAssertNoThrow(try b2mp.process(buffer: ByteBuffer(string: "new newline eva\r")) { line in
|
||||||
|
XCTFail("not taking calls")
|
||||||
|
})
|
||||||
|
XCTAssertThrowsError(try b2mp.finishProcessing(seenEOF: false, { line in
|
||||||
|
XCTFail("not taking calls")
|
||||||
|
})) { error in
|
||||||
|
if let error = error as? NIOExtrasErrors.LeftOverBytesError {
|
||||||
|
XCTAssertEqual(ByteBuffer(string: "new newline eva\r"), error.leftOverBytes)
|
||||||
|
} else {
|
||||||
|
XCTFail("unexpected error: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user