为了方式封装和解析二进制数据 给tolua添加 ipack库 和一个lua的解析类 ByteArray
在lua中解析byte[]数据
ipcak https://github.com/LuaDist/lpack
参考 https://forum.cocos.com/t/bytearray/14319
1 从git上获得 ipack库
ipcak 库修改
2 在tolua-runtime库 https://github.com/topameng/tolua_runtime
添加ipack 注册 找到tolua.c文件 tolua_openlibs方法 添加这个方法
3 生成对应平台的库文件 这个教程后期出 不过需要这个功能的人应该也是会的
4 添加LUA代码
ipack =require 'ipack'
local setmetatable = setmetatable
local ByteArray =
{
}
ByteArray.__index = ByteArray
local typeEnum=
{
OP_ZSTRING= 'z',--/* zero-terminated string */
OP_BSTRING= 'p',--/* string preceded by length byte */
OP_WSTRING= 'P',--/* string preceded by length word */
OP_SSTRING= 'a',--/* string preceded by length size_t */
OP_STRING= 'A',--/* string */
OP_FLOAT= 'f',--/* float */
OP_DOUBLE= 'd',--/* double */
OP_NUMBER= 'n',--/* Lua number */
OP_BYTE = 'c',--/* char is byte*/
OP_UBYTE = 'b',--/* byte = unsigned char */
OP_SHORT ='h',--/* short */
OP_USHORT= 'H',--/* unsigned short */
OP_INT = 'i',--/* int */
OP_UINT = 'I',--/* unsigned int */
OP_LONG = 'l',--/* long */
OP_ULONG= 'L',--/* unsigned long */
OP_LITTLEENDIAN= '<',--/* little endian */
OP_BIGENDIAN= '>',--/* big endian */
OP_NATIVE= '=',--/* native endian */
}
--local OP_ZSTRING= 'z'--/* zero-terminated string */
--local OP_BSTRING= 'p'--/* string preceded by length byte */
--local OP_WSTRING= 'P'--/* string preceded by length word */
--local OP_SSTRING= 'a'--/* string preceded by length size_t */
--local OP_STRING= 'A'--/* string */
--local OP_FLOAT= 'f'--/* float */
--local OP_DOUBLE= 'd'--/* double */
--local OP_NUMBER= 'n'--/* Lua number */
--local OP_CHAR = 'c'--/* char */
--local OP_BYTE = 'b'--/* byte = unsigned char */
--local OP_SHORT ='h'--/* short */
--local OP_USHORT= 'H'--/* unsigned short */
--local OP_INT = 'i'--/* int */
--local OP_UINT = 'I'--/* unsigned int */
--local OP_LONG = 'l'--/* long */
--local OP_ULONG= 'L'--/* unsigned long */
--local OP_LITTLEENDIAN= '<'--/* little endian */
--local OP_BIGENDIAN= '>'--/* big endian */
--local OP_NATIVE= '='--/* native endian */
--
--@packedStr --已经打包的字节字符串 如果是创建写bytearray 此参数不需要传nil
--@endian --字节序 不传默认小字节序
--]]
function ByteArray:new(packedStr, endian)
local t = {}
setmetatable(t, self)
self.packedStr =packedStr
self.endian = endian or '<'
self.fmt = {}
self.data = {}
self.position = 1
self.__index = self
return t
end
--清除数据
--]]
function ByteArray:destroy()
self.packedStr = nil
self.fmt = nil
self.data = nil
end
function ByteArray:readByte()
local val = 0
self.position, val = ipack.unpack(self.packedStr, typeEnum.OP_BYTE, self.position)
return val
end
function ByteArray:writeByte(b)
self.fmt[#self.fmt + 1] = typeEnum.OP_BYTE
self.data[#self.data + 1] = b
end
function ByteArray:readUByte()
local val = 0
self.position, val = ipack.unpack(self.packedStr, typeEnum.OP_UBYTE, self.position)
return val
end
function ByteArray:writeUByte(b)
self.fmt[#self.fmt + 1] = typeEnum.OP_UBYTE
self.data[#self.data + 1] = b
end
function ByteArray:readShort()
local val = 0
self.position, val = ipack.unpack(self.packedStr, self.endian .. typeEnum.OP_SHORT, self.position)
return val
end
function ByteArray:readUshort()
local val = 0
self.position, val = ipack.unpack(self.packedStr, self.endian .. typeEnum.OP_USHORT, self.position)
return val
end
function ByteArray:writeUShort(h)
self.fmt[#self.fmt + 1] = typeEnum.OP_USHORT
self.data[#self.data + 1] = h
end
function ByteArray:writeShort(h)
self.fmt[#self.fmt + 1] = typeEnum.OP_SHORT
self.data[#self.data + 1] = h
end
function ByteArray:readInt()
local val = 0
self.position, val = ipack.unpack(self.packedStr, self.endian .. typeEnum.OP_INT, self.position)
return val
end
function ByteArray:writeInt(i)
self.fmt[#self.fmt + 1] = typeEnum.OP_INT
self.data[#self.data + 1] = i
end
function ByteArray:readDouble()
local val = 0
self.position, val = ipack.unpack(self.packedStr, self.endian .. typeEnum.OP_DOUBLE, self.position)
return val
end
function ByteArray:readUint()
local val = 0
self.position, val = ipack.unpack(self.packedStr, self.endian .. typeEnum.OP_UINT, self.position)
return val
end
function ByteArray:writeDouble(d)
self.fmt[#self.fmt + 1] = typeEnum.OP_DOUBLE
self.data[#self.data + 1] = d
end
function ByteArray:readString()
local l = self:readShort()
local val = 0
self.position, val = ipack.unpack(self.packedStr, typeEnum.OP_STRING .. l, self.position)
return val
end
function ByteArray:writeString(s)
self:writeShort(#s)
self.fmt[#self.fmt + 1] = typeEnum.OP_STRING
self.data[#self.data + 1] = s
end
--获取打包后的 数据 -str
--]]
function ByteArray:getbytesString()
if self.packedStr and self.packedStr ~= '' then
return self.packedStr
else
print(self.endian .. table.concat(self.fmt))
print(unpack(self.data))
return ipack.pack(self.endian .. table.concat(self.fmt), unpack(self.data))
end
end
return ByteArray
使用方法 特别注意的是 大小端问题‘’<‘’ 如果解析失败 换下试试
如果解析数据是从C# 传过到lua的 记得要给数据加上标签[LuaByteBufferAttribute] 否则传过来是个table
local ByteArray=require"ipack/ByteArray"
local ba = ByteArray:new(nil, '<')
ba:writeInt(333300)
ba:writeString('fuck 1334 goddess')
ba:writeShort(44)
ba:writeByte(-3)
ba:writeByte(122)
local s = ba:getbytesString()
print(#s, s)
print('----------------')
local ba2 = ByteArray:new(s, '<')
print(ba:readInt())
print(ba:readString())
print(ba:readShort())
print(ba:readByte())
print(ba:readByte())