protobuf-gen-lua 不能支持int64的解决方法
protobuf-gen-lua 不能支持int64,序列化的时候数据出错,少了一个字节,很大概率出现。为此,下面就给大家介绍下protobuf-gen-lua 不能支持int64的解决办法
不知道是 Lua5.1.4的问题还是 protobuf-gen-lua 的问题。
后面有时间来升级SLua到 Lua5.3再测试
前天到 Github 上搜索,发现网友 zhenmu 在 issues 下面提到了这个问题,而且提出了解决方案供我尝试,在我测试无效之后,又提供了完整的修改,实在是非常感谢!
Github原址:https://github.com/sean-lin/protoc-gen-lua/issues/23
因为我对Lua不是很熟悉,所以只能大致的说出来缘由:
1、Protobuf-lua-gen 默认是不支持 int64 以及 UINT64,并不是不能支持,而是作者说他们当时候不需要 int64和UINT64,所以没有加上 。
2、Protobuf-lua-gen 默认对int64是当作int32来处理,UINT64是当作UINT32来处理的。
3、由于INT64被当成了int处理,所以数据的大小范围序列化出来的数据Size出错。
所以Github 网友提供的修改方案就是添加 INT64 的数据大小判断,使Protobuf 序列化的时候生成正确的数据。
以下来自 Github 网友 zhenmu 的解决方法 ( https://github.com/sean-lin/protoc-gen-lua/issues/23 ):
1.encoder.lua
function _VarintSize(value) if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end return 5 end function _SignedVarintSize(value) if value < 0 then return 10 end if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end return 5 end改成
function _VarintSize(value) if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end if value <= 0x7ffffffff then return 5 end if value <= 0x3ffffffffff then return 6 end if value <= 0x1ffffffffffff then return 7 end if value <= 0xffffffffffffff then return 8 end if value <= 0x7fffffffffffffff then return 9 end return 10 end function _SignedVarintSize(value) if value < 0 then return 10 end if value <= 0x7f then return 1 end if value <= 0x3fff then return 2 end if value <= 0x1fffff then return 3 end if value <= 0xfffffff then return 4 end if value <= 0x7ffffffff then return 5 end if value <= 0x3ffffffffff then return 6 end if value <= 0x1ffffffffffff then return 7 end if value <= 0xffffffffffffff then return 8 end if value <= 0x7fffffffffffffff then return 9 end return 10 end
2.ware_format里 (非必要?)
local function _VarUInt64ByteSizeNoTag(uint64) if uint64 <= 0x7f then return 1 end if uint64 <= 0x3fff then return 2 end if uint64 <= 0x1fffff then return 3 end if uint64 <= 0xfffffff then return 4 end return 5 end
改成
local function _VarUInt64ByteSizeNoTag(uint64) if uint64 <= 0x7f then return 1 end if uint64 <= 0x3fff then return 2 end if uint64 <= 0x1fffff then return 3 end if uint64 <= 0xfffffff then return 4 end if uint64 <= 0x7ffffffff then return 5 end if uint64 <= 0x3ffffffffff then return 6 end if uint64 <= 0x1ffffffffffff then return 7 end if uint64 <= 0xffffffffffffff then return 8 end if uint64 <= 0x7fffffffffffffff then return 9 end return 10 end
type_checkers.lua里 (这个范围是我们自己根据一些情况 设定了一个范围)增加
function Int64ValueChecker() local _MIN = -562949953421312 local _MAX = 562949953421312 return function(proposed_value) if type(proposed_value) ~= 'number' then error(string.format('%s has type %s, but expected one of: number', proposed_value, type(proposed_value))) end if _MIN > proposed_value or proposed_value > _MAX then error('Value out of range: ' .. proposed_value) end end end function Uint64ValueChecker(IntValueChecker) local _MIN = 0 local _MAX = 1125899906842624
我在项目里设置这里为上限和下限。
4.protobuf.lua 里
[FieldDescriptor.CPPTYPE_INT64] = type_checkers.Int32ValueChecker(), [FieldDescriptor.CPPTYPE_UINT64] = type_checkers.Uint32ValueChecker(),
改成
[FieldDescriptor.CPPTYPE_INT64] = type_checkers.Int64ValueChecker(), [FieldDescriptor.CPPTYPE_UINT64] = type_checkers.Uint64ValueChecker(),
也可以下载我修改好的文件替换
下载地址:http://pan.baidu.com/s/1eRyWJdC