mc.bitstring提供了常用的二进制操作方法,提供对二进制数据的编码、解码功能。lua语法结合LPeg的模板匹配库实现的。
加载方式
local bs = require 'mc.bitstring'bitstring接口说明
bs.new
描述
- 根据传入的模板创建bitstring对象
参数
| 参数 | 类型 | 描述 | 是否必选 |
|---|---|---|---|
| pattern | string | bitsting的匹配模板 | 是 |
| env | table | 匹配模板中自定义类型 | 否 |
WARNING
1、bitstring中参数类型默认integer类型,模板中可显示指定成其他数据类型,如<<var1:16/float, var2:8/string, var3:8/binary>>,可支持自定义类型(后续介绍)
2、bitstring中数字类型默认是unsigned类型,模板中可显示指定成signed类型,如<<value:16/signed>>,和数据类型用字符-进行连接,如<<value:16/float-signed>>
3、bitstring中参数大小默认值跟随参数类型,integer类型默认8,如<<var1>>等价于<<var1/integer>>等价于<<var1:8/integer>>,float类型默认是32,如<<var1/float>>等价于等价于<<var1:32/float>>,可通过字符:后显示指定成任意size
4、bitstring中参数默认小端序,模板中可用字符big显示指定大端序,little显示指定成小端序,如<<var1:16/big-signed-float>>
5、bitstring中参数单元默认值跟随参数类型,模板中可用字符unit:显示指定单元大小,string和binary类型单元默认8bit,其他数据类型默认1bit,显示指定如<<var1:16/big-signed-float-unit:2>>最终var1参数占用16*2bit
6、自定义参数类型指类型可内部嵌套一层bitstring,如bs.new('<< var1:1/MSG_TYPE >>', {MSG_TYPE = bs.new('<< header:8, len:8 >>')})\
返回
- bitstring对象,类型为table
异常
- 匹配模板解析失败时,将抛异常
示例
local bs = require 'mc.bitstring'
local pattern = [[<<
cmd:8,
len:8,
data:len/string
>>]]
local MSG = bs.new(pattern); -- 根据模板创建一个bitstring的对象
-- 发送端编码
local send_msg_args = {
cmd = 0x5,
len = 8,
data = '0123ABCD'
}
local send_msg = MSG:pack(send_msg_args) -- 根据模板即可生成二进制'\x05\x08\x30\x31\x32\x33\x41\x42\x43\x44'的字符串
-- 接收端解码
local recv_msg_args = MSG:unpack(send_msg) -- 根据模板即可解码得到lua中table类型的结果{cmd = 5, len = 8, data = '01234ABCD'}bs.new(pattern, env):pack(input_args)
描述
- 将输入的table数据按pattern中的模板进行匹配转换成二进制
参数
| 参数 | 类型 | 描述 | 是否必选 |
|---|---|---|---|
| input_args | table | 待模板匹配编码的参数 | 可选 |
返回
- string类型的二进制编码数据,可以使用
mc.utils中的to_hex()方法进行转换成十六进制
异常
- 若输入成参数与模板不匹配时,将抛异常
WARNING
1、当模板中无变量名,而是纯数字场景时,则pack方法直接将模板中的数字按模板形式进行编码,如
local bs = require 'mc.bitstring'
local value = bs.pack('<<0x123456:32/big-signed>>'):pack()示例
local bs = require 'mc.bitstring'
local pattern = [[<<
cmd:8,
len:8,
data:len/string
>>]]
local MSG = bs.new(pattern); -- 根据模板创建一个bitstring的对象
-- 发送端编码
local send_msg_args = {
cmd = 0x5,
len = 8,
data = '0123ABCD'
}
local send_msg = MSG:pack(send_msg_args) -- 根据模板即可生成'\x05\x08\x30\x31\x32\x33\x41\x42\x43\x44'的二进制字符串bs.new(pattern, env):unpack(data, ret_some)
描述
- 输入字符串数据或者将二进制文件的文件句柄,按pattern中的模板进行匹配转换成table类型数据
参数
| 参数 | 类型 | 描述 | 是否必选 |
|---|---|---|---|
| data | string或文件句柄 | 待模板匹配解码参数 | 必选 |
| ret_some | bool类型 | 缺省值为false,代表是否支持只匹配部分模板,true的场景下支持匹配部分模板,匹配到源数据结束为止。false场景下源数据不足以匹配时,返回nil | 可选 |
返回
- table类型的解析结果或者nil
- 解析过程模板匹配失败时,返回nil
- ret_some配置为false或者nil时,且源数据长度小于模板匹配所需的长度时,返回nil
- pattern模板中用
_占位符的变量会忽略,不会输出到返回的table中(用于过滤数据)
异常
- 无
示例
local bs = require 'mc.bitstring'
local pattern = [[<<
cmd:8,
len:8,
data:len/string
>>]]
local SEND_MSG = bs.new(pattern); -- 根据模板创建一个bitstring的对象
-- 发送端编码
local send_msg_args = {
cmd = 0x5,
len = 8,
data = '0123ABCD'
}
local send_msg = SEND_MSG:pack(send_msg_args) -- 根据模板即可生成'\x05\x08\x30\x31\x32\x33\x41\x42\x43\x44'的二进制字符串
-- 接收端解码
local RECV_MSG = bs.new('<<_:8,len:8,data:len/string>>') -- 使用占位符,第1个字节解析完后不会输出到返回值中,用于过滤数据
local recv_msg_args = RECV_MSG:unpack(send_msg) -- 根据模板即可解码得到lua中table类型的结果{len = 8, data = '01234ABCD'}