/* this is a file autogenerated by spice_codegen.py */
/*
  Copyright (C) 2013 Red Hat, Inc.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#include <config.h>
#include "test-marshallers.h"
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <spice/protocol.h>
#include <spice/macros.h>
#include <common/mem.h>
#include <common/demarshallers.h>

#ifdef _MSC_VER
#pragma warning(disable:4101)
#endif



#include <spice/start-packed.h>
typedef struct SPICE_ATTR_PACKED {
    int16_t v;
} int16_unaligned_t;
typedef struct SPICE_ATTR_PACKED {
    uint16_t v;
} uint16_unaligned_t;
typedef struct SPICE_ATTR_PACKED {
    int32_t v;
} int32_unaligned_t;
typedef struct SPICE_ATTR_PACKED {
    uint32_t v;
} uint32_unaligned_t;
typedef struct SPICE_ATTR_PACKED {
    int64_t v;
} int64_unaligned_t;
typedef struct SPICE_ATTR_PACKED {
    uint64_t v;
} uint64_unaligned_t;
#include <spice/end-packed.h>

#define read_int8(ptr) (*((int8_t *)(ptr)))
#define write_int8(ptr, val) *(int8_t *)(ptr) = val
#define read_uint8(ptr) (*((uint8_t *)(ptr)))
#define write_uint8(ptr, val) *(uint8_t *)(ptr) = val

#ifdef WORDS_BIGENDIAN
#define read_int16(ptr) ((int16_t)SPICE_BYTESWAP16(((uint16_unaligned_t *)(ptr))->v))
#define write_int16(ptr, val) ((uint16_unaligned_t *)(ptr))->v = SPICE_BYTESWAP16((uint16_t)val)
#define read_uint16(ptr) ((uint16_t)SPICE_BYTESWAP16(((uint16_unaligned_t *)(ptr))->v))
#define write_uint16(ptr, val) ((uint16_unaligned_t *)(ptr))->v = SPICE_BYTESWAP16((uint16_t)val)
#define read_int32(ptr) ((int32_t)SPICE_BYTESWAP32(((uint32_unaligned_t *)(ptr))->v))
#define write_int32(ptr, val) ((uint32_unaligned_t *)(ptr))->v = SPICE_BYTESWAP32((uint32_t)val)
#define read_uint32(ptr) ((uint32_t)SPICE_BYTESWAP32(((uint32_unaligned_t *)(ptr))->v))
#define write_uint32(ptr, val) ((uint32_unaligned_t *)(ptr))->v = SPICE_BYTESWAP32((uint32_t)val)
#define read_int64(ptr) ((int64_t)SPICE_BYTESWAP64(((uint64_unaligned_t *)(ptr))->v))
#define write_int64(ptr, val) ((uint64_unaligned_t *)(ptr))->v = SPICE_BYTESWAP64((uint64_t)val)
#define read_uint64(ptr) ((uint64_t)SPICE_BYTESWAP64(((uint64_unaligned_t *)(ptr))->v))
#define write_uint64(ptr, val) ((uint64_unaligned_t *)(ptr))->v = SPICE_BYTESWAP64((uint64_t)val)
#else
#define read_int16(ptr) (((int16_unaligned_t *)(ptr))->v)
#define write_int16(ptr, val) (((int16_unaligned_t *)(ptr))->v) = val
#define read_uint16(ptr) (((uint16_unaligned_t *)(ptr))->v)
#define write_uint16(ptr, val) (((uint16_unaligned_t *)(ptr))->v) = val
#define read_int32(ptr) (((int32_unaligned_t *)(ptr))->v)
#define write_int32(ptr, val) (((int32_unaligned_t *)(ptr))->v) = val
#define read_uint32(ptr) (((uint32_unaligned_t *)(ptr))->v)
#define write_uint32(ptr, val) (((uint32_unaligned_t *)(ptr))->v) = val
#define read_int64(ptr) (((int64_unaligned_t *)(ptr))->v)
#define write_int64(ptr, val) (((int64_unaligned_t *)(ptr))->v) = val
#define read_uint64(ptr) (((uint64_unaligned_t *)(ptr))->v)
#define write_uint64(ptr, val) (((uint64_unaligned_t *)(ptr))->v) = val
#endif

static int8_t SPICE_GNUC_UNUSED consume_int8(uint8_t **ptr)
{
    int8_t val;
    val = read_int8(*ptr);
    *ptr += 1;
    return val;
}

static uint8_t SPICE_GNUC_UNUSED consume_uint8(uint8_t **ptr)
{
    uint8_t val;
    val = read_uint8(*ptr);
    *ptr += 1;
    return val;
}

static int16_t SPICE_GNUC_UNUSED consume_int16(uint8_t **ptr)
{
    int16_t val;
    val = read_int16(*ptr);
    *ptr += 2;
    return val;
}

static uint16_t SPICE_GNUC_UNUSED consume_uint16(uint8_t **ptr)
{
    uint16_t val;
    val = read_uint16(*ptr);
    *ptr += 2;
    return val;
}

static int32_t SPICE_GNUC_UNUSED consume_int32(uint8_t **ptr)
{
    int32_t val;
    val = read_int32(*ptr);
    *ptr += 4;
    return val;
}

static uint32_t SPICE_GNUC_UNUSED consume_uint32(uint8_t **ptr)
{
    uint32_t val;
    val = read_uint32(*ptr);
    *ptr += 4;
    return val;
}

static int64_t SPICE_GNUC_UNUSED consume_int64(uint8_t **ptr)
{
    int64_t val;
    val = read_int64(*ptr);
    *ptr += 8;
    return val;
}

static uint64_t SPICE_GNUC_UNUSED consume_uint64(uint8_t **ptr)
{
    uint64_t val;
    val = read_uint64(*ptr);
    *ptr += 8;
    return val;
}
static int SPICE_GNUC_UNUSED consume_fd(uint8_t **ptr SPICE_GNUC_UNUSED)
{
    return -1;
}

typedef struct PointerInfo PointerInfo;
typedef void (*message_destructor_t)(uint8_t *message);
typedef uint8_t * (*parse_func_t)(uint8_t *message_start, uint8_t *message_end, uint8_t *struct_data, PointerInfo *ptr_info);
typedef uint8_t * (*parse_msg_func_t)(uint8_t *message_start, uint8_t *message_end, size_t *size_out, message_destructor_t *free_message);
typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor, size_t *size_out, message_destructor_t *free_message);

struct PointerInfo {
    uint64_t offset;
    parse_func_t parse;
    void * *dest;
    uint64_t nelements;
};

static uint8_t * parse_array_uint64(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
{
    uint8_t *in = message_start + this_ptr_info->offset;
    uint8_t *end;
    uint32_t i;

    end = struct_data;
    for (i = 0; i < this_ptr_info->nelements; i++) {
        *(uint64_t *)end = consume_uint64(&in);
        end += sizeof(uint64_t);
    }
    return end;
}

static uint8_t * parse_msg_main_ShortDataSubMarshall(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    uint64_t nw_size;
    uint64_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[1];
    uint64_t data__extra_size;
    uint64_t data__array__nelements;
    SpiceMsgMainShortDataSubMarshall *out;
    uint32_t i;

    { /* data */
        uint32_t data__value;
        uint64_t data__array__nw_size;
        uint64_t data__array__mem_size;
        uint32_t data_size__value;
        pos = (start + 5);
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        data__value = read_uint32(pos);
        if (SPICE_UNLIKELY(data__value >= (uintptr_t) (message_end - message_start))) {
            goto error;
        }
        pos = start + 1;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        data_size__value = read_uint32(pos);
        data__array__nelements = data_size__value;

        data__array__nw_size = (8) * data__array__nelements;
        data__array__mem_size = sizeof(uint64_t) * data__array__nelements;
        if (SPICE_UNLIKELY(data__array__nw_size > (uintptr_t) (message_end - message_start - data__value))) {
            goto error;
        }
        data__extra_size = data__array__mem_size + /* for alignment */ 3;
    }

    nw_size = 9;
    mem_size = sizeof(SpiceMsgMainShortDataSubMarshall) + data__extra_size;

    /* Check if message fits in reported side */
    if (nw_size > (uintptr_t) (message_end - start)) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainShortDataSubMarshall);
    in = start;

    out = (SpiceMsgMainShortDataSubMarshall *)data;

    out->dummy_byte = consume_uint8(&in);
    out->data_size = consume_uint32(&in);
    ptr_info[n_ptr].offset = consume_uint32(&in);
    ptr_info[n_ptr].parse = parse_array_uint64;
    ptr_info[n_ptr].dest = (void **)&out->data;
    ptr_info[n_ptr].nelements = data__array__nelements;
    n_ptr++;

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    free(data);
    return NULL;
}

