//===----------------------------------------------------------------------===// // // This source file is part of the SwiftProtobuf open source project // // Copyright (c) 2019 Circuit Dragon, Ltd. // Licensed under Apache License v2.0 // // See LICENSE.txt for license information // // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// import NIO import SwiftProtobuf public class VarintFrameDecoder: ByteToMessageDecoder { public typealias InboundOut = ByteBuffer private var messageLength: Int? = nil public init() {} public func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState { // If we don't have a length, we need to read one if self.messageLength == nil { self.messageLength = buffer.readVarint() } guard let length = self.messageLength else { // Not enough bytes to read the message length. Ask for more. return .needMoreData } // See if we can read this amount of data. guard let messageBytes = buffer.readSlice(length: length) else { // not enough bytes in the buffer to satisfy the read. Ask for more. return .needMoreData } // We don't need the length now. self.messageLength = nil // The message's bytes up the pipeline to the next handler. context.fireChannelRead(self.wrapInboundOut(messageBytes)) // We can keep going if you have more data. return .continue } public func decodeLast(context: ChannelHandlerContext, buffer: inout ByteBuffer, seenEOF: Bool) throws -> DecodingState { return try decode(context: context, buffer: &buffer) } } public class VarintLengthFieldPrepender: MessageToByteEncoder { public typealias OutboundIn = ByteBuffer public init() {} public func encode(data: ByteBuffer, out: inout ByteBuffer) throws { let bodyLen = data.readableBytes out.writeVarint(bodyLen) out.writeBytes(data.readableBytesView) } }