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 <spice/protocol.h>
#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

如发送鼠标位置给服务器需要先序列化,先打包头spice_msg_out_new,然后打包数据msgc_inputs_mouse_position:

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;
}

调用marshallers.msgc_inputs_mouse_position = spice_marshall_msgc_inputs_mouse_position;

static void spice_marshall_msgc_inputs_mouse_position(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED const SpiceMsgcMousePosition *msg)
{
    SPICE_GNUC_UNUSED SpiceMarshaller *m2;
    const SpiceMsgcMousePosition *src;
    src = (const SpiceMsgcMousePosition *)msg;

    spice_marshaller_add_uint32(m, src->x);
    spice_marshaller_add_uint32(m, src->y);
    spice_marshaller_add_uint16(m, src->buttons_state);
    spice_marshaller_add_uint8(m, src->display_id);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值