static uint8_t * parse_msg_main_ArrayMessage(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    uint64_t nw_size;
    uint64_t mem_size;
    uint8_t *in, *end;
    uint64_t name__nw_size, name__mem_size;
    uint64_t name__nelements;
    SpiceMsgMainArrayMessage *out;

    { /* name */
        if (SPICE_UNLIKELY((start + 0) > message_end)) {
            goto error;
        }
        name__nelements = message_end - (start + 0);

        name__nw_size = name__nelements;
        name__mem_size = sizeof(int8_t) * name__nelements;
    }

    nw_size = 0 + name__nw_size;
    mem_size = sizeof(SpiceMsgMainArrayMessage) + name__mem_size;

    /* Check if message fits in reported side */
    if (nw_size > (uintptr_t) (message_end - start)) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainArrayMessage);
    in = start;

    out = (SpiceMsgMainArrayMessage *)data;

    verify(sizeof(out->name) == 0);
    memcpy(out->name, in, name__nelements);
    in += name__nelements;
    end += name__nelements;

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    free(data);
    return NULL;
}

static uint8_t * parse_msg_main_Zeroes(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    uint64_t nw_size;
    uint64_t mem_size;
    uint8_t *in, *end;
    SpiceMsgMainZeroes *out;

    nw_size = 7;
    mem_size = sizeof(SpiceMsgMainZeroes);

    /* Check if message fits in reported side */
    if (nw_size > (uintptr_t) (message_end - start)) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainZeroes);
    in = start;

    out = (SpiceMsgMainZeroes *)data;

    consume_uint8(&in);
    out->n = consume_uint16(&in);
    consume_uint32(&in);

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    free(data);
    return NULL;
}

