morozovsk\websocket\Daemon::_decode PHP Method

_decode() protected method

protected _decode ( $connectionId )
    protected function _decode($connectionId)
    {
        $data = $this->_read[$connectionId];
        if (strlen($data) < 2) {
            return false;
        }
        $unmaskedPayload = '';
        $decodedData = array();
        // estimate frame type:
        $firstByteBinary = sprintf('%08b', ord($data[0]));
        $secondByteBinary = sprintf('%08b', ord($data[1]));
        $opcode = bindec(substr($firstByteBinary, 4, 4));
        $isMasked = $secondByteBinary[0] == '1';
        $payloadLength = ord($data[1]) & 127;
        switch ($opcode) {
            // text frame:
            case 1:
                $decodedData['type'] = 'text';
                break;
            case 2:
                $decodedData['type'] = 'binary';
                break;
                // connection close frame:
            // connection close frame:
            case 8:
                $decodedData['type'] = 'close';
                break;
                // ping frame:
            // ping frame:
            case 9:
                $decodedData['type'] = 'ping';
                break;
                // pong frame:
            // pong frame:
            case 10:
                $decodedData['type'] = 'pong';
                break;
            default:
                $decodedData['type'] = '';
        }
        if ($payloadLength === 126) {
            if (strlen($data) < 4) {
                return false;
            }
            $payloadOffset = 8;
            $dataLength = bindec(sprintf('%08b', ord($data[2])) . sprintf('%08b', ord($data[3]))) + $payloadOffset;
        } elseif ($payloadLength === 127) {
            if (strlen($data) < 10) {
                return false;
            }
            $payloadOffset = 14;
            for ($tmp = '', $i = 0; $i < 8; $i++) {
                $tmp .= sprintf('%08b', ord($data[$i + 2]));
            }
            $dataLength = bindec($tmp) + $payloadOffset;
        } else {
            $payloadOffset = 6;
            $dataLength = $payloadLength + $payloadOffset;
        }
        if (strlen($data) < $dataLength) {
            return false;
        } else {
            $this->_read[$connectionId] = substr($data, $dataLength);
        }
        if ($isMasked) {
            if ($payloadLength === 126) {
                $mask = substr($data, 4, 4);
            } elseif ($payloadLength === 127) {
                $mask = substr($data, 10, 4);
            } else {
                $mask = substr($data, 2, 4);
            }
            for ($i = $payloadOffset; $i < $dataLength; $i++) {
                $j = $i - $payloadOffset;
                if (isset($data[$i])) {
                    $unmaskedPayload .= $data[$i] ^ $mask[$j % 4];
                }
            }
            $decodedData['payload'] = $unmaskedPayload;
        } else {
            $payloadOffset = $payloadOffset - 4;
            $decodedData['payload'] = substr($data, $payloadOffset, $dataLength - $payloadOffset);
        }
        return $decodedData;
    }