介绍: ardio 的 raw.pack 是 Python 的 struct 库的兼容实现。
使用的二进制格式化语法与 Python 相同( 请参考 Python struct 模块文档 )。 工具: 使用「aardio 工具 » 转换工具 » 原生类型转换」
可以将 Python 二进制格式化串自动转换为结构体声明,并生成用结构体打包解包的示例。
使用结构体打包解包仅需要用到内置函数 raw.convert 与 raw.buffer,
不需要引入 raw.pack 库。 aardio 使用结构体处理二进制更为简单,速度也更快,结构体描述二进制数据的可读性也更好。
但是对于大端序格式串使用 raw.pack 会省事一些,这是因为 raw.pack 与 raw.pack.unpack 会自动转换大端序。
但结构体使用的是小端序,大端序要使用 raw.swap 或 math.size64 的 swap 函数手动转换。 函数对比: 有关的 Python 函数与 aardio 函数的对应关系如下。 raw.pack, raw.pack.unpack 与 Python 相同处理的都是单个非数组值,
而 raw.pack.unpackArray,raw.pack.getStruct,raw.pack.getCode 都将指定重复次数的格式化字符处理为数组字段。
例如 raw.pack.getCode("@10H") 会返回包含结构体声明的 aardio 代码 raw.pack.getCode 将 Python 的二进制格式化串转换为 aardio 结构体声明,
「aardio 工具 » 转换工具 » 原生类型转换」就是调用 raw.pack.getCode 转换二进制格式化串。 注意 raw.pack 返回的是 buffer 而不是字符串,在 aardio 里大部份函数通常可以用 buffer 替代字符串参数。
可以用 tostring(buffer) 将 buffer 转换为字符串。 格式化字符: 完整的格式化字符请查看 Python 文档,下面仅说明 aardio 中需要注意的一些格式。 aardio 中的 buffer 是可读写的,而 Python 字节串是只读的。 可以将 Python 格式串先转换为 aardio 结构体,
在结构体中 byte [] 类型字段默认处理为字符串值。
如果值预先指定为 buffer 类型则解包时也会填充数据到原来的 buffer 中。
如果值预先指定数组,则解包时会生成一个新的数组。 在 Python 中 上面的代码利用 buffer 的定长特性可以简化如下: 但其实 raw.pack 本就可以将字符串或 buffer 自动转换为定长数据,
所以可以直接写: raw.pack 底层是基于 aardio 的结构体打包数据,
aardio 结构体里的数组字段都不要求传入定长数组,太长太短 aardio 都会自动处理。
所以处理这类问题,用 aardio 可以少写很多代码。使用必读
Python 函数
aardio 函数
struct.pack
raw.pack
struct.pack_into
raw.pack.into
struct.unpack
raw.pack.unpack
struct.unpack_from 返回多值
raw.convert 返回单个结构体
struct.calcsize
raw.sizeof 或 raw.calcsize
struct.iter_unpack
raw.pack.each
{ WORD field1[10]; } 。
s 格式打包时可输入字符串或 buffer,解包时返回字符串,
aardio 中字符串也是二进制兼容的,都可以作为字节数组使用。s 格式打包时,不需要预先处理字符串的长度,
raw.pack 会自动截断超出长度的部分,不足的部分会自动填充为 0。
这是因为 raw.pack 底层基于 aardio 的结构体,而结构体自动就会处理这些问题。s 格式对应 Python 中的字节串(bytes)。
在 aardio 与 Python 交互时,aardio 也会将 Python 字节串转换为 aardio 中的 buffer 。
s 格式打包时需经预先处理长度,翻译为 aardio 代码就是这样写:import raw.pack;
var variableLengthString = "abcd"
var size = 5;
var fixedSizeString;
//使用定长字符串
if(#variableLengthString < size ) {
fixedSizeString = variableLengthString + string.repeat(size-#variableLengthString)
}
else{
fixedSizeString = string.left(variableLengthString,size)
}
var buf = raw.pack("<5sb",variableLengthString,3);
var fixedSizeBuffer = raw.buffer(size,variableLengthString)
buf = raw.pack("<5sb",fixedSizeBuffer,3) //参数里字符串与 buffer 可以互换
buf = raw.pack("<5sb",variableLengthString/*太长太短都会自动处理*/,3)
p 格式在 aardio 中作为 s 格式处理。
p 格式的唯一区别是第一个字节记录了长度,aardio 不会移除这个长度标记,也不会清除尾部的填充字节。
这种格式现在基本不太可能用到,可以忽略。Q 格式表示无符号 64 位整数,在 aardio 中解包时返回的是 math.size64 对象。
aardio 使用 math.size64 对象存储 64 位无符号整数,使用 tonumber 可以将其转换为普通的 64 位浮点数。? 格式在 aardio 中处理为 byte 类型,这个类型原本表示单字节 bool 类型,
但是 aardio 原生类型的 bool 类型是 4 字节,所以 ? 以单字节 byte 替代。
aardio 中以 0 为 false,非 0 数值为 true,所以在使用上并没有太大区别。可以用双冒号 !! 将数值转换为 aardio 中的 boolean 类型。
参数 @format 指定格式化字符串。
其他不定个数的参数指定待打包的值,也可以传入包含多个参数的单个数组参数。
成功返回字节串( buffer 类型 ),
失败返回 null,错误信息。
为了与 Python 的用法保持一致,
每个打包解包的参数都必须是单个非数组值(数值、字符串、buffer 等)。
但改用 getStruct 或 getCode 可以得到支持数组的 aardio 结构体声明。
将结构体作为参数就以用 raw.convert 解包或调用 raw.buffer 或 raw.tostring 打包。
用于二进制打包的库。
兼容 Python struct.pack 格式化字符。
raw.pack 与 raw.pack.unpack 会自动处理字节序。
仅 > 与 ! 开始的大端序与 aardio 的默认字节序不同需要转换。
导入此库与 string.builder 库可使用 string.builder 的 pack 函数连续或批量打包。
建议应 raw.pack.getCode 获取与打包解包格式化字符串一致的结构体声明,
然后直接使用 raw.convert 解包,使用 raw.buffer 或 raw.tostring 打包。
raw.pack.sizeof 函数的别名。
根据参数 @format 指定的格式化字符串计算打包后的字节长度。
失败返回 0
参数 @format 指定格式化字符串。
参数 @buffer 指定需要解包的 buffer 或者字符串。
可选用 @offset 参数指定偏移字节数,默认为 0。
成功返回解包后的结构体对象(指定重复次数的格式字符转为数组) ,失败返回 null,错误信息。
for count,items in raw.pack.each("<10s2HI",buffer){
/*
解包迭代器,每次都返回包含所有字段的数组。
不展开数组字段( 例如 "2H" 格式化为 WORD[] 数组 )
相当于循环调用 raw.pack.unpackArray 函数。
第一次循环只要 buffer 的长度大于 1 就会执行。
后续会安全地检测剩下的长度是否足够解包,长度不够时退出循环。
参数 @format 指定格式化字符串。
兼容 Python struct.unpack 格式化字符。
参数 @buffer 指定需要解包的 buffer 或者字符串。
可选用 @offset 参数指定偏移字节数,默认为 0。
*/
}
根据参数 @format 指定的格式化字符串生成创建结构体的 aardio 代码,支持数组字段。
失败返回 null,错误信息。
此函数调用 raw.pack.getStruct 获取结构体并转换为代码,
细节请参考该函数说明。
根据参数 @format 指定的格式化字符串生成结构体对象,支持数组字段。
无对齐时 _struct_aligned 字段值为 1,否则遵守默认的结构体对齐规则。
无对齐(紧凑结构)时如果巧合了自动对齐规则,则不会添加 _struct_aligned 字段。
成功返回结构体,失败返回 null,错误信息。
参数 @format 指定格式化字符串。
buffer 指定缓冲区( buffer 类型字节串 ) 对象,传 null 值则创建新的 buffer。
offset 指定写入位置的字节偏移量,默认为 0。
其他不定个数的参数指定待打包的值,也可以传入包含多个参数的单个数组参数。
成功返回字节串( buffer 类型 ),
失败返回 null,错误信息。
为了与 Python 的用法保持一致,
每个打包解包的参数都必须是单个非数组值(数值、字符串、buffer 等)。
但改用 getStruct 或 getCode 可以得到支持数组的 aardio 结构体声明。
将结构体作为参数就以用 raw.convert 解包或调用 raw.buffer 或 raw.tostring 打包。
原地转换字节序。
参数 buffer 指定字节串( buffer 类型 )。
此函数不会检查参数 @buffer 的类型,调用者有责任传入正确的类型。
参数 @index 指定开始转换的索引,起始索引为 1。
参数 @size 指定要转换的字节长度。
根据参数 @format 指定的格式化字符串计算打包后的字节长度。
失败返回 0
参数 @format 指定格式化字符串。
兼容 Python struct.unpack 格式化字符。
参数 @buffer 指定需要解包的 buffer 或者字符串。
可选用 @offset 参数指定偏移字节数,默认为 0。
顺序返回解包成功的一个或多个值(指定重复次数的格式字符返回多个值而非数组)。
参数 @format 指定格式化字符串。
兼容 Python struct.unpack 格式化字符。
参数 @buffer 指定需要解包的 buffer 或者字符串。
可选用 @offset 参数指定偏移字节数,默认为 0。
此函数默认将指定重复次数的格式字符解包为单个数组值,
如果参数 @4 为 false 则展开数组为多个值
成功返回一个包含所有解包值的数组,失败无返回值。