mutating func parseStep()

in Sources/NIOWebSocket/WebSocketFrameDecoder.swift [107:184]


    mutating func parseStep(_ buffer: inout ByteBuffer) -> ParseResult {
        switch self.state {
        case .idle:
            // This is a new buffer. We want to find the first octet and save it off.
            guard let firstByte = buffer.readInteger(as: UInt8.self) else {
                return .insufficientData
            }
            self.state = .firstByteReceived(firstByte: firstByte)
            return .continueParsing

        case .firstByteReceived(let firstByte):
            // Now we're looking for the length. We begin by finding the length byte to see if we
            // need any more data.
            guard let lengthByte = buffer.readInteger(as: UInt8.self) else {
                return .insufficientData
            }

            let masked = (lengthByte & 0x80) != 0

            switch (lengthByte & 0x7F, masked) {
            case (126, _):
                self.state = .waitingForLengthWord(firstByte: firstByte, masked: masked)
            case (127, _):
                self.state = .waitingForLengthQWord(firstByte: firstByte, masked: masked)
            case (let len, true):
                assert(len <= 125)
                self.state = .waitingForMask(firstByte: firstByte, length: Int(len))
            case (let len, false):
                assert(len <= 125)
                self.state = .waitingForData(firstByte: firstByte, length: Int(len), maskingKey: nil)
            }
            return .continueParsing

        case .waitingForLengthWord(let firstByte, let masked):
            // We've got a one-word length here.
            guard let lengthWord = buffer.readInteger(as: UInt16.self) else {
                return .insufficientData
            }

            if masked {
                self.state = .waitingForMask(firstByte: firstByte, length: Int(lengthWord))
            } else {
                self.state = .waitingForData(firstByte: firstByte, length: Int(lengthWord), maskingKey: nil)
            }
            return .continueParsing

        case .waitingForLengthQWord(let firstByte, let masked):
            // We've got a qword of length here.
            guard let lengthQWord = buffer.readInteger(as: UInt64.self) else {
                return .insufficientData
            }

            if masked {
                self.state = .waitingForMask(firstByte: firstByte, length: Int(lengthQWord))
            } else {
                self.state = .waitingForData(firstByte: firstByte, length: Int(lengthQWord), maskingKey: nil)
            }
            return .continueParsing

        case .waitingForMask(let firstByte, let length):
            // We're waiting for the masking key.
            guard let maskingKey = buffer.readInteger(as: UInt32.self) else {
                return .insufficientData
            }

            self.state = .waitingForData(firstByte: firstByte, length: length, maskingKey: WebSocketMaskingKey(networkRepresentation: maskingKey))
            return .continueParsing

        case .waitingForData(let firstByte, let length, let maskingKey):
            guard let data = buffer.readSlice(length: length) else {
                return .insufficientData
            }

            let frame = WebSocketFrame(firstByte: firstByte, maskKey: maskingKey, applicationData: data)
            self.state = .idle
            return .result(frame)
        }
    }