func (f *Frame) unpack(packet []byte) []byte {
	var isHaveLen bool
	for !isHaveLen {
		switch len(f.chopped) {
		case 0:
			f.fin = packet[0] & frameIsFinished
			f.rsv1 = packet[0] & 0x40
			f.rsv2 = packet[0] & 0x20
			f.rsv3 = packet[0] & 0x10
			f.opcode = Opcode(packet[0] & 0x0F)
			f.chopped = append(f.chopped, packet[0])
			packet = packet[1:]
			if len(packet) == 0 {
				return nil
			}
		case 1:
			f.masked = packet[0] & frameIsMasked
			f.len = uint64(packet[0] & 0x7F)
			f.chopped = append(f.chopped, packet[0])
			packet = packet[1:]
		default:
			switch f.len {
			case frameLargePayload:
				if len(f.chopped) < 10 {
					exp := 10 - len(f.chopped)
					if len(packet) < exp {
						f.chopped = append(f.chopped,
							packet...)
						return nil
					}
					f.chopped = append(f.chopped,
						packet[:exp]...)
					f.len = binary.BigEndian.Uint64(
						f.chopped[2:10])
					packet = packet[exp:]
				}
			case frameMediumPayload:
				if len(f.chopped) < 4 {
					exp := 4 - len(f.chopped)
					if len(packet) < exp {
						f.chopped = append(f.chopped,
							packet...)
						return nil
					}
					f.chopped = append(f.chopped,
						packet[:exp]...)
					f.len = uint64(binary.BigEndian.Uint16(
						f.chopped[2:4]))
					packet = packet[exp:]
				}
			}
			isHaveLen = true
		}
	}
	if f.masked == frameIsMasked && len(f.maskKey) != 4 {
		if len(packet) == 0 {
			return nil
		}
		exp := 4 - len(f.maskKey)
		if len(packet) < exp {
			f.maskKey = append(f.maskKey, packet...)
			return nil
		}
		f.maskKey = append(f.maskKey, packet[:exp]...)
		packet = packet[exp:]
	}
	if f.len == 0 {
		if f.opcode == OpcodeClose {
			f.closeCode = StatusNormal
		}
		f.isComplete = true
		f.chopped = nil
		return packet
	}
	if len(packet) == 0 {
		return nil
	}
	exp := f.len - uint64(len(f.payload))
	if uint64(len(packet)) < exp {
		exp = uint64(len(packet))
	}
	if f.masked == frameIsMasked {
		start := len(f.payload) % 4
		for x := uint64(0); x < exp; x++ {
			packet[x] ^= f.maskKey[start%4]
			start++
		}
	}
	f.payload = append(f.payload, packet[:exp]...)
	packet = packet[exp:]
	if uint64(len(f.payload)) == f.len {
		if f.opcode == OpcodeClose {
			switch len(f.payload) {
			case 0:
				f.closeCode = StatusNormal
			case 1:
				f.closeCode = StatusBadRequest
			default:
				f.closeCode = CloseCode(binary.BigEndian.Uint16(
					f.payload[:2]))
			}
		}
		f.isComplete = true
		f.chopped = nil
	}
	return packet
}
unpack the WebSocket data protocol from raw bytes into single frame.

On success it will return the rest of unpacked frame.

WebSocket data protocol,

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+
package websocket
import (
	"encoding/binary"
	"math"
	"math/rand"
)
type Frame struct {
	fin byte
	rsv1 byte
	rsv2 byte
	rsv3 byte
	opcode Opcode
	masked byte
	closeCode CloseCode
	len uint64
	maskKey []byte
	payload []byte
	chopped []byte
	isComplete bool
}
func NewFrameBin(isMasked bool, payload []byte) []byte {
	return NewFrame(OpcodeBin, isMasked, payload)
}
func NewFrameClose(isMasked bool, code CloseCode, payload []byte) []byte {
	if code == 0 {
		code = StatusNormal
	}
	packet := make([]byte, 2+len(payload))
	binary.BigEndian.PutUint16(packet[:2], uint16(code))
	copy(packet[2:], payload)
	return newControlFrame(OpcodeClose, isMasked, packet)
}
func NewFramePing(isMasked bool, payload []byte) (packet []byte) {
	return newControlFrame(OpcodePing, isMasked, payload)
}
func NewFramePong(isMasked bool, payload []byte) (packet []byte) {
	return newControlFrame(OpcodePong, isMasked, payload)
}
func NewFrameText(isMasked bool, payload []byte) []byte {
	return NewFrame(OpcodeText, isMasked, payload)
}
func newControlFrame(opcode Opcode, isMasked bool, payload []byte) []byte {
	if len(payload) > frameSmallPayload {
		payload = payload[:frameSmallPayload]
	}
	return NewFrame(opcode, isMasked, payload)
}
func NewFrame(opcode Opcode, isMasked bool, payload []byte) []byte {
	f := &Frame{
		fin:     frameIsFinished,
		opcode:  opcode,
		payload: payload,
	}
	if isMasked {
		f.masked = frameIsMasked
	}
	return f.pack()
}
func (f *Frame) IsData() bool {
	return f.opcode == OpcodeText || f.opcode == OpcodeBin
}
func (f *Frame) isValid(isMasked, allowRsv1, allowRsv2, allowRsv3 bool) bool {
	if isMasked {
		if f.masked != frameIsMasked {
			return false
		}
	} else {
		if f.masked == frameIsMasked {
			return false
		}
	}
	if f.rsv1 > 0 && !allowRsv1 {
		return false
	}
	if f.rsv2 > 0 && !allowRsv2 {
		return false
	}
	if f.rsv3 > 0 && !allowRsv3 {
		return false
	}
	if f.opcode >= OpcodeClose {
		if f.fin == 0 {
			return false
		}
		if f.len > frameSmallPayload {
			return false
		}
	}
	return true
}
func (f *Frame) Opcode() Opcode {
	return f.opcode
}
func (f *Frame) pack() (out []byte) {
	headerSize := uint64(2)
	payloadSize := uint64(len(f.payload))
	switch {
	case payloadSize > math.MaxUint16:
		f.len = frameLargePayload
		headerSize += 8
	case payloadSize > frameSmallPayload:
		f.len = frameMediumPayload
		headerSize += 2
	default:
		f.len = payloadSize
	}
	if f.masked == frameIsMasked {
		headerSize += 4
	}
	frameSize := headerSize + payloadSize
	out = make([]byte, frameSize)
	x := 0
	out[x] = f.fin | byte(f.opcode)
	x++
	out[x] = f.masked | uint8(f.len)
	x++
	switch f.len {
	case frameLargePayload:
		binary.BigEndian.PutUint64(out[x:x+8], payloadSize)
		x += 8
	case frameMediumPayload:
		binary.BigEndian.PutUint16(out[x:x+2], uint16(payloadSize))
		x += 2
	}
	if f.masked == frameIsMasked {
		if len(f.maskKey) != 4 {
			f.maskKey = make([]byte, 4)
			binary.LittleEndian.PutUint32(f.maskKey, rand.Uint32())
		}
		out[x] = f.maskKey[0]
		x++
		out[x] = f.maskKey[1]
		x++
		out[x] = f.maskKey[2]
		x++
		out[x] = f.maskKey[3]
		x++
		for y := uint64(0); y < payloadSize; y++ {
			out[x] = f.payload[y] ^ f.maskKey[y%4]
			x++
		}
	} else {
		copy(out[x:], f.payload)
	}
	return out
}
func (f *Frame) Payload() []byte {
	return f.payload
}