spice的序列化与反序列化

marshaller是序列化和反序列使用的工具类,主要用在打包中。
其中,SpiceMessageMarshallers定义在生成文件generated_client_marshallers.h中
typedef struct {
    void (*msgc_ack_sync)(SpiceMarshaller *m, const SpiceMsgcAckSync *msg);
    void (*msg_SpiceMsgEmpty)(SpiceMarshaller *m, const SpiceMsgEmpty *msg);
    void (*msgc_pong)(SpiceMarshaller *m, const SpiceMsgPing *msg);
    void (*msg_SpiceMsgData)(SpiceMarshaller *m, const SpiceMsgData *msg);
    void (*msgc_disconnecting)(SpiceMarshaller *m, const SpiceMsgDisconnect *msg);
    void (*msgc_main_client_info)(SpiceMarshaller *m, const SpiceMsgcClientInfo *msg);
    void (*msgc_main_mouse_mode_request)(SpiceMarshaller *m, const SpiceMsgcMainMouseModeRequest *msg);
    void (*msgc_main_agent_start)(SpiceMarshaller *m, const SpiceMsgMainAgentTokens *msg);
    void (*msgc_main_agent_token)(SpiceMarshaller *m, const SpiceMsgMainAgentTokens *msg);
    void (*msgc_main_migrate_dst_do_seamless)(SpiceMarshaller *m, const SpiceMsgcMainMigrateDstDoSeamless *msg);
    void (*msgc_main_client_capability)(SpiceMarshaller *m, const SpiceMsgcMainClientCapability *msg);
    void (*msgc_display_init)(SpiceMarshaller *m, const SpiceMsgcDisplayInit *msg);
    void (*msgc_display_stream_report)(SpiceMarshaller *m, const SpiceMsgcDisplayStreamReport *msg);
    void (*msgc_display_preferred_compression)(SpiceMarshaller *m, const SpiceMsgcDisplayPreferredCompression *msg);
    void (*msgc_display_gl_draw_done)(SpiceMarshaller *m, const SpiceMsgcDisplayGlDrawDone *msg);
    void (*msgc_display_preferred_video_codec_type)(SpiceMarshaller *m, const SpiceMsgcDisplayPreferredVideoCodecType *msg);
    void (*msgc_display_client_draw_ack)(SpiceMarshaller *m, const SpiceMsgcDisplayClientDrawAck *msg);
    void (*msgc_inputs_key_down)(SpiceMarshaller *m, const SpiceMsgcKeyDown *msg);
    void (*msgc_inputs_key_up)(SpiceMarshaller *m, const SpiceMsgcKeyUp *msg);
    void (*msgc_inputs_key_modifiers)(SpiceMarshaller *m, const SpiceMsgcKeyModifiers *msg);
    void (*msgc_inputs_mouse_motion)(SpiceMarshaller *m, const SpiceMsgcMouseMotion *msg);
    void (*msgc_inputs_mouse_position)(SpiceMarshaller *m, const SpiceMsgcMousePosition *msg);
    void (*msgc_inputs_mouse_press)(SpiceMarshaller *m, const SpiceMsgcMousePress *msg);
    void (*msgc_inputs_mouse_release)(SpiceMarshaller *m, const SpiceMsgcMouseRelease *msg);
    void (*msgc_record_data)(SpiceMarshaller *m, const SpiceMsgPlaybackPacket *msg);
    void (*msgc_record_mode)(SpiceMarshaller *m, const SpiceMsgPlaybackMode *msg);
    void (*msgc_record_start_mark)(SpiceMarshaller *m, const SpiceMsgcRecordStartMark *msg);
#ifdef USE_SMARTCARD
    void (*msgc_smartcard_data)(SpiceMarshaller *m, const VSCMsgHeader *msg);
#endif /* USE_SMARTCARD */
    void (*msg_SpiceMsgCompressedData)(SpiceMarshaller *m, const SpiceMsgCompressedData *msg);
    void (*msgc_port_event)(SpiceMarshaller *m, const SpiceMsgcPortEvent *msg);
} SpiceMessageMarshallers;
实现在generated_client_marshaller.c中
SpiceMessageMarshallers * spice_message_marshallers_get(void)
{
    static SpiceMessageMarshallers marshallers = {0};

    marshallers.msg_SpiceMsgCompressedData = spice_marshall_SpiceMsgCompressedData;
    marshallers.msg_SpiceMsgData = spice_marshall_SpiceMsgData;
    marshallers.msg_SpiceMsgEmpty = spice_marshall_SpiceMsgEmpty;
    marshallers.msgc_ack_sync = spice_marshall_msgc_ack_sync;
    marshallers.msgc_disconnecting = spice_marshall_msgc_disconnecting;
    marshallers.msgc_display_client_draw_ack = spice_marshall_msgc_display_client_draw_ack;
    marshallers.msgc_display_gl_draw_done = spice_marshall_msgc_display_gl_draw_done;
    marshallers.msgc_display_init = spice_marshall_msgc_display_init;
    marshallers.msgc_display_preferred_compression = spice_marshall_msgc_display_preferred_compression;
    marshallers.msgc_display_preferred_video_codec_type = spice_marshall_msgc_display_preferred_video_codec_type;
    marshallers.msgc_display_stream_report = spice_marshall_msgc_display_stream_report;
    marshallers.msgc_inputs_key_down = spice_marshall_msgc_inputs_key_down;
    marshallers.msgc_inputs_key_modifiers = spice_marshall_msgc_inputs_key_modifiers;
    marshallers.msgc_inputs_key_up = spice_marshall_msgc_inputs_key_up;
    marshallers.msgc_inputs_mouse_motion = spice_marshall_msgc_inputs_mouse_motion;
    marshallers.msgc_inputs_mouse_position = spice_marshall_msgc_inputs_mouse_position;
    marshallers.msgc_inputs_mouse_press = spice_marshall_msgc_inputs_mouse_press;
    marshallers.msgc_inputs_mouse_release = spice_marshall_msgc_inputs_mouse_release;
    marshallers.msgc_main_agent_start = spice_marshall_msgc_main_agent_start;
    marshallers.msgc_main_agent_token = spice_marshall_msgc_main_agent_token;
    marshallers.msgc_main_client_capability = spice_marshall_msgc_main_client_capability;
    marshallers.msgc_main_client_info = spice_marshall_msgc_main_client_info;
    marshallers.msgc_main_migrate_dst_do_seamless = spice_marshall_msgc_main_migrate_dst_do_seamless;
    marshallers.msgc_main_mouse_mode_request = spice_marshall_msgc_main_mouse_mode_request;
    marshallers.msgc_pong = spice_marshall_msgc_pong;
    marshallers.msgc_port_event = spice_marshall_msgc_port_event;
    marshallers.msgc_record_data = spice_marshall_msgc_record_data;
    marshallers.msgc_record_mode = spice_marshall_msgc_record_mode;
    marshallers.msgc_record_start_mark = spice_marshall_msgc_record_start_mark;
#ifdef USE_SMARTCARD
    marshallers.msgc_smartcard_data = spice_marshall_msgc_smartcard_data;
#endif /* USE_SMARTCARD */

    return &marshallers;
}
使用SpiceChannelPrivate中,记录所有的协议转换函数
struct _SpiceChannelPrivate {    
        ...  
        SpiceMessageMarshallers *marshallers;  
         ...
}
在link时候初始化
/* coroutine context */
static void spice_channel_send_link(SpiceChannel *channel)
{
    ...
    switch (protocol) {
    case 1: /* protocol 1 == major 1, old 0.4 protocol, last active minor */
        g_critical("deprecated major %d", protocol);
        return;
    case SPICE_VERSION_MAJOR: /* protocol 2 == current */
        c->link_hdr.major_version = SPICE_VERSION_MAJOR;
        c->link_hdr.minor_version = SPICE_VERSION_MINOR;
        c->parser = spice_get_server_channel_parser(c->channel_type, NULL);
        c->marshallers = spice_message_marshallers_get();
        break;
    default:
        g_critical("unknown major %d", protocol);
        return;
    }
    ...
}
spice_message_marshallers_get定义spice-common中在client_marshallers.h源文件中
#ifndef H_SPICE_COMMON_CLIENT_MARSHALLERS
#define H_SPICE_COMMON_CLIENT_MARSHALLERS

#include 
#include "messages.h"
#include "common/generated_client_marshallers.h"
#include "marshaller.h"

SPICE_BEGIN_DECLS
SpiceMessageMarshallers *spice_message_marshallers_get(void);
SPICE_END_DECLS

#endif

static SpiceMsgOut* mouse_position(SpiceInputsChannel *channel)
{
    SpiceInputsChannelPrivate *c = channel->priv;
    SpiceMsgcMousePosition position;
    SpiceMsgOut *msg;
    if (c->dpy == -1)
        return NULL;

    /* CHANNEL_DEBUG(channel, "%s: +%d+%d", __FUNCTION__, c->x, c->y); */
    position.buttons_state = c->bs;
    position.x             = c->x;
    position.y             = c->y;
    position.display_id    = c->dpy;
    msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_MOUSE_POSITION);
    msg->marshallers->msgc_inputs_mouse_position(msg->marshaller, &position);
    c->motion_count++;
    c->dpy = -1;

    return msg;
}

你可能感兴趣的:(spice,spice-gtk)