Google Protocol Buffer

由.proto文件生成C++的相关文件时,一个对应的的类和相关功能的对应关系如下:

Varint的相关实现(节省大小,小的数字从4个字节变为一个字节):

对于编码,遇到的第一个字节,需要检查高位,如果高位为0,说明这个最后个byte,使用剩余的7位标识真实的值,在这种情况下,最大表示的值是2^7(128),超过128的数,至少需要使用两个字节。

对于key-value的实现,比如上面使用varint编码完后,对应的是Value字段,对于key字段,使用的是
(field_number << 3) | wire_type
wire_type的表示:

所以对于:

message LogonReqMessage {
required int64 acctID = 1;
required string passwd = 2;
}


LogonReqMessage message;

message.set_acctid(300);
message.set_passwd("hello");
编码后的结果:

 

 

acctID:
Key: 0x08 ->(1<<3 | 0)
Value: 0xac 0x12-> 1010 1100 0000 0010 ->300

Passwd:
Key:0x12 ->(2<<3 |2)
Value:0x05(个数) 0x68 0x65 0x6c 0x6c 0x6f->hello

这里可以看到,使用field_number的目的是可以显示的标识一个字段,这样的话可以在两边声明不一致的时候,最大可能的保持兼容,只要能在被序列化的一端找到相关的number就可以解码,同时对于repeated字段,可以显示的表示当前内存所对应的字段,如果将passwd 改为repeated,并设置两个值(12 05 … 12 05…):

 

 

posted @ 2017-04-10 08:03  llluiop  阅读(119)  评论(0编辑  收藏  举报