mirror of
https://github.com/apple/swift-nio-extras.git
synced 2025-05-14 00:42:41 +08:00
LineBasedFrameDecoder: Don't discard everything after EOF (#39)
Motivation: LineBasedFrameDecoder discarded everything after EOF and delivered it in the left-over bytes error. For the real world however that doesn't make much sense, you'd want all previously received lines and only receive the partial lines as left-overs. Modifications: deliver lines until there are only partial lines left, even in case of EOF. Result: LineBasedFrameDecoder more useful
This commit is contained in:
parent
66c13a41c7
commit
1c39f44412
@ -49,6 +49,7 @@ public class LineBasedFrameDecoder: ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState {
|
public func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState {
|
||||||
|
while try self.decode(context: context, buffer: &buffer) == .continue {}
|
||||||
if buffer.readableBytes > 0 {
|
if buffer.readableBytes > 0 {
|
||||||
context.fireErrorCaught(NIOExtrasErrors.LeftOverBytesError(leftOverBytes: buffer))
|
context.fireErrorCaught(NIOExtrasErrors.LeftOverBytesError(leftOverBytes: buffer))
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ class LineBasedFrameDecoderTest: XCTestCase {
|
|||||||
self.channel = EmbeddedChannel()
|
self.channel = EmbeddedChannel()
|
||||||
self.decoder = LineBasedFrameDecoder()
|
self.decoder = LineBasedFrameDecoder()
|
||||||
self.handler = ByteToMessageHandler(self.decoder)
|
self.handler = ByteToMessageHandler(self.decoder)
|
||||||
try? self.channel.pipeline.addHandler(self.handler).wait()
|
XCTAssertNoThrow(try self.channel.pipeline.addHandler(self.handler).wait())
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
@ -141,6 +141,7 @@ class LineBasedFrameDecoderTest: XCTestCase {
|
|||||||
|
|
||||||
func channelRead(context: ChannelHandlerContext, data: NIOAny) {
|
func channelRead(context: ChannelHandlerContext, data: NIOAny) {
|
||||||
let buffer = self.unwrapInboundIn(data)
|
let buffer = self.unwrapInboundIn(data)
|
||||||
|
context.fireChannelRead(data)
|
||||||
|
|
||||||
if buffer.readableBytes == 3 {
|
if buffer.readableBytes == 3 {
|
||||||
context.close(promise: nil)
|
context.close(promise: nil)
|
||||||
@ -159,9 +160,16 @@ class LineBasedFrameDecoderTest: XCTestCase {
|
|||||||
let handler = CloseWhenMyFavouriteMessageArrives(receivedLeftOversPromise: receivedLeftOversPromise)
|
let handler = CloseWhenMyFavouriteMessageArrives(receivedLeftOversPromise: receivedLeftOversPromise)
|
||||||
XCTAssertNoThrow(try self.channel.pipeline.addHandler(handler).wait())
|
XCTAssertNoThrow(try self.channel.pipeline.addHandler(handler).wait())
|
||||||
var buffer = self.channel.allocator.buffer(capacity: 16)
|
var buffer = self.channel.allocator.buffer(capacity: 16)
|
||||||
buffer.writeString("a\nbb\nccc\ndddd\neeeee\nffffff\n")
|
buffer.writeString("a\nbb\nccc\ndddd\neeeee\nffffff\nXXX")
|
||||||
XCTAssertNoThrow(try self.channel.writeInbound(buffer))
|
XCTAssertNoThrow(try self.channel.writeInbound(buffer))
|
||||||
XCTAssertNoThrow(try XCTAssertEqual("dddd\neeeee\nffffff\n",
|
for s in ["a", "bb", "ccc", "dddd", "eeeee", "ffffff"] {
|
||||||
|
XCTAssertNoThrow(XCTAssertEqual(s,
|
||||||
|
(try self.channel.readInbound(as: ByteBuffer.self)?.readableBytesView).map {
|
||||||
|
String(decoding: $0, as: Unicode.UTF8.self)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
XCTAssertNoThrow(XCTAssertNil(try self.channel.readInbound(as: ByteBuffer.self)))
|
||||||
|
XCTAssertNoThrow(try XCTAssertEqual("XXX",
|
||||||
String(decoding: receivedLeftOversPromise.futureResult.wait().readableBytesView,
|
String(decoding: receivedLeftOversPromise.futureResult.wait().readableBytesView,
|
||||||
as: UTF8.self)))
|
as: UTF8.self)))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user