static uint8_t * parse_msg_main_channels_list(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    uint64_t nw_size;
    uint64_t mem_size;
    uint8_t *in, *end;
    uint64_t channels__nw_size, channels__mem_size;
    uint64_t channels__nelements;
    SpiceMsgChannels *out;
    uint32_t i;

    { /* channels */
        uint32_t num_of_channels__value;
        pos = start + 0;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        num_of_channels__value = read_uint32(pos);
        channels__nelements = num_of_channels__value;

        channels__nw_size = (2) * channels__nelements;
        channels__mem_size = sizeof(uint16_t) * channels__nelements;
    }

    nw_size = 4 + channels__nw_size;
    mem_size = sizeof(SpiceMsgChannels) + channels__mem_size;

    /* Check if message fits in reported side */
    if (nw_size > (uintptr_t) (message_end - start)) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgChannels);
    in = start;

    out = (SpiceMsgChannels *)data;

    out->num_of_channels = consume_uint32(&in);
    verify(sizeof(out->channels) == 0);
    for (i = 0; i < channels__nelements; i++) {
        out->channels[i] = consume_uint16(&in);
        end += sizeof(uint16_t);
    }

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    free(data);
    return NULL;
}

static uint8_t * parse_msg_main_LenMessage(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    uint64_t nw_size;
    uint64_t mem_size;
    uint8_t *in, *end;
    uint64_t data__nw_size, data__mem_size;
    uint64_t data__nelements;
    SpiceMsgMainLenMessage *out;
    uint64_t dummy__nelements;
    uint32_t i;

    { /* data */
        if (SPICE_UNLIKELY((start + 8) > message_end)) {
            goto error;
        }
        data__nelements = message_end - (start + 8);

        data__nw_size = data__nelements;
        data__mem_size = sizeof(uint8_t) * data__nelements;
    }

    nw_size = 8 + data__nw_size;
    mem_size = sizeof(SpiceMsgMainLenMessage) + data__mem_size;

    /* Check if message fits in reported side */
    if (nw_size > (uintptr_t) (message_end - start)) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainLenMessage);
    in = start;

    out = (SpiceMsgMainLenMessage *)data;

    dummy__nelements = 2;
    for (i = 0; i < dummy__nelements; i++) {
        out->dummy[i] = consume_uint32(&in);
    }
    verify(sizeof(out->data) == 0);
    memcpy(out->data, in, data__nelements);
    in += data__nelements;
    end += data__nelements;

    assert(in <= message_end);
    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    free(data);
    return NULL;
}

static uint8_t * parse_array_uint8_terminated(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info)
{
    uint8_t *in = message_start + this_ptr_info->offset;
    uint8_t *end;

    end = struct_data;
    memcpy(end, in, this_ptr_info->nelements);
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
    ((char *) (end))[this_ptr_info->nelements] = 0;
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
    in += this_ptr_info->nelements;
    end += this_ptr_info->nelements;
    end += 1;
    return end;
}

static uint8_t * parse_msg_main_ZeroLen1(uint8_t *message_start, uint8_t *message_end, size_t *size, message_destructor_t *free_message)
{
    SPICE_GNUC_UNUSED uint8_t *pos;
    uint8_t *start = message_start;
    uint8_t *data = NULL;
    uint64_t nw_size;
    uint64_t mem_size;
    uint8_t *in, *end;
    SPICE_GNUC_UNUSED intptr_t ptr_size;
    uint32_t n_ptr=0;
    PointerInfo ptr_info[2];
    uint64_t txt2__extra_size;
    uint64_t txt2__array__nelements;
    uint64_t txt3__nw_size, txt3__mem_size;
    uint64_t txt3__nelements;
    uint32_t txt3__saved_size = 0;
    uint64_t txt4__nw_size, txt4__mem_size;
    uint64_t txt4__nelements;
    SpiceMsgMainZeroLen1 *out;
    uint64_t txt1__nelements;
    uint64_t txt3__array__nelements;
    uint32_t i;

    { /* txt2 */
        uint32_t txt2__value;
        uint64_t txt2__array__nw_size;
        uint64_t txt2__array__mem_size;
        uint32_t txt2_len__value;
        pos = (start + 9);
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        txt2__value = read_uint32(pos);
        if (SPICE_UNLIKELY(txt2__value >= (uintptr_t) (message_end - message_start))) {
            goto error;
        }
        pos = start + 5;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        txt2_len__value = read_uint32(pos);
        txt2__array__nelements = txt2_len__value;

        txt2__array__nw_size = txt2__array__nelements;
        txt2__array__mem_size = sizeof(uint8_t) * txt2__array__nelements + sizeof(uint8_t);
        txt2__array__mem_size = SPICE_ALIGN(txt2__array__mem_size, 4);
        if (SPICE_UNLIKELY(txt2__array__nw_size > (uintptr_t) (message_end - message_start - txt2__value))) {
            goto error;
        }
        txt2__extra_size = txt2__array__mem_size + /* for alignment */ 3;
    }

    { /* txt3 */
        uint32_t txt2_len__value;
        pos = start + 5;
        if (SPICE_UNLIKELY(pos + 4 > message_end)) {
            goto error;
        }
        txt2_len__value = read_uint32(pos);
        txt3__nelements = txt2_len__value;

        txt3__nw_size = txt3__nelements;
        txt3__mem_size = sizeof(uint8_t) * txt3__nelements + sizeof(uint8_t);
        txt3__mem_size = SPICE_ALIGN(txt3__mem_size, 4);
        txt3__saved_size = txt3__nw_size;
    }

    { /* txt4 */
        uint16_t txt4_len__value;
        pos = start + 17 + txt3__nw_size;
        if (SPICE_UNLIKELY(pos + 2 > message_end)) {
            goto error;
        }
        txt4_len__value = read_uint16(pos);
        txt4__nelements = txt4_len__value;

        txt4__nw_size = txt4__nelements;
        txt4__mem_size = sizeof(uint8_t) * txt4__nelements + sizeof(uint8_t);
        txt4__mem_size = SPICE_ALIGN(txt4__mem_size, 4);
    }

    nw_size = 19 + txt3__nw_size + txt4__nw_size;
    mem_size = sizeof(SpiceMsgMainZeroLen1) + txt2__extra_size + txt3__mem_size + txt4__mem_size;

    /* Check if message fits in reported side */
    if (nw_size > (uintptr_t) (message_end - start)) {
        return NULL;
    }

    /* Validated extents and calculated size */
    data = (uint8_t *)(mem_size > UINT32_MAX ? NULL : malloc(mem_size));
    if (SPICE_UNLIKELY(data == NULL)) {
        goto error;
    }
    end = data + sizeof(SpiceMsgMainZeroLen1);
    in = start;

    out = (SpiceMsgMainZeroLen1 *)data;

    txt1__nelements = 4;
    memcpy(out->txt1, in, txt1__nelements);
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
    ((char *) (out->txt1))[txt1__nelements] = 0;
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
    in += txt1__nelements;
    out->sep1 = consume_uint8(&in);
    out->txt2_len = consume_uint32(&in);
    ptr_info[n_ptr].offset = consume_uint32(&in);
    ptr_info[n_ptr].parse = parse_array_uint8_terminated;
    ptr_info[n_ptr].dest = (void **)&out->txt2;
    ptr_info[n_ptr].nelements = txt2__array__nelements;
    n_ptr++;
    ptr_info[n_ptr].offset = in - start;
    ptr_info[n_ptr].parse = parse_array_uint8_terminated;
    ptr_info[n_ptr].dest = (void **)&out->txt3;
    txt3__array__nelements = out->txt2_len;
    ptr_info[n_ptr].nelements = txt3__array__nelements;
    n_ptr++;
    in += txt3__saved_size;
    out->n = consume_uint32(&in);
    out->txt4_len = consume_uint16(&in);
    verify(sizeof(out->txt4) == 0);
    memcpy(out->txt4, in, txt4__nelements);
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
    ((char *) (out->txt4))[txt4__nelements] = 0;
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
    in += txt4__nelements;
    end += txt4__nelements;
    end += 1;

    assert(in <= message_end);

    for (i = 0; i < n_ptr; i++) {
        if (ptr_info[i].offset == 0) {
            *ptr_info[i].dest = NULL;
        } else {
            /* Align to 32 bit */
            end = (uint8_t *)SPICE_ALIGN((uintptr_t)end, 4);
            *ptr_info[i].dest = (void *)end;
            end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i]);
            if (SPICE_UNLIKELY(end == NULL)) {
                goto error;
            }
        }
    }

    assert(end <= data + mem_size);

    *size = end - data;
    *free_message = (message_destructor_t) free;
    return data;

   error:
    free(data);
    return NULL;
}

static uint8_t * parse_TestChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
{
    static parse_msg_func_t funcs1[6] =  {
        parse_msg_main_ShortDataSubMarshall,
        parse_msg_main_ArrayMessage,
        parse_msg_main_Zeroes,
        parse_msg_main_channels_list,
        parse_msg_main_LenMessage,
        parse_msg_main_ZeroLen1
    };
    if (message_type >= 1 && message_type < 7) {
        return funcs1[message_type-1](message_start, message_end, size_out, free_message);
    }
    return NULL;
}

spice_parse_channel_func_t spice_get_server_channel_parser_test(uint32_t channel, unsigned int *max_message_type)
{
    static struct {spice_parse_channel_func_t func; unsigned int max_messages; } channels[2] =  {
        { NULL, 0 },
        { parse_TestChannel_msg, 6}
    };
    if (channel < 2) {
        if (max_message_type != NULL) {
            *max_message_type = channels[channel].max_messages;
        }
        return channels[channel].func;
    }
    return NULL;
}

uint8_t * spice_parse_msg_test(uint8_t *message_start, uint8_t *message_end, uint32_t channel, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
{
    spice_parse_channel_func_t func;
    func = spice_get_server_channel_parser_test(channel, NULL);
    if (func != NULL) {
        return func(message_start, message_end, message_type, minor, size_out, free_message);
    }
    return NULL;
}
