public static WebSocketFrame Unpack(byte *s, int len) { if (s == null || len < HEADERSIZE) { return(default(WebSocketFrame)); } WebSocketFrame frame = new WebSocketFrame(); frame.fin = ((*s >> 7) & 0x01) == 1; frame.rsv1 = ((*s >> 6) & 0x01) == 1; frame.rsv2 = ((*s >> 5) & 0x01) == 1; frame.rsv3 = ((*s >> 4) & 0x01) == 1; frame.opcode = (byte)(0x0F & *s); frame.masked = (s[1] >> 7) == 0x01; frame.payload_length = (s[1] & 0x7F); s += 2; len -= 2; if (frame.payload_length == 0x7E) { // If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length if (len < HEADERSIZE + 2) { return(null); } frame.payload_length = *s++ << 0x08 | *s++ & 0xFF; len -= 2; } else if (frame.payload_length == 0x7F) { // If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0) are the payload length if (len < HEADERSIZE + 8) { return(null); } frame.payload_length = *s++ << 0x38 | *s++ << 0x30 | *s++ << 0x28 | *s++ << 0x20 | *s++ << 0x18 | *s++ << 0x10 | *s++ << 0x08 | *s++ & 0xFF; len -= 8; } byte[] mask = new byte[4]; if (frame.masked) { mask[0] = s[0]; mask[1] = s[1]; mask[2] = s[2]; mask[3] = s[3]; s += 4; len -= 4; frame.masking_key = mask; } frame.payload_data = new byte[frame.payload_length]; PayloadAdditional(frame, s, len); return(frame); }
public static MemoryStream Pack(WebSocketFrame frame) { byte[] header = PackFrameHeader(frame); if (header == null) { return(null); } MemoryStream ms = new MemoryStream(); ms.Write(header, 0, 2); int len = (header[1] & 0x7F); byte[] buffer = null; if (len == 0x7E) { buffer = new byte[2]; fixed(long *pinned = &frame.payload_length) { byte *s = (byte *)pinned; buffer[1] = *s++; buffer[0] = *s++; } } else if (len == 0x7F) { buffer = new byte[8]; fixed(long *pinned = &frame.payload_length) { byte *s = (byte *)pinned; buffer[7] = *s++; buffer[6] = *s++; buffer[5] = *s++; buffer[4] = *s++; buffer[3] = *s++; buffer[2] = *s++; buffer[1] = *s++; buffer[0] = *s++; } } if (buffer != null) { ms.Write(buffer, 0, buffer.Length); } byte[] mask = null; if (frame.masked) { Random rand = new Random(); mask = new byte[4]; for (int i = 0; i < 4; i++) { mask[i] = (byte)rand.Next(0x00, 0xFF); } frame.masking_key = mask; ms.Write(mask, 0, 4); } byte[] payload = frame.payload_data; if (frame.masked) { for (long i = 0; i < frame.payload_length; i++) { payload[i] ^= mask[i % 4]; } } ms.Write(payload, 0, payload.Length); return(ms); }