protoc-gen-lua

lua里使用proto buffer

protoc-gen-lua

官方不维护了,自己维护个:protoc-gen-lua

  1. int64支持,将64位int转换成lua的string。
  2. message相互嵌套引用,不依赖定义的顺序。
  3. import的bug

protoc-gen-lua int64支持

lua 5.1里使用double表示number,然后double最多兼容int53。
项目中协议已经使用int64了,为了支持int64,将int64全部转换成string来处理。

看懂protoc-gen-lua的decode、encode代码,在熟悉下protbuf的存储格式。然后修改编解码部分。

protoc-gen-lua import bug

官方的protoc字段名都是定义成local变量,外部不可访问,import引用就挂了。
修改后,字段名都当成module里的全局变量,损失性能,但是外部可以访问。

proto buffer的一些细节

google开源的序列化工具,类似json,二机制格式。

存储格式

protobuf把message保存成一系列key-value对。
key由每个field的index和type来确定,算法key = (index<<3) | type。使用varint格式保存,所以index小于16才能用一个字节保存。
value随type不同,有不同的保存方式。

type对于的message的类型编码存储说明
0int32, int64, uint32, uint64, sint32, sint64, bool, enum
varint、zigint
1fixed64, sfixed64, double64-bit
2string, bytes, embedded messages, packed repeated fields长度(varint) + 内容
5

fixed32, sfixed32, float

32-bit

额外说明下packed repeated fields

对于repeated类型的字段,可以不用连续存储,每个都是key+value,只是key都是一样的。
使用packed可以达到压缩key的效果,整体连续存储为key+size+value+value+...
例子:

 
 
  1. message Test {
  2. repeated int32 d = 1 [packed=true];
  3. }
  4. 假设添加两个数字`1,128`
  5. 序列号结果:
  6. 08 key
  7. 03 字节数
  8. 01 数字1
  9. 80 01 数字128

varint

变长int,用一个或多个字节表示整数。值越小,字节数越少。整数在这里都是当成无符号

具体这么做:

  1. varint的每个字节的最高bit位表示数字序列有没有结束。1表示没有结束,0表示结束。
  2. 每个字节的剩余7个bit位存储数字的有效bit位。如果数字小于128,就只要1个字节了,如64表示为01000000
  3. 字节序使用的小端序。

数字150转换过程:

  1. 二机制表示10010110
  2. 划分7bit位00000001 00010110
  3. 反序00010110 00000001
  4. 设置最高位10010110 00000001

zigint

varint有个缺点,如果是负数,就达不到压缩字节数的效果。因为最高位是1,是个有效位。
如int64类型的-1,要使用10个字节,而绝对值只有1。

zigint就是针对这种情况处理的。先用zigzag重新编码下数字,再使用varint存储。
int64转换公式:

  1. zig_int = (signed_int << 1) ^ (signed_int >> 63)
  2. signed_int = (zig_int >> 1) ^ - (int64_t)(n & 1)

这种表示方法类似于1个bit位保存符号为,其他的保存绝对值。
但是64用zigint标识就得两个字节了,保存的是128。

搜集的资料等

  1. protobuf序列化原理
  2. Google Protocol Buffer 的使用和原理
  3. Gooogle Protoc-gen-lua
  4. protoc-gen-lua github 好像不维护了
  5. protoc-gen-lua int64支持,有条件的,实际是int32才能不出错
  6. protoc-gen-lua int64支持,将64位int转换成lua的string,修改不少bug




转载于:https://www.cnblogs.com/treert/p/5908022.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值