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的类型 编码存储说明
0 int32, int64, uint32, uint64, sint32, sint64, bool, enum
varint、zigint
1 fixed64, sfixed64, double 64-bit
2 string, 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

protoc-gen-lua的更多相关文章

  1. thrift的lua实现

    最近要进行系统升级,后台的数据是根据城市区分的.担心新系统的稳定性及新数据的准确性,计划部分城市采用新接口.接口的入参里没有城市信息,只有经纬度坐标,需要调用一个thrift接口来根据坐标获取城市信息 ...

  2. uLua学习笔记(三):Unity3D和Lua之间的相互调用

    这篇笔记主要集中学习一下uLua和Unity3D之间相互调用的方法,我们导入了uLua之后,现在会弹出一个类似学习屏幕的东西,如下: 先赞一个! Unity3D调用Lua Unity3D调用Lua的方 ...

  3. Java调用Lua(转)

    Java 调用 Lua app发版成本高,覆盖速度慢,覆盖率页低.一些策略上的东西如果能够从服务端控制会方便一些.所以考虑使用Lua这种嵌入式语言作为策略实现,Java则是宿主语言. 总体上看是一个模 ...

  4. thrift的lua

    thrift的lua实现 最近要进行系统升级,后台的数据是根据城市区分的.担心新系统的稳定性及新数据的准确性,计划部分城市采用新接口.接口的入参里没有城市信息,只有经纬度坐标,需要调用一个thrift ...

  5. Thrift的TBinaryProtocol二进制协议分析

    先上张图,说明一下thrift的二进制协议是什么东东. 报文格式编码: bool类型: 一个字节的类型,两个字节的字段编号,一个字节的值(true:1,false:0). Byte类型: 一个字节的类 ...

  6. ulua学习笔记(二):官方资料及问题解决方案

    uLua&SimpleFramework入门视频教程网盘地址 视频教程地址 http://pan.baidu.com/s/1gd8fG4N游戏框架地址 https://github.com/j ...

  7. unity3d热更新插件uLua学习整理

    前言 IOS不能热更新,不是因为不能用反射,是因为System.Reflection.Assembly.Load 无法使用System.Reflection.Emit 无法使用System.CodeD ...

  8. Unity编程笔录--ulua+PureMVC框架简单热更新使用

    ulua+PureMVC框架简单热更新使用 前言: 1:作者官网论坛 首先介绍的是这个框架是一位大牛  骏擎[CP]  jarjin   写的,据说原本是"非常多人不知道怎么使用Ulua,所 ...

  9. LuaFramework 学习

    LuaFramework_UGUI_V2 https://github.com/jarjin/LuaFramework_UGUI_V2 using UnityEngine; using LuaInte ...

  10. 热更新解决方案--tolua学习笔记

    一.tolua使用准备工作:从GitHub上下载tolua(说明:这篇笔记使用的Unity版本是2019.4.18f1c1,使用的tolua是2021年4月9日从GitHub上Clone的tolua工 ...

随机推荐

  1. pip

    查看安装的包 pip list

  2. Spring学习之AOP

    Spring-AOP(Aspect-orented programming) 在业务流程中插入与业务无关的逻辑,这样的逻辑称为Cross-cutting concerns,将Crossing-cutt ...

  3. 【大数阶乘】NYOJ-28

    大数阶乘 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 我们都知道如何计算一个数的阶乘,可是,如果这个数很大呢,我们该如何去计算它并输出它?   输入 输入一个整数 ...

  4. TCP/IP详解学习笔记(6)-UDP协议

    1.UDP简要介绍 UDP是传输层协议,和TCP协议处于一个分层中,但是与TCP协议不同,UDP协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议. 2.UDP协议头 2.1.UDP端口号 ...

  5. POJ 2421 Constructing Roads

    题意:要在n个城市之间建造公路,使城市之间能互相联通,告诉每个城市之间建公路的费用,和已经建好的公路,求最小费用. 解法:最小生成树.先把已经建好的边加进去再跑kruskal或者prim什么的. 代码 ...

  6. linux命令——rm

    rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除了链接,原有文件均保持不变. rm是一个危险的命令,使用的 ...

  7. UVA 12532-Interval Product(BIT)

    题意: 给n个数字的序列,C v p 把v位上的数字置成p , S l r代表求区间[l,r]各数字相乘得数的符号,对于每个S输出所得符号(’+‘,’-‘,’0‘) 分析: 开两个数组表示区间负数的个 ...

  8. 【剑指offer 面试题12】打印1到最大的n位数

    思路: 用n位字符数组表示n位数,通过递归的方式逐层(位)遍历,递归终止时打印. #include "stdio.h" #include "string.h" ...

  9. 用duilib制作仿QQ2013动态背景登录器

    转载请说明原出处,谢谢~~ 在上一篇博客里,我修复了CActiveXUI控件的bug,从而可以使用flash动画来制作程序的背景,这篇博客说明一下应该怎么使用CActiveXUI控件创建透明无窗体的背 ...

  10. 单片机usb转串口的时灵时不灵的解答

    写这篇博客,首先检讨一下自己,因为以前串口的程序,也和步进电机一样,时灵时不灵,我现在终于知道这是为什么了,因为51上有三个串口,一个公口,一个母口,一个usb转串口,这样的话,串口有3个了,我手头上 ...