protocol buffers 编码规则(二)
补充负数, 浮点数, 字符串, 嵌套结构的编码规则
负数
因为负数是用最高位表示符号位, 使用 varint 去编码会占用特别多的字节(10 字节), 所以 varint 不适合负数, 为了解决这个问题 pb 定义了 sint32, sint64 的类型, 先使用 ZigZag 编码, 再使用 varint 编码.
仅使用 varint 编码负数的结果:
08 | ff fe ff ff ff ff ff ff ff 01
具体编码过程有点复杂, 就跳过了, 总之除 tag 外会占用 10 字节, 对比上文的正数占用非常大的空间.
而 ZigZag 编码是将有符号的整数全部转换成正整数:

这样再使用 varint 编码就可以压缩大小.
非 varint 数字
使用一般编码, double 占用 8 字节(64 bit), float 占用 4 字节(32 bit), 此处没有优化.
字符串
字符串遵循 tag + length + data 的规则, length 使用 varint 编码
1 | message HelloRequest { |
编码为
0a | 05 | 77 6f 72 6c 64
0a 为 tag, 05 为长度
嵌套消息体
1 | message HelloRequestAgain { |
嵌套的消息体都会转成 string 编码:
0a | 07 | 0a 05 77 6f 72 6c 64
0a 为 tag, 07 为长度