static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,

                                                 Error **errp)

{

    unsigned char opcode, fin, has_mask;

    size_t header_size;

    size_t payload_len;

    QIOChannelWebsockHeader *header =

        (QIOChannelWebsockHeader *)ioc->encinput.buffer;



    if (ioc->payload_remain) {

        error_setg(errp,

                   "Decoding header but %zu bytes of payload remain",

                   ioc->payload_remain);

        return -1;

    }

    if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT) {

        /* header not complete */

        return QIO_CHANNEL_ERR_BLOCK;

    }



    fin = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >>

        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN;

    opcode = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE;

    has_mask = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >>

        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK;

    payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;



    if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {

        /* disconnect */

        return 0;

    }



    /* Websocket frame sanity check:

     * * Websocket fragmentation is not supported.

     * * All  websockets frames sent by a client have to be masked.

     * * Only binary encoding is supported.

     */

    if (!fin) {

        error_setg(errp, "websocket fragmentation is not supported");

        return -1;

    }

    if (!has_mask) {

        error_setg(errp, "websocket frames must be masked");

        return -1;

    }

    if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {

        error_setg(errp, "only binary websocket frames are supported");

        return -1;

    }



    if (payload_len < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT) {

        ioc->payload_remain = payload_len;

        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;

        ioc->mask = header->u.m;

    } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT &&

               ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT) {

        ioc->payload_remain = be16_to_cpu(header->u.s16.l16);

        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT;

        ioc->mask = header->u.s16.m16;

    } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT &&

               ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT) {

        ioc->payload_remain = be64_to_cpu(header->u.s64.l64);

        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;

        ioc->mask = header->u.s64.m64;

    } else {

        /* header not complete */

        return QIO_CHANNEL_ERR_BLOCK;

    }



    buffer_advance(&ioc->encinput, header_size);

    return 1;

}

static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,

                                                 Error **errp)

{

    unsigned char opcode, fin, has_mask;

    size_t header_size;

    size_t payload_len;

    QIOChannelWebsockHeader *header =

        (QIOChannelWebsockHeader *)ioc->encinput.buffer;



    if (ioc->payload_remain) {

        error_setg(errp,

                   "Decoding header but %zu bytes of payload remain",

                   ioc->payload_remain);

        return -1;

    }

    if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT) {

        

        return QIO_CHANNEL_ERR_BLOCK;

    }



    fin = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >>

        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN;

    opcode = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE;

    has_mask = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >>

        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK;

    payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;



    if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {

        

        return 0;

    }



    









    if (!fin) {

        error_setg(errp, "websocket fragmentation is not supported");

        return -1;

    }

    if (!has_mask) {

        error_setg(errp, "websocket frames must be masked");

        return -1;

    }

    if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {

        error_setg(errp, "only binary websocket frames are supported");

        return -1;

    }



    if (payload_len < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT) {

        ioc->payload_remain = payload_len;

        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;

        ioc->mask = header->u.m;

    } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT &&

               ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT) {

        ioc->payload_remain = be16_to_cpu(header->u.s16.l16);

        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT;

        ioc->mask = header->u.s16.m16;

    } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT &&

               ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT) {

        ioc->payload_remain = be64_to_cpu(header->u.s64.l64);

        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;

        ioc->mask = header->u.s64.m64;

    } else {

        

        return QIO_CHANNEL_ERR_BLOCK;

    }



    buffer_advance(&ioc->encinput, header_size);

    return 1;

}

static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,                                                  Error **errp)     fin = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >>         QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN;     has_mask = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >>         QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK;         error_setg(errp, "websocket frames must be masked");
static ssize_t FUNC_0(QIOChannelWebsock *ioc,

                                                 Error **errp)

{

    unsigned char VAR_0, VAR_1, VAR_2;

    size_t header_size;

    size_t payload_len;

    QIOChannelWebsockHeader *header =

        (QIOChannelWebsockHeader *)ioc->encinput.buffer;



    if (ioc->payload_remain) {

        error_setg(errp,

                   "Decoding header but %zu bytes of payload remain",

                   ioc->payload_remain);

        return -1;

    }

    if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT) {

        

        return QIO_CHANNEL_ERR_BLOCK;

    }



    VAR_1 = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >>

        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN;

    VAR_0 = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE;

    VAR_2 = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >>

        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK;

    payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;



    if (VAR_0 == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {

        

        return 0;

    }



    









    if (!VAR_1) {

        error_setg(errp, "websocket fragmentation is not supported");

        return -1;

    }

    if (!VAR_2) {

        error_setg(errp, "websocket frames must be masked");

        return -1;

    }

    if (VAR_0 != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {

        error_setg(errp, "only binary websocket frames are supported");

        return -1;

    }



    if (payload_len < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT) {

        ioc->payload_remain = payload_len;

        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;

        ioc->mask = header->u.m;

    } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT &&

               ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT) {

        ioc->payload_remain = be16_to_cpu(header->u.s16.l16);

        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT;

        ioc->mask = header->u.s16.m16;

    } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT &&

               ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT) {

        ioc->payload_remain = be64_to_cpu(header->u.s64.l64);

        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;

        ioc->mask = header->u.s64.m64;

    } else {

        

        return QIO_CHANNEL_ERR_BLOCK;

    }



    buffer_advance(&ioc->encinput, header_size);

    return 1;

}

static ssize_t FUNC_0(QIOChannelWebsock *ioc,
Error **errp)
{ unsigned char VAR_0, VAR_1, VAR_2; size_t header_size; size_t payload_len; QIOChannelWebsockHeader *header =
(QIOChannelWebsockHeader *)ioc->encinput.buffer; if (ioc->payload_remain) { error_setg(errp,
"Decoding header but %zu bytes of payload remain",
ioc->payload_remain); return -1; } if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT) { return QIO_CHANNEL_ERR_BLOCK; } VAR_1 = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >>
QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN; VAR_0 = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE; VAR_2 = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >>
QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK; payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN; if (VAR_0 == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) { return 0; } if (!VAR_1) { error_setg(errp, "websocket fragmentation is not supported"); return -1; } if (!VAR_2) { error_setg(errp, "websocket frames must be masked"); return -1; } if (VAR_0 != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) { error_setg(errp, "only binary websocket frames are supported"); return -1; } if (payload_len < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT) { ioc->payload_remain = payload_len; header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT; ioc->mask = header->u.m; } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT && ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT) { ioc->payload_remain = be16_to_cpu(header->u.s16.l16); header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT; ioc->mask = header->u.s16.m16; } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT && ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT) { ioc->payload_remain = be64_to_cpu(header->u.s64.l64); header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT; ioc->mask = header->u.s64.m64; } else { return QIO_CHANNEL_ERR_BLOCK; } buffer_advance(&ioc->encinput, header_size); return 1; }