74 zbuff
作者:王棚嶙
一、概述
zbuff 是 LuatOS 中用于直接操作二进制内存数据的库,类似于 C 语言中的内存指针。它提供以下核心功能:
-
动态内存管理:申请指定长度的内存空间(支持 SRAM/PSRAM);
-
灵活读写:支持字节、整数、浮点数等数据类型的读写(如
readU32()
、writeF32()
); -
高级操作:内存拷贝(
copy
)、填充(set
)、比较(isEqual
)、Base64 编码等; -
帧缓冲(FrameBuffer):可直接操作显示缓冲区(如设置像素
pixel()
、画线drawLine()
);
可以在 sram 上或者 psram 上申请空间,也可以自动申请(如存在 psram 则在 psram 进行申请,如不存在或失败则在 sram 进行申请);
zbuff、string、pack 的关系与区别
既然已经有了string/pack库了,为什么还要单独有个zbuff库呢?
库 | 用途 | 区别 |
---|---|---|
string | 处理文本(如 JSON、URL 编码) | 不可修改,拼接生成新对象;适合小文本。 |
pack | 结构化数据打包/解包(如将数字转为大端字节序) | 依赖 string 存储结果;适合协议封装(如 Modbus 帧)。 |
zbuff | 操作原始二进制数据(如图像、网络包) | 可原地修改;支持指针偏移;适合大块数据流处理。 |
二、核心示例
1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;
2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;
3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/zbuff;
--[[
本核心示例的的业务逻辑为:
1.创建一个task,展示zbuff最常用的基础功能:
缓冲区创建与初始化
基础功能操作(读写)
指针控制
元信息查询
高效数据查询(query接口)
2.创建一个task,展示zbuff复杂数据处理功能,包括:
数据打包/解包
类型化读写
浮点数操作
3.创建一个task,展示zbuff内存管理操作,包括:
缓冲区大小调整
内存块设置
数据删除
内存比较
Base64编码转换功能
]]
local function zbuff_core_task_func()
log.info("zbuff_core", "启动核心功能演示")
-- 创建1024字节的缓冲区
local buff = zbuff.create(1024)
-- 打印缓冲区长度
log.info("zbuff_core", "缓冲区创建", "长度:", buff:len())
-- === 缓冲区创建与初始化演示 ===
log.info("zbuff_core", "=== 缓冲区创建与初始化演示 ===")
-- 通过索引直接访问和修改数据(索引从0开始)
buff[0] = 0xAE
log.info("zbuff_core", "索引访问示例", "buff[0] =", buff[0])
-- === 基础读写操作演示 ===
--[[
buff:write()中的参数可以是任意类型,zbuff会自动进行类型转换,写入buff的数据,
string时为一个参数,number时可为多个参数
]]
buff:write("123")
log.info("zbuff_core", "写入字符串", "123")
buff:write(0x12, 0x13, 0x13, 0x33)
log.info("zbuff_core", "写入数值", "0x12, 0x13, 0x13, 0x33")
buff:seek(5, zbuff.SEEK_CUR)
log.info("zbuff_core", "指针当前位置", "向后移动5字节","当前位置:", buff:used())
buff:seek(0)
log.info("zbuff_core", "指针移动", "重置到开头")
local data = buff:read(3)
log.info("zbuff_core", "读取数据", "长度3:",data)
-- === 缓冲区清除操作 ===
log.info("zbuff_core", "=== 缓冲区清除操作 ===")
buff:clear()
log.info("zbuff_core", "清除操作", "全部清零")
buff:clear(0xA5)
log.info("zbuff_core", "清除操作", "填充0xA5")
-- === 元信息查询 ===
log.info("zbuff_core", "=== 元信息查询 ===")
local len = buff:len()
log.info("zbuff_core", "元信息", "总长度:", len)
local used = buff:used()
log.info("zbuff_core", "元信息", "已使用:", used)
-- === 高效数据查询 ===
log.info("zbuff_core", "=== 高效数据查询 ===")
buff:clear()
buff:seek(0)
buff:write(0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC)
local all_data = buff:query(0, 6)
log.info("zbuff_core", "query查询", "全部数据:" ,all_data:toHex())
-- 查询部分数据并转换格式,查询1,2,4,8字节的时候会自动根据后续参数进行转换(大端序、无符号)
-- 参数:起始位置0,长度4,大端序,无符号,非浮点
local part_data = buff:query(0, 4, true, false, false)
log.info("zbuff_core", "query查询", "大端序格式:", part_data)
end
local function zbuff_advanced_task_func()
-- 创建1024字节的缓冲区
local buff = zbuff.create(1024)
-- === 数据打包与解包演示 ===
log.info("zbuff_advanced", "=== 数据打包与解包演示 ===")
-- 清空缓冲区
buff:clear()
-- 重置指针到开头
buff:seek(0)
-- 打包数据:大端序,2个32位整数,1个16位整数,1个字符串
buff:pack(">IIHA", 0x1234, 0x4567, 0x12, "abcdefg")
log.info("zbuff_advanced", "数据打包", "格式: >IIHA", "值: 0x1234, 0x4567, 0x12,
'abcdefg'")
-- 显示打包后的二进制内容
local packed = buff:toStr(0, buff:used())--按照起始位置和长度,取出数据,并转换为字符串
log.info("zbuff_advanced", "打包后数据", packed:toHex())
-- 重置指针到开头
buff:seek(0)
-- 解包数据:大端序,2个32位整数,1个16位整数,1个10字节字符串
local cnt, a, b, c, s = buff:unpack(">IIHA10")
log.info("zbuff_advanced", "数据解包", "数量:", cnt, "值:", a, b, c, s)
-- 显示解包后的输出内容
--[[
string.forma是Lua的格式化字符串函数,按照格式化参数formatstring,返回后面...
内容的格式化版本。string.format("0x%X", a)表示将整数a转换为十六进制字符串。
]]
log.info("zbuff_advanced", "解包输出内容",
"cnt:", cnt,
"a(32位):", string.format("0x%X", a),
"b(32位):", string.format("0x%X", b),
"c(16位):", string.format("0x%X", c),
"s(字符串):", s)
-- === 类型化读写演示 ===
--[[
类型化读写演示
展示I8和U32两种类型操作
@param buff zbuff对象
--]]
log.info("zbuff_advanced", "=== 类型化读写演示 ===")
-- 重置指针到开头
buff:seek(0)
-- 写入8位有符号整数
buff:writeI8(10)
log.info("zbuff_advanced", "类型化写入", "I8:", 10)
-- 写入32位无符号整数
buff:writeU32(1024)
log.info("zbuff_advanced", "类型化写入", "U32:", 1024)
-- 重置指针到开头
buff:seek(0)
-- 读取8位有符号整数
local i8data = buff:readI8()
log.info("zbuff_advanced", "类型化读取", "I8:", i8data)
-- 读取32位无符号整数
local u32data = buff:readU32()
log.info("zbuff_advanced", "类型化读取", "U32:", u32data)
--[[
浮点数操作演示
@param buff zbuff对象
--]]
log.info("zbuff_advanced", "=== 浮点数操作演示 ===")
-- 重置指针到开头
buff:seek(0)
-- 写入32位浮点数
buff:writeF32(1.2)
log.info("zbuff_advanced", "浮点数操作", "写入F32:", 1.2)
-- 重置指针到开头
buff:seek(0)
-- 读取32位浮点数
local f32data = buff:readF32()
log.info("zbuff_advanced", "浮点数操作", "读取F32:", f32data)
end
local function zbuff_memory_task_func()
--[[内存管理操作演示@param buff zbuff对象]]
log.info("zbuff_memory", "启动内存管理功能演示")
-- 1. 调整缓冲区大小
local buff = zbuff.create(1024)
local original_size = buff:len()
buff:resize(2048) -- 扩容到2048字节
log.info("zbuff_memory", "大小调整", "原始大小:", original_size, "新大小:", buff:len())
-- 2. 内存块设置(类似memset)
-- 从位置10开始设置5个字节为0xaa
buff:set(10,0xaa,5)
log.info("zbuff_memory", "内存设置", "位置10-14设置为0xaa")
-- 验证设置结果
log.info("zbuff_memory", "验证结果", "位置10:", buff[10], "应为0xaa")
-- 3. 数据删除操作
-- 写入测试数据
buff:clear()
buff:seek(0)
buff:write("ABCDEFGH")
log.info("zbuff_memory", "删除前数据", buff:toStr())
-- 删除位置2开始的3个字节
buff:del(2, 3)
log.info("zbuff_memory", "删除操作", "删除位置2-4", "结果:", buff:toStr())
-- 4. 内存比较
local buff2 = zbuff.create(10)
buff2:write("12345")
-- 比较两个缓冲区前5字节内容
local equal, offset = buff:isEqual(0, buff2, 0, 5)
log.info("zbuff_memory", "内存比较", "结果:", equal, "差异位置:", offset)
-- 5. Base64编码转换
-- 创建足够大的目标缓冲区
local dst = zbuff.create(buff:used() * 2)
-- 进行Base64编码
local len = buff:toBase64(dst)
log.info("zbuff_memory", "Base64编码", "长度:", len, "结果:", dst:toStr(0, len))
end
三、常量详解
核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;
3.1 zbuff.SEEK_SET
常量含义:从缓冲区头部为基点;
数据类型:number;
取值范围:0;
示例代码:-- 从缓冲区头部开始定位;
local buff = zbuff.create(1024)
buff:seek(0, zbuff.SEEK_SET)
3.2 zbuff.SEEK_CUR
常量含义:以当前指针位置为基点;
数据类型:number;
取值范围:1;
示例代码:local buff = zbuff.create(1024)
buff:write("Hello")
-- 从当前位置向前移动2个字节;
buff:seek(-2, zbuff.SEEK_CUR)
3.3 zbuff.SEEK_END
常量含义:以缓冲区末尾为基点;
数据类型:number;
取值范围:2;
示例代码:local buff = zbuff.create(1024)
buff:write("Hello")
-- 从缓冲区末尾向前移动5个字节;
buff:seek(-5, zbuff.SEEK_END)
3.4 zbuff.HEAP_AUTO
常量含义:自动申请(如存在psram则在psram进行申请,如不存在或失败则在sram进行申请);
数据类型:number;
取值范围:0;
示例代码:-- 自动选择内存类型创建缓冲区;
local buff = zbuff.create(1024, zbuff.HEAP_AUTO)
3.5 zbuff.HEAP_SRAM
常量含义:在sram申请缓冲区;
数据类型:number;
取值范围:1;
示例代码:-- 在SRAM中创建缓冲区;
local buff = zbuff.create(1024, zbuff.HEAP_SRAM)
3.6 zbuff.HEAP_PSRAM
常量含义:在psram申请缓冲区;
数据类型:number;
取值范围:2;
示例代码:-- 在PSRAM中创建缓冲区;
local buff = zbuff.create(1024, zbuff.HEAP_PSRAM)
四、函数详解
4.1 zbuff.create(length,data,type)
功能
创建zbuff缓冲区/创建帧缓冲区;
注意事项
-
创建失败返回nil,需检查返回值;
-
指定data参数时会填充初始数据;
-
可创建普通缓冲区或framebuffer;
参数
length
参数含义:zbuff字节长度或framebuffer配置表;
table时专用于图形显示的帧缓冲区,table内容格式为{width, height, bit_depth}说明如下;
{
-- 参数含义:像素宽度;
-- 数据类型:number;
-- 取值范围:必须>0;
-- 是否必选:是;
-- 注意事项:暂无;
-- 参数示例:--创建一个128*160,色位深度16的framebuff;
local buff = zbuff.create({128,160,16}
width = ,
-- 参数含义:像素高度;
-- 数据类型:number;
-- 取值范围:必须>0;
-- 是否必选:是;
-- 注意事项:暂无;
-- 参数示例:--创建一个128*160,色位深度16的framebuff;
local buff = zbuff.create({128,160,16}
height = ,
-- 参数含义:色位深度;
-- 数据类型:number;
-- 取值范围:必须>0;
-- 是否必选:是;
-- 注意事项:暂无;
-- 参数示例:--创建一个128*160,色位深度16的framebuff;
local buff = zbuff.create({128,160,16}
bit_depth = ,
}
数据类型:number/table;
取值范围:普通缓冲区:>0;
framebuffer:{width, height, bit_depth};
是否必选:是;
注意事项:framebuffer需指定色深;
参数示例:-- 创建一个1024大小的缓冲区;
local buff = zbuff.create(1024)
--创建一个128*160,色位深度16的framebuff;
local buff = zbuff.create({128,160,16}
--创建一个128*160,色位深度16的framebuff,初始状态红色;
local buff = zbuff.create({128,160,16},0xf800)
date
参数含义:初始填充数据;
数据类型:number/string/nil;
取值范围:number: 0-255;
string: 任意长度;
是否必选:否;
注意事项:number类型会填充整个zbuff;
参数示例:--创建一个初值全为0x33的内存区域;
local buff = zbuff.create(1024, 0x33)
-- 创建,并填充一个已有字符串的内容;
local buff = zbuff.create(1024, "123321456654")
type
参数含义:内存类型;
数据类型:number;
取值范围:zbuff.HEAP_AUTO - 自动选择(默认);
zbuff.HEAP_SRAM - 内部SRAM;
zbuff.HEAP_PSRAM - 外部PSRAM;
是否必选:否;
注意事项:使用zbuff.HEAP_PSRAM时,硬件需支持PSRAM;
参数示例:-- 自动选择内存类型创建缓冲区;
local buff = zbuff.create(1024, zbuff.HEAP_AUTO)
返回值
local buff = zbuff.create(length,data,type)
有一个返回值buff
buff
含义说明:创建的buff缓冲区对象,如果创建失败会返回nil;
数值类型:userdata;
取值范围:成功为缓冲区对象,失败返回nil;
注意事项:zbuff对象创建后所有数据操作必须通过方法调用(使用冒号语法 :),直接访问属性只会返回地址标识符。这是LuatOS对内存安全操作的设计约束;
返回值示例:local buff = zbuff.create(1024)
if buff then
-- 输出1024;
log.info("创建成功,长度:", buff:len())
else
--输出nil;
log.error("创建失败")
end
PS:错误的打印方式如下
local buff = zbuff.create(1024)
-- 输出:ZBUFF*: 0C7F6F30(地址标识符);
log.info("zbuff_core", "缓冲区创建", "容量:", buff)
示例
创建普通缓冲区:
-- 创建1024字节空白缓冲区;
local buff1 = zbuff.create(1024)
-- 创建全0x33填充的缓冲区;
local buff2 = zbuff.create(1024, 0x33)
-- 用字符串初始化;
local buff3 = zbuff.create(1024, "ABC")
创建帧缓冲区:
-- 创建framebuff用的zbuff;
-- zbuff.create({width,height,bit},data,type);
-- table 宽度、高度、色位深度;
@number 可选参数,填充数据
@number 可选参数,内存类型
@return object zbuff对象,如果创建失败会返回nil
@usage
-- 创建zbuff
local buff = zbuff.create({128,160,16})--创建一个128*160的framebuff
local buff = zbuff.create({128,160,16},0xf800)--创建一个128*160的framebuff,初始状态红色
4.2 buff:write(para,...)
功能
从当前指针位置写入数据(支持多参数),指针自动后移;
注意事项
-
写入后指针自动后移;
-
支持多参数写入;
参数
para
参数含义:写入的数据;
数据类型:number,支持多参数,如buff:write(0x12, 0x34),连续写入多个字节;
string,不支持多参数,如buff:write("AB","CD")是错误的,buff:write("AB")才是正确的;
混合类型,支持多参数,如buff:write("AB",0x55),先字符串后数值;
取值范围:number: 0-255(单字节);
string: 任意长度二进制数据;
是否必选:是;
注意事项:作为必需参数,若不提供会导致错误;
参数示例:-- 方法1: 连接字符串(推荐),单次写入合并后的字符串;
buff:write("AB" .. "CD")
-- 方法2: 多次调用,需注意指针位置连续;
buff:write("AB")
buff:write("CD")
返回值
local len = buff:write(para,...)
有一个返回值len
len
含义说明:成功写入的字节数
数值类型:number;
取值范围:成功写入的字节数;
注意事项:若空间不足,实际写入数可能小于参数长度;
返回值示例:local len = buff:write("Test", 0x55)
-- 输出5("Test"占4字节 + 0x55占1字节)
log.info("写入长度:", len)
-- 指针从0移动到5
log.info("指针位置:", buff:used())
示例
-- 类file的读写操作;
-- 写入数据, 指针相应地往后移动,返回写入的数据长度;
local len = buff:write("123")
-- 按数值写入多个字节数据;
local len = buff:write(0x1a,0x30,0x31,0x32,0x00,0x01)
4.3 buff:read(length)
功能
zbuff读数据:从当前指针读取指定长度的二进制数据,指针自动后移;
注意事项
-
读取后指针自动后移;
-
读取长度不能超过缓冲区剩余空间,超过会被截断;
参数
length
参数含义:读取长度;
数据类型:number;
取值范围:>0的整数;
是否必选:是;
注意事项:超过剩余空间会截断;
参数示例:-- 类file的读写操作
local str = buff:read(3)
返回值
local str = buff:read(length)
有一个返回值str;
str
含义说明:读取的数据;
数值类型:string;
取值范围:长度为0到length的字符串;
注意事项:暂无;
示例
-- 写入 'A'(0x41)、'B'(0x42)、'C'(0x43);
buff:write(0x41,0x42,0x43)
-- 指针复位 准备开始读取;
buff:seek(0)
local str = buff:read(3)
-- 输出 "414243";
log.info("Hex数据:", data:toHex())
4.4 buff:clear(num)
功能
zbuff清空数据(与当前指针位置无关;执行后指针位置不变)全缓冲区填充指定值;
注意事项
-
清空操作不影响缓冲区大小;
-
指针位置保持不变;
-
默认填充0x00(全零);
参数
num
参数含义:填充值;
数据类型:number;
取值范围:0-255;
是否必选:否,默认值为0;
注意事项:仅修改字节值,不改变指针位置;
参数示例:-- 全填充为0xAA;
buff:clear(0xAA)
-- 全填充为0,即清空;
buff:clear(0)
-- 全填充为0(默认为0),即清空;
buff:clear()
返回值
暂无;
示例
-- 全部初始化为0;
buff:clear(0)
-- 全填充为0xAA;
buff:clear(0xAA)
-- 输出170(0xAA的十进制);
log.info("索引0的值:", buff[0])
4.5 buff:seek(offset,base)
功能
zbuff移动读写指针位置(与当前指针位置有关;执行后指针会被设置到指定位置);
注意事项
-
指针位置范围:0 ~ buff:len()-1;
-
超出范围的偏移会自动调整到边界值;
-
查询模式不改变指针位置;
-
修改模式会改变当前指针位置;
参数
offset
参数含义:偏移量;
数据类型:number;
取值范围:任意整数;
是否必选:否默认值为0;
注意事项:负值表示向前偏移;
绝对值超过缓冲区长度时自动截断;
参数示例:-- 把光标设置到指定位置;
buff:seek(0)
-- 从当前位置向后移动5个字节;
buff:seek(5,zbuff.SEEK_CUR)
base
参数含义:基准位置;
数据类型:number;
取值范围:zbuff.SEEK_SET - 缓冲区开头;
zbuff.SEEK_CUR - 当前位置;
zbuff.SEEK_END - 缓冲区结尾;
是否必选:否,默认值:zbuff.SEEK_SET;
注意事项:仅当设置位置时有效
参数示例:--从缓冲区结尾位置向前移动三个字节
buff:seek(-3,zbuff.SEEK_END)
返回值
local current_pos = buff:seek(offset,base)
有一个返回值 current_pos;
current_pos
含义说明:设置后的当前指针位置;
数值类型:number;
取值范围:0 ~ buff:len()-1;
注意事项:暂无;
返回值示例:-- 指针置0;
buff:seek(0)
-- 从当前位置后移5字节;
buff:seek(5, zbuff.SEEK_CUR)
-- 输出5;
log.info("指针位置:", buff:used())
示例
-- 把光标设置到指定位置;
buff:seek(0)
-- 从当前位置向后移动五个字节;
buff:seek(5,zbuff.SEEK_CUR)
-- 从缓冲区尾向前移动三个字节;
buff:seek(-3,zbuff.SEEK_END)
验证:
-- 创建100字节缓冲区
local buff = zbuff.create(100)
-- 设置指针;
-- 输出100;
local end_pos = buff:len()
local new_pos = buff:seek(-3, zbuff.SEEK_END)
-- 输出97(100-3);
log.info("新位置", new_pos)
-- 写入验证,从指针位置开始写入0xAA;
buff:write(0xAA)
-- 输出0xAA;
log.info("倒数第3字节", buff[97])
-- 输出0(未写入区域)
log.info("倒数第4字节", buff[96])
4.6 buff:pack(format,val1, val2,...)
功能
将一系列数据按照格式字符转化,并写入(从当前指针位置开始;执行后指针会向后移动);
注意事项
-
从当前指针位置开始打包;
-
打包后指针自动向后移动;
-
支持多种数据类型和字节序控制;
-
格式字符串控制打包方式;
参数
format
参数含义:数据格式描述字符串;
数据类型:string;
取值范围:见下表;
是否必选:是;
注意事项:格式字符需与后续参数匹配;
参数示例:buff:pack(">IIHA", 0x1234, 0x4567, 0x12,"abcdefg")
符号 | 类型 | 字节数 | 取值范围 | 特殊说明 |
---|---|---|---|---|
A | string | 变长 | 任意字符串 | 自动写入完整字符串 |
f | float (单精度浮点) | 4 | -2147483648~2147483647 | |
d | double (双精度浮点) | 8 | IEEE754标准 | |
n | Lua number | 8 | Lua number范围 | 平台相关 |
c | char | 1 | -128~127 | 有符号 |
b | byte | 1 | 0~255 | 无符号 |
h | short | 2 | -32768~32767 | 有符号 |
H | unsigned short | 2 | 0~65535 | 无符号 |
i | number | 4 | -2147483648~2147483647 | 有符号 |
I | unsigned number | 4 | 0~4294967295 | 无符号 |
l | long | 4或8 | 平台相关 | |
L | unsigned long | 4或8 | 平台相关 | |
< | 前缀 | - | 小端序 | 必须放在格式串开头 |
> | 前缀 | - | 大端序 | 必须放在格式串开头 |
= | 前缀 | - | 默认大小端 | 必须放在格式串开头 |
大端序,小端序举例说明:
如有一个32位的16进制的数据0x12345678,分成4个字节传过来;
如果是0x78,0x56,0x34,0x12这个顺序输出就是小端序;
如果是0x12,0x34,0x56,0x78这个顺序,那就是大端序;
多字节数据的高位字节存储在内存的低地址处,低位字节存储在高地址处;
0x12是高位字节,第一个输出出来就是大端序。反之则是小端序。
val1, val2, ...
参数含义:待打包的数据;
数据类型:根据format决定;
取值范围:A: 任意字符串;
f/d: 浮点数范围;
n: Lua number范围;
整型: 对应类型取值范围;
是否必选:是;
注意事项:参数数量需与格式字符匹配;
参数示例:-- 打包协议数据;
--[[
格式: 大端序输出,无符号整型 + 无符号短整型 + 字符串;
0x12345678,为整型值;0xABCD,为短整型值;"end"为字符串
]]
local len = buff:pack(">IHA",0x12345678, 0xABCD,"end")
返回值
local len = buff:pack(format,val1, val2,...)
有一个返回值len;
len
含义说明:成功打包的字节数;
数值类型:number;
取值范围:≥0;
注意事项:暂无;
返回值示例:-- 打包协议数据;
--[[
格式: 大端序输出,无符号整型 + 无符号短整型 + 字符串;
0x12345678,为整型值;0xABCD,为短整型值;"end"为字符串
]]
local len = buff:pack(">IHA",0x12345678, 0xABCD,"end")
-- 验证结果;
-- 输出: 4+2+3=9;
log.info("打包字节数", len)
-- 输出: 12345678ABCD656E64;
log.info("缓冲区内容", buff:toStr(0, len):toHex())
示例
-- 按格式写入几个数据:
--[[
">IIHA", -- 格式字符串:大端序,依次为[4字节无符号整型, 4字节无符号整型, 2字节无符号短整型, 字符串];
0x1234, -- 参数1:整数值,写入为4字节(大端:00 00 12 34);
0x4567, -- 参数2:整数值,写入为4字节(大端:00 00 45 67);
0x12, -- 参数3:整数值,写入为2字节(大端:00 12);
"abcdefg" -- 参数4:字符串,写入7字节ASCII码(61 62 63 64 65 66 67);
格式字符串开头的字节序标识符(>大端、<小端、=默认)会作用于后续所有多字节格式符,单字节类型不受影响:如 b(字节)、c(字符)等,因单字节无顺序问题;
]]
buff:pack(">IIHA", 0x1234, 0x4567, 0x12,"abcdefg")
-- 显示打包后的二进制内容;
-- buff:used():按照起始位置和长度,取出数据,并转换为字符串;
local packed = buff:toStr(0, buff:used())
-- 输出0000123400004567001261626364656667 34,"34" 是十六进制值 0x34 的合法文本表示;
log.info("zbuff_advanced", "打包后数据", packed:toHex())
4.7 buff:unpack(format)
功能
将一系列数据按照格式字符读取出来(从当前指针位置开始;执行后指针会向后移动)
注意事项
-
从当前指针位置开始解包;
-
解包后指针自动向后移动;
-
格式字符串控制解包方式;
-
缓冲区数据不足时可能返回部分结果;
参数
format
参数含义:数据格式描述字符串;
数据类型:string;
取值范围:同 buff:pack的参数,参考上文表格;
是否必选:是;
注意事项:格式字符需与缓冲区数据匹配;
字符串类型需指定长度;
参数示例:-- 按格式读取几个数据
-- 如果全部成功读取,cnt就是4+4+2+10=20
-- A10为指定字符串长度
local cnt,a,b,c,s = buff:unpack(">IIHA10")
返回值
local cnt, val1,val2,... = buff:unpack(format)
有两个返回值:一个为解包字节数cnt,一个为解包出的数据 val1,val2,...;
cnt
含义说明:成功解包的字节数;
数值类型:number;
取值范围:≥0;
注意事项:暂无;
val1,val2,...
含义说明:解包出的数据值;
数值类型:根据format决定;
取值范围:对应数据类型的取值范围;
注意事项:暂无;
示例
-- 解包数据:大端序,2个32位整数,1个16位整数,1个10字节字符串;
local cnt, a, b, c, s = buff:unpack(">IIHA10")
-- 显示解包后的输出内容应为 数据解包数量: 20 值: 4660 17767 18 abcdefg;
log.info( "数据解包", "数量:", cnt, "值:", a, b, c, s)
4.8 buff:read类型(number)
功能
读取一个指定类型的数据(从当前指针位置开始;执行后指针会向后移动);
注意事项
-
从当前指针位置开始读取;
-
读取后指针自动向后移动;
-
使用系统默认字节序;
-
缓冲区数据不足时返回nil;
参数
无;
读取类型
函数名 | 数据类型 | 大小(字节) | 数值范围 | 说明 |
---|---|---|---|---|
readI8() | 有符号8位整数 | 1 | -128 ~ 127 | 读取带符号字节 |
readU8() | 无符号8位整数 | 1 | 0 ~ 255 | 读取无符号字节 |
readI16() | 有符号16位整数 | 2 | -32768 ~ 32767 | 读取带符号短整数 |
readU16() | 无符号16位整数 | 2 | 0 ~ 65535 | 读取无符号短整数 |
readI32() | 有符号32位整数 | 4 | -2^31 ~ 2^31-1 | 读取带符号整数 |
readU32() | 无符号32位整数 | 4 | 0 ~ 4,294,967,295 | 读取无符号整数 |
readI64() | 有符号64位整数 | 8 | -2^63 ~ 2^63-1 | 读取带符号长整数 |
readU64() | 无符号64位整数 | 8 | 0 ~ 18,446,744,073,709,551,615 | 读取无符号长整数 |
readF32() | 单精度浮点数 | 4 | ±1.18×10^-38 ~ ±3.4×10^38 | 读取IEEE 754单精度浮点数 |
readF64() | 双精度浮点数 | 8 | ±2.23×10^-308 ~ ±1.80×10^308 | 读取IEEE 754双精度浮点数 |
返回值
local data = buff:read类型(number)
data返回值有两个,正常读取时为读取的数据,如果越界则为nil;
越界读取是指尝试从缓冲区中读取超出其实际存储范围的数据。在zbuff库中表现为:
- 当前指针位置 + 要读取的数据类型大小 > 缓冲区总长度;
- 或超出已写入数据的范围(如果使用
used
指针限制);
data
含义说明:按照类型读取数值,这里以I8为例,读取的8位有符号整数值;
数值类型:number;
取值范围:-128 ~ 127;
注意事项:将zbuff的read类型函数(如readU32, readI16等)按照指定格式进行文档化;
返回值示例:-- 创建小缓冲区;
local buff = zbuff.create(3)
-- 写入2字节;
buff:writeU16(0x1234)
-- 尝试读取不同类型数据 ;
-- 指针回到起点,准备开始读取;
buff:seek(0)
-- 成功读取2字节;
local data1 = buff:readU16()
-- 输出: U16值: 4660 (0x1234);
log.info("U16值:", data1)
-- 越界读取4字节 ;
local data2 = buff:readU32()
-- 输出: U32值: nil ;
log.info("U32值:", data2)
示例
-- 示例一;
-- 创建并初始化缓冲区;
local buff = zbuff.create(4)
-- 写入 -128 (0x80的二进制补码);
buff:writeI8(0x80)
-- 重置指针;
buff:seek(0)
-- 读取1字节有符号整数(-128 到 127);
-- 成功:返回整数值(如 10, -20, 0x7F),失败:返回 nil(缓冲区空间不足);
local data1 = buff:readI8()
-- 输出: 读取结果: -128;
log.info("读取结果:", data1)
-- 输出: 1;
log.info("当前指针:", buff:seek())
-- 示例二;
-- 创建并初始化缓冲区;
local buff = zbuff.create(6)
-- 写入最大32位无符号整数;
buff:writeU32(4294967295)
-- 重置指针;
buff:seek(0)
-- 读取4字节无符号整数(0 到 4,294,967,295);
-- 成功:返回整数值(如 1024, 0xFFFFFFFF),失败:返回 nil(缓冲区空间不足);
local data2 = buff:readU32()
-- 输出: 读取结果: 4294967295;
log.info("读取结果:", data2)
-- 输出: 4;
log.info("当前指针:", buff:seek())
4.9 buff:write类型(value)
功能
写入一个指定类型的数据(从当前指针位置开始;执行后指针会向后移动);
注意事项
-
从当前指针位置开始写入;
-
写入后指针自动向后移动1字节;
-
缓冲区空间不足时写入失败;
-
数值超出范围时会自动截断;
参数
value
参数含义:待写入的数值;
数据类型:number;
取值范围:按写入类型进行确认,数据类型对照表见下表;
是否必选:是;
注意事项:暂无;
参数示例:--写入1字节(I8类型);
local len = buff:writeI8(10)
支持的数据类型
函数名 | 数据类型 | 大小(字节) | 数值范围 | 说明 |
---|---|---|---|---|
writeI8() | 有符号8位整数 | 1 | -128 ~ 127 | 带符号字节 |
writeU8() | 无符号8位整数 | 1 | 0 ~ 255 | 无符号字节 |
writeI16() | 有符号16位整数 | 2 | -32768 ~ 32767 | 带符号短整数 |
writeU16() | 无符号16位整数 | 2 | 0 ~ 65535 | 无符号短整数 |
writeI32() | 有符号32位整数 | 4 | -2^31 ~ 2^31-1 | 带符号整数 |
writeU32() | 无符号32位整数 | 4 | 0 ~ 4,294,967,295 | 无符号整数 |
writeI64() | 有符号64位整数 | 8 | -2^63 ~ 2^63-1 | 带符号长整数 |
writeU64() | 无符号64位整数 | 8 | 0 ~ 18,446,744,073,709,551,615 | 无符号长整数 |
writeF32() | 单精度浮点数 | 4 | ±1.18×10^-38 ~ ±3.4×10^38 | IEEE 754标准 |
writeF64() | 双精度浮点数 | 8 | ±2.23×10^-308 ~ ±1.80×10^308 | IEEE 754标准 |
返回值
local len = buff:write类型(value)
有一个返回值len,表示成功按照类型写入的字节数;
含义说明:成功按照类型写入的字节数;
数值类型:number;
取值范围:按写入类型划分,写入失败返回0;
注意事项:暂无;
返回值示例:-- 创建8字节缓冲区;
local buff = zbuff.create(8)
-- 情景1:正常写入4字节(U32类型);
local len1 = buff:writeU32(0x12345678)
-- 输出: 返回值:4;
log.info("写入U32", "返回值:", len1, "预期值:4")
-- 情景2:写入2字节(U16类型);
local len2 = buff:writeU16(0xABCD)
-- 输出: 返回值:2;
log.info("写入U16", "返回值:", len2, "预期值:2")
-- 情景3:剩余空间不足;
-- 尝试再写入4字节(但只剩2字节空间);
local len3 = buff:writeU32(0xFFFFFFFF)
-- 输出: 返回值:0;
log.info("空间不足写入", "返回值:", len3, "预期值:0")
-- 验证指针位置;
-- 输出: 6 (4+2+0);
log.info("当前指针位置", buff:seek())
示例
-- writeI8 写入 1个字节 的8位有符号整数;
-- 返回值:1;
local len = buff:writeI8(10)
--writeU32 写入 4个字节 的32位无符号整数;
-- 返回值:4;
--如空间不足时返回 0;
local len = buff:writeU32(1024)
4.10 buff:toStr(offset,length)
功能
按起始位置和长度取出数据(与当前指针位置无关;执行后指针位置不变);
注意事项
-
不改变缓冲区指针位置;
-
支持部分数据提取(可指定起始位置和长度);
参数
offset
参数含义:数据读取起始位置;
数据类型:number;
取值范围:≥0,且小于缓冲区长度;
是否必选:否,默认为0(缓冲区起始位置);
注意事项:暂无;
参数示例:--读取开头的五个字节数据;
local s = buff:toStr(0,5)
length
参数含义:要提取的字节长度;
数据类型:number;
取值范围:≥0;
是否必选:否,默认情况下读取缓冲区所有数据;
注意事项:若指定长度超过可用空间,返回实际可用数据;
参数示例:-- 取出整个zbuff的数据
local s = buff:toStr()
-- 创建缓冲区并写入数据;
local buff = zbuff.create(20)
--实际使用16个字节;
buff:write("HelloLuatOSWorld")
-- 长度超出实际范围;
-- 输出: "World" (实际长度5);
local s = buff:toStr(10, 20)
返回值
local s = buff:toStr(offset,length)
有一个返回值 s;
s
含义说明:提取的字节数据转换成的字符串;
数值类型:string;
取值范围:任意string类型的字符串都行,无特别限制;
注意事项:暂无;
返回值示例:-- 创建并初始化缓冲区;
local buff = zbuff.create(10)
-- 写入10字节字符串;
buff:write("HelloWorld")
-- 移动指针到中间位置(不影响toStr);
buff:seek(5)
-- 读取开头的5字节;
local s1 = buff:toStr(0, 5)
-- 输出: "Hello";
log.info("开头5字节:", s1)
-- 读取整个缓冲区;
local s2 = buff:toStr()
-- 输出: "HelloWorld";
log.info("全部内容:", s2)
-- 读取已使用部分;
local s3 = buff:toStr(0, buff:used())
-- 输出: "HelloWorld" (同s2);
log.info("已用部分:", s3)
示例
-- 读取开头的五个字节数据;
local s = buff:toStr(0,5)
-- 取出整个zbuff的数据;
local s = buff:toStr()
-- 取出已使用的部分, 与buff:query()一样 ;
local s = buff:toStr(0, buff:used())
4.11 buff:len()
功能
获取zbuff对象的长度(与当前指针位置无关;执行后指针位置不变);
注意事项
-
该接口返回缓冲区创建时设置的固定长度,与缓冲区内容无关;
-
返回值始终等于创建缓冲区时指定的长度;
-
不会因读写操作改变返回值;
-
缓冲区对象自动扩容后,使用buff:len()获取的长度仍为创建时设置的长度;
参数
无
返回值
local length = buff:len()
有一个返回值 length;
length
含义说明:缓冲区的总容量(字节数);
数值类型:number;
取值范围:≥0的整数;
注意事项:返回值是创建时设置的固定值,不会随读写操作改变;
若缓冲区未创建或已释放,可能返回0或nil(取决于具体实现);
返回值示例:-- 创建不同大小的缓冲区;
-- 10字节缓冲区;
local buff1 = zbuff.create(10)
-- 1024缓冲区;
local buff2 = zbuff.create(1024)
-- 获取长度;
-- 输出: 10;
log.info("buff1长度:", buff1:len())
-- 输出: 1024 (使用#语法糖);
log.info("buff2长度:", #buff2)
--创建3字节缓冲区;
local buff3 = zbuff.create(3)
-- 写入6字节数据;
buff3:write(0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC)
-- 全部读取
local data = buff3:query(0, 6)
-- 通过data:toHex()转换为十六进制字符串显示
-- 输出: "123456"
log.info("query查询", "全部数据:", data:toHex())
-- 输出3,证明自动扩容后,长度仍为创建时设置的长度;
log.info("buff长度:", buff:len())
示例
len = buff:len()
len = #buff
--语法糖(Syntactic Sugar) 是指编程语言中一种特殊的语法,它不增加新功能,但能让代码更简洁易读。就像糖让食物更可口一样,语法糖让代码更"甜美"。
--在 Lua 中,# 是长度操作符,其默认行为是:对于字符串:返回字节数
log.info(#"Hello") -- 输出: 5
对于数组(table):返回连续数字索引的最大值
local arr = {10, 20, 30}
-- 输出: 3
log.info(#arr)
4.12 buff:setFrameBuffer(width,height,bit,color)
功能
设置buff对象的FrameBuffer属性,即设置buff对象的FrameBuffer属性(与当前指针位置无关;执行后指针位置不变);
注意事项
初始化后,zbuff将按照指定的宽度、高度和色深来解析缓冲区内存;
参数
width
参数含义:帧缓冲区的宽度(单位:像素);
数据类型:number;
取值范围:> 0;
是否必选:是;
注意事项:宽度与高度的乘积再乘以每个像素的字节数不能超过zbuff的总容量;
参数示例:--设置一个320*240,色深16的的FrameBuffer,填充颜色为白色;
result = buff:setFrameBuffer(320,240,16,0xffff)
height
参数含义:帧缓冲区的高度(单位:像素);
数据类型:number;
取值范围:> 0;
是否必选:是;
注意事项:宽度与高度的乘积再乘以每个像素的字节数不能超过zbuff的总容量;
参数示例:--设置一个320*300,色深16的的FrameBuffer,填充颜色为白色;
result = buff:setFrameBuffer(320,300,16,0xffff)
bit
参数含义:像素的色深(每个像素用多少位来表示它的颜色);
数据类型:number;
取值范围:常见的有 1(单色),8(灰度或调色板),16(如RGB565),24(如RGB888),32(如ARGB8888);
是否必选:是;
注意事项:色深决定了每个像素占用的字节数(bit/8)和可表示的颜色数量。务必确保zbuff的容量至少为 width * height * (bit / 8) 字节;
参数示例:--设置一个320*300,色深16的的FrameBuffer,填充颜色为白色;
result = buff:setFrameBuffer(320,300,16,0xffff)
color
参数含义:设置帧缓冲区后填充的背景颜色;
数据类型:number;
取值范围:取决于色深 bit。例如,对于16位色深(,颜色值范围是0x0000到0xFFFF;
是否必选:否,默认是黑色,0x0000;
注意事项:颜色值的具体含义需与色深匹配。0xF800表示红色,0x07E0表示绿色,0x001F表示蓝色,0xFFFF表示白色;
若不提供此参数,帧缓冲区内存的初始值将保持不变;
参数示例:--设置一个320*240,色深16的的FrameBuffer,填充颜色默认黑色;
result = buff:setFrameBuffer(320,240,16)
返回值
local result = buff:setFrameBuffer(width,height,bit,color)
有一个返回值result;
result
含义说明:设置操作是否成功;
数值类型:boolean;
取值范围:true - 成功;
false - 失败(通常是由于参数无效,例如所需的缓冲区大小超过了zbuff的实际容量);
注意事项:暂无;
返回值示例:-- 创建足够容纳320x240@16位色的缓冲区;
local buff = zbuff.create(320 * 240 * 2)
local result = buff:setFrameBuffer(320, 240, 16, 0xFFFF)
if result then
-- 输出:true;
log.info("帧缓冲初始化成功")
end
示例
内存不足会创建失败:缓冲区总空间小于帧缓冲所需大小(width × height × (bit/8))
-- 创建一个仅100字节的缓冲区;
local buff = zbuff.create(100)
local result = buff:setFrameBuffer(320, 240, 16, 0xFFFF)
-- 输出:false(需320 * 240 * 2=153,600字节);
log.info(result)
4.13 buff:pixel(x,y,color)
功能
操作帧缓冲区中指定坐标的像素值,支持 写入 或 读取 操作:
- 写入模式(提供
color
参数):设置(x, y)
处的像素颜色; - 读取模式(省略
color
参数):获取(x, y)
处的像素颜色值;
注意事项
1.此方法需在 zbuff 已通过 setFrameBuffer
初始化为帧缓冲区后使用;
2.颜色值 color
的解释取决于帧缓冲区初始化时指定的色深(bit depth),例如 16 位(RGB565)或 32 位(ARGB8888);
3.当仅提供 x
, y
参数时,为获取像素颜色操作;当提供 x
, y
, color
三个参数时,为设置像素颜色操作;
4.坐标 (x, y)
应从 (0, 0) 开始,且不应超过帧缓冲区的宽度和高度减一;
参数
x
参数含义:像素点的 X 轴坐标(水平方向,原点为左上角,向右递增);
数据类型:number;
取值范围:0 ≤ x < width (帧缓冲区宽度);
是否必选:是;
注意事项:超出范围的 x 坐标可能导致操作失败或未定义行为;
参数示例:rerult = buff:pixel(0,3,0)
y
参数含义:像素点的 Y 轴坐标(垂直方向,原点为左上角,向下递增);
数据类型:number;
取值范围:0 ≤ y < height (帧缓冲区高度);
是否必选:是;
注意事项:超出范围的 y 坐标可能导致操作失败或未定义行为;
参数示例:rerult = buff:pixel(0,20,0)
color
参数含义:要设置的像素颜色值;
数据类型:number;
取值范围:取决于帧缓冲区的色深(bit depth);
16位色深(RGB565): 0x0000 ~ 0xFFFF;
32位色深(ARGB8888): 0x00000000 ~ 0xFFFFFFFF;
是否必选:否(设置像素颜色时必选,获取像素颜色时不应提供);
注意事项:暂无;
参数示例:-- 示例1:设置坐标(0,3)位置像素颜色为黑色(写入模式);
local result = buff:pixel(0, 3, 0)
-- 示例2:获取坐标(0,3)位置的像素颜色(读取模式);
local color = buff:pixel(0, 3)
返回值
设置像素颜色时
local result = buff:pixel(x,y,color)
有一个返回值result,表示设置是否成功;
result
含义说明:像素颜色设置是否成功;
数值类型:boolean;
取值范围:true - 成功;
false - 失败(可能原因:坐标越界、缓冲区未初始化为FrameBuffer等);
注意事项:暂无;
获取像素颜色时
local color = buff:pixel(0,3)
有一个返回值color;
color
含义说明:指定坐标处的像素颜色值;
数值类型:number;
取值范围:与帧缓冲区色深对应的颜色值范围;
注意事项:如果获取失败(如坐标越界),会返回 nil;
示例
-- 创建 64x64 像素、16位色深(RGB565)的帧缓冲区,初始填充黑色
local buff = zbuff.create({64, 64, 16}, 0x0000)
-- 示例1:设置像素颜色(写入模式);
-- 功能:将坐标 (0, 3) 的像素设置为黑色(RGB565: 0x0000);
-- 参数:x=0, y=3, color=0;
-- 返回值:boolean 类型,表示操作是否成功;
local result = buff:pixel(0, 3, 0)
if result then
-- 输出:true(坐标有效且缓冲区已初始化);
log.info("像素写入成功")
else
-- 输出:false(坐标越界或非帧缓冲);
log.error("像素写入失败")
end
-- 示例2:获取像素颜色(读取模式);
-- 功能:读取坐标 (0, 3) 的像素颜色值;
-- 参数:x=0, y=3;
-- 返回值:number 类型(成功返回颜色值,失败返回 nil);
local color = buff:pixel(0, 3)
if color then
-- 输出:0x0000(黑色);
log.info("像素颜色", string.format("0x%04X", color))
else
-- 输出:nil(坐标越界);
log.warn("像素读取失败")
end
4.14 buff:drawLine(x1,y1,x2,y2,color)
功能
画一条线(与当前指针位置无关;执行后指针位置不变);
注意事项
此方法需在 zbuff 已通过 setFrameBuffer
初始化为帧缓冲区后使用;
参数
x1
参数含义:线条起点的 X 轴坐标(水平方向);
数据类型:number;
取值范围:0 ≤ x1 < width (帧缓冲区宽度);
是否必选:是;
注意事项:超出范围的坐标可能导致绘制不全或失败;
参数示例:rerult = buff:drawLine(20,0,2,3,0xffff)
y1
参数含义:线条起点的 Y 轴坐标(垂直方向);
数据类型:number;
取值范围:0 ≤ y1 < height (帧缓冲区高度);
是否必选:是;
注意事项:超出范围的坐标可能导致绘制不全或失败;
参数示例:rerult = buff:drawLine(0,20,2,3,0xffff)
x2
参数含义:线条终点的 X 轴坐标(水平方向);
数据类型:number;
取值范围:0 ≤ x2 < width (帧缓冲区宽度);
是否必选:是;
注意事项:超出范围的坐标可能导致绘制不全或失败;
参数示例:rerult = buff:drawLine(0,0,5,3,0xffff)
y2
参数含义:线条终点的 Y 轴坐标(垂直方向);
数据类型:number;
取值范围:0 ≤ y2 < height (帧缓冲区高度);
是否必选:是;
注意事项:超出范围的坐标可能导致绘制不全或失败;
参数示例:rerult = buff:drawLine(0,0,2,5,0xffff)
color
参数含义:线条的颜色值;
数据类型:number;
取值范围:取决于帧缓冲区的色深;
是否必选:是;
注意事项:颜色值的具体含义需与帧缓冲区的像素格式匹配;
常用值如 0xF800(红),0x07E0(绿),0x001F(蓝),0xFFFF(白);
参数示例:rerult = buff:drawLine(0,0,2,5,0xffff)
返回值
local success = buff:drawLine(x1,y1,x2,y2,color)
有一个返回值success,表示线条绘制是否成功;
success
含义说明:线条绘制是否成功;
数值类型:boolean;
取值范围:true - 成功;
false - 失败(可能原因:坐标越界、缓冲区未初始化为FrameBuffer等;
注意事项:暂无;
示例
-- 首先,创建一个足够大的缓冲区并初始化为FrameBuffer;
-- 128x160, 16位色深,背景色默认;
local buff = zbuff.create(128 * 160 * 2)
-- 初始化,背景色默认
buff:setFrameBuffer(128, 160, 16)
-- 从点 (10, 20) 到点 (100, 80) 绘制一条红色直线;
local result = fb:drawLine(10, 20, 100, 80, 0xF800)
if result then
log.info("线条绘制成功")
else
log.error("线条绘制失败")
end
-- 绘制一条水平绿线(Y坐标相同);
buff:drawLine(10, 50, 118, 50, 0x07E0)
-- 绘制一条垂直蓝线(X坐标相同);
buff:drawLine(64, 10, 64, 150, 0x001F)
4.15 buff:drawRect(x1,y1,x2,y2,color,fill)
功能
在帧缓冲区中绘制矩形,支持 空心边框 或 实心填充 两种模式。与当前指针位置无关;执行后指针位置不变);
注意事项
-
需先通过
setFrameBuffer
初始化帧缓冲区; -
坐标范围必须在帧缓冲区尺寸内;
参数
x1
参数含义:矩形左上角 X 坐标;
数据类型:number;
取值范围:0 ≤ x1 < width;
是否必选:是;
注意事项:超出范围会导致绘制失败;
参数示例:rerult = buff:drawRect(0,0,2,3,0xffff)
y1
参数含义:矩形左上角 Y 坐标;
数据类型:number;
取值范围:0 ≤ y1 < height;
是否必选:是;
注意事项:超出范围会导致绘制失败;
参数示例:rerult = buff:drawRect(0,0,2,3,0xffff)
x2
参数含义:矩形右下角 X 坐标;
数据类型:number;
取值范围:0 ≤ x2 < width;
是否必选:是;
注意事项:需大于 x1;
参数示例:rerult = buff:drawRect(0,0,2,3,0xffff)
y2
参数含义:矩形右下角 Y 坐标;
数据类型:number;
取值范围:0 ≤ y2 < height;
是否必选:是;
注意事项:需大于 y1;
参数示例:rerult = buff:drawRect(0,0,2,3,0xffff)
color
参数含义:矩形颜色值;
数据类型:number;
取值范围:根据色深确定;
是否必选:是;
注意事项:暂无;
参数示例:rerult = buff:drawRect(0,0,2,3,0xffff)
fill
参数含义:填充模式开关;
数据类型:boolean;
取值范围:true/false;
是否必选:否;
注意事项:true=填充矩形, false=仅绘制边框(默认);
参数示例:rerult = buff:drawRect(0,0,2,3,0xffff)
返回值
local result = buff:drawRect(x1,y1,x2,y2,color,fill)
有一个返回值result,表示绘制操作是否成功;
result
含义说明:绘制操作是否成功;
数值类型:boolean;
取值范围:true/false;
注意事项:失败原因可能是坐标越界或未初始化帧缓冲区;
示例
-- 创建 64x64 像素、16位色深的帧缓冲区(初始黑色);
local buff = zbuff.create({64, 64, 16}, 0x0000)
-- 绘制实心绿色矩形 (左上角: (0,0), 右下角: (2,3));
local result = buff:drawRect(0, 0, 2, 3, 0x07E0,true)
-- 检查返回值
if result then
-- 输出: true
log.info("矩形绘制成功")
else
-- 输出: false
log.error("矩形绘制失败")
end
-- 验证绘制效果;
-- 取矩形内部点;
local pixel_color = buff:pixel(1, 1)
-- 输出: 0x07E0(绿色);
log.info("像素颜色", string.format("0x%04X", pixel_color))
4.16 buff:drawCircle(x,y,r,color,fill)
功能
在帧缓冲区中绘制圆形或圆环,支持 空心边框 或 实心填充 两种模式。(与当前指针位置无关;执行后指针位置不变);
注意事项
-
需先通过 setFrameBuffer 初始化帧缓冲区;
-
使用中点圆算法绘制;
-
坐标范围必须在帧缓冲区尺寸内;
参数
x
参数含义:圆心 X 坐标;
数据类型:number;
取值范围:0 ≤ x < width;
是否必选:是;
注意事项:需在帧缓冲区内回执,超出范围会导致绘制不全;
参数示例:rerult = buff:drawCircle(15,5,3,0xC)
y
参数含义:圆心 Y 坐标;
数据类型:number;
取值范围:0 ≤ y < height;
是否必选:是;
注意事项:需在帧缓冲区内回执,超出范围会导致绘制不全;
参数示例:rerult = buff:drawCircle(15,5,3,0xC)
r
参数含义:圆的半径(像素);
数据类型:number;
取值范围:> 0;
是否必选:是;
注意事项:半径过大可能导致部分区域超出画布;
参数示例:rerult = buff:drawCircle(15,5,3,0xC)
color
参数含义:圆的颜色值;
数据类型:number;
取值范围:取决于帧缓冲区的色深;
是否必选:否,默认为0;
注意事项:暂无;
参数示例:rerult = buff:drawCircle(15,5,3,0xC)
fill
参数含义:填充模式开关;
数据类型:boolean;
取值范围:true/false;
是否必选:否,默认为false;
注意事项:true=填充圆形, false=仅绘制边框(默认);
参数示例:rerult = buff:drawCircle(15,5,3,0xC,true)
返回值
local result = buff:drawCircle(x,y,r,color,fill)
有一个返回值result,表示绘制是否成功;
result
含义说明:绘制操作是否成功;
数值类型:boolean;
取值范围:true/false;
注意事项:失败原因可能是坐标越界或未初始化帧缓冲区;
示例
-- 在坐标 (15,5) 绘制半径 3 像素的红色空心圆环 ;
local result1 = buff:drawCircle(15, 5, 3,0xC)
-- 返回值说明:
-- 成功:true(圆心在缓冲区内且半径有效);
-- 失败:false(如圆心越界或半径≤0);
-- 在坐标 (15,5) 绘制半径 3 像素的红色实心圆 ;
-- 返回值:true(绘制成功);
local result = buff:drawCircle(15, 5, 3, 0xC, true)
4.17 buff[n]
功能
通过下标索引直接读写 zbuff 缓冲区中的字节数据(类似数组操作)。此操作与指针位置无关,且执行后指针位置不变;
注意事项
该操作为只读,支持通过下标索引进行读写操作,可以读取和修改缓冲区中的字节数据;
参数
n
参数含义:要访问的字节在缓冲区中的位置索引;
数据类型:number;
取值范围:1 ≤ n ≤ zbuff:len();
是否必选:是;
注意事项:索引值必须是整数,小数部分会被截断;
索引超出范围(小于1或大于缓冲区长度)时返回nil;
参数示例:-- 访问缓冲区第1个字节;
buff[1]
-- 访问缓冲区第5个字节;
buff[5]
返回值
local data = buff[n]
有一个返回值data;
data
含义说明:缓冲区中指定位置的字节值;
数值类型:number;
取值范围:0-255;
注意事项:当索引无效时返回nil;
返回值仅表示字节数值,不包含其他元数据;
示例
-- 创建 8 字节缓冲区,初始全 0;
local buff = zbuff.create(8)
-- 写入数据(下标 0 位置写入 0xC8);
buff[0] = 0xC8
-- 输出: 0xC8;
log.info("写入值", string.format("0x%02X", buff[0]))
-- 读取数据;
local data = buff[0]
-- 输出: 200(0xC8 的十进制);
log.info("读取值", data)
4.18 buff:free()
功能
释放zbuff所申请内存 注意:gc时会自动释放zbuff以及zbuff所申请内存,所以通常无需调用此函数,调用前请确认您已清楚此函数用处!调用此函数并不会释放掉zbuff,仅会释放掉zbuff所申请的内存,zbuff需等gc时自动释放!!!
注意事项
暂无;
参数
无
返回值
无
示例
-- 创建 zbuff 对象;
local buff = zbuff.create(1024)
-- 使用 zbuff 对象...;
-- 释放 zbuff 对象;
buff:free()
4.19 buff:resize(n)
功能
动态调整 zbuff 缓冲区分配的内存空间大小(类似 C 语言的 realloc
,new = realloc(old, n)),支持扩容或缩容。调整后:
-
扩容:保留原数据,新增空间未初始化;
-
缩容:截断超出新长度的数据,若
used > len
则强制used =新len
;
注意事项
-
新大小 n 必须大于 0,否则调整失败;
-
扩容调整后原数据保留,新增部分填充为 0;
-
缩小缓冲区时,超出新尺寸的数据会被丢弃;
参数
n
参数含义:调整后的缓冲区大小;
数据类型:number;
取值范围:正整数(≥1);
是否必选:必须传入此参数;
注意事项:若传入值小于1,会返回false;
调整后读写指针位置不变(除非指针超出新尺寸范围);
参数示例:-- 将缓冲区大小调整为1024字节;
buff:resize(1024)
返回值
无
示例
示例 1:基本扩容(保留数据)
-- 创建初始缓冲区(8字节);
local buff = zbuff.create(8)
-- 写入4字节,used=4;
buff:write("ABCD")
-- 输出: 8;
log.info("原长度", buff:len())
-- 扩容至20字节;
buff:resize(20)
-- 输出: 20;
log.info("新长度", buff:len())
-- 输出: 4(数据保留);
log.info("有效数据", buff:used())
-- 验证数据完整性;
buff:seek(0)
local data = buff:read(4)
-- 输出: "ABCD";
log.info("数据", data)
示例 2:缩容及数据截断
-- 创建含数据的缓冲区 ;
local buff = zbuff.create(10)
-- 写入9字节,used=9;
buff:write("123456789")
-- 缩容至5字节(截断超出部分);
buff:resize(5)
-- 输出: 5(强制used=5);
log.info("used", buff:used())
-- 尝试读取被截断数据 ;
buff:seek(0)
-- 实际读取5字节;
local data = buff:read(10)
-- 输出: "12345"('6789'丢失);
log.info("截断后数据", data)
4.20 buff:copy(start, para,...)
功能
zbuff动态写数据,类似于memcpy效果,当原有空间不足时动态扩大空间;
注意事项
-
此方法用于高效地将数据复制到 zbuff 中,类似于 C 语言的 memcpy;
-
当目标位置超出当前缓冲区大小时,会自动扩容缓冲区以适应数据;
-
复制操作会更新缓冲区的已使用位置指针 (used);
-
支持多种数据源类型:字符串、数值、其他 zbuff 对象;
参数
start
参数含义:数据写入的起始位置偏移量
数据类型:number/nil
取值范围:整数/nil
是否必选:否
注意事项:为nil时,从当前已使用位置 (used) 开始写入
为负数时,从已使用位置向前偏移(如 -1 = used - 1)
超出当前长度时,缓冲区会自动扩容
参数示例:-- 类似于memcpy(&buff[used], "123", 3) used+= 3 从buff开始写入数据,指针相应地往后移动;
local len = buff:copy(nil, "123")
para
参数含义:要写入的数据内容;
数据类型:any;
取值范围:string/zbuff/number;
是否必选:是;
注意事项:string: 作为整体字符串写入;
zbuff: 复制另一个zbuff对象的内容;
number: 可接受多个数值参数,每个作为单独字节写入;
参数示例:--当参数是string类型时;
local len = buff:copy(0, "123")
--当参数是number类型时;
local len = buff:copy(3, 0x1a,0x30,0x31,0x32,0x00,0x01)
--当参数是zbuff时;
local len = buff:copy(9, buff2)
...(可变参数)
参数含义:当para参数是另一个zbuff对象时,这个参数代表的是buff2的起点和长度;
数据类型:当第para数据是zbuff时,...为两个参数(偏移和长度)为number类型;
如果是数值,则后面可以继续跟数值;
取值范围:偏移和长度必须是非负整数,且不能超出源zbuff的范围;
是否必选:可选;
注意事项:当para参数是zbuff时,如果只提供zbuff对象,不提供偏移和长度,则默认从zbuff2的0位置拷贝整个
used长度;
如果提供偏移和长度,则按照指定范围拷贝;
参数示例:--从位置 5 复制 buff2 的 (10,1024) 区间
local len = buff:copy(5, buff2, 10, 1024)
返回值
local len = buff:copy(start, para,...)
有一个返回值len,代表数据成功写入的长度;
len
含义说明:实际写入的数据长度(字节数);
数值类型:number;
取值范围:非负整数;
注意事项:暂无;
示例
示例 1:从 used 位置写入字符串;
-- 创建初始缓冲区(8字节);
local buff = zbuff.create(8)
-- 写入 "AB",used=2;
buff:write("AB")
-- 从 used 位置写入 "123"(等效于追加);
local len = buff:copy(nil, "123")
-- 等效操作: memcpy(&buff[used], "123", 3) → used += 3;
-- 输出: 3;
log.info("写入长度", len)
-- 输出: "AB123";
log.info("当前内容", buff:toStr())
-- 输出: 5 ;
log.info("used 位置", buff:used())
示例 2:覆盖写入字符串(指定起始位置);
-- 从位置 0 写入 "123"(覆盖开头);
local len = buff:copy(0, "123")
-- 等效操作: memcpy(&buff[0], "123", 3) → used = max(used, 3) ;
-- 输出: 3;
log.info("写入长度", len)
-- 输出: "12323"(覆盖了前3字节);
log.info("当前内容", buff:toStr())
示例 3:写入数值列表(多字节数据);
-- 从位置 2 写入字节序列 [0x1A, 0x30, 0x31] ;
local len = buff:copy(2, 0x1A, 0x30, 0x31)
-- 等效操作: memcpy(&buff[2], [0x1A,0x30,0x31], 3) → used = max(used, 5);
-- 输出: 3;
log.info("写入长度", len)
-- 输出: "31321A3031000000";
log.info("HEX 内容", buff:toStr():toHex())
示例 4:合并另一个 zbuff
-- 创建源缓冲区(含数据 "CD");
local buff2 = zbuff.create(5)
-- buff2.used=2
buff2:write("CD")
-- 从位置 9 合并 buff2 的内容(自动扩容)
local len = buff:copy(9, buff2)
-- 等效操作: memcpy(&buff[9], &buff2[0], buff2.used);
-- 原 buff 长度 8 → 扩容至 11 (9+2);
-- 输出: 2;
log.info("合并长度", len)
-- 输出: "31321A30310000004344";
log.info("合并后内容", buff:toStr(0, 11):toHex())
示例 5:复制 zbuff 的指定区间;
-- 从位置 5 复制 buff2 的 (0,2) 区间(2字节);
local len = buff:copy(5, buff2, 0, 2)
-- 等效操作: memcpy(&buff[5], &buff2[0], 2);
-- 输出: 2;
log.info("复制长度", len)
-- 输出: "31321A30314344";
log.info("最终内容", buff:toStr(0, 7):toHex())
4.21 buff:used(offset)
功能
设置/获取zbuff里最后一个数据位置指针到首地址的偏移量,来表示zbuff内已有有效数据量大小,注意这个不同于分配的空间大小,由于seek()会改变最后一个数据位置指针,因此也会影响到used()返回值;
注意事项
1.该操作会修改 zbuff 的内部状态(若设置偏移量);
2.设置的值会被自动限制在 zbuff 的实际长度范围内;
3.若通过 buff:seek()
移动指针,会影响 used()
的返回值;
参数
offset
参数含义:要设置的有效数据长度;
数据类型:number;
取值范围:应为正整数。设置的值会被自动限制在 zbuff 的实际长度范围内(即不超过缓冲区的总容量);
是否必选:否,此为可选参数。不传递该参数时,函数会返回当前的used值;
注意事项:该操作会修改 zbuff 对象的 used 属性(有效数据长度);
如果通过 buff:seek() 移动了指针位置,会影响 used() 的返回值;
参数示例:-- 直接返回当前的有效数据量大小 ;
local buff = zbuff.create(10)
buff:write("ABC")
-- 输出三字节;
local used = buff:used()
返回值
local used = buff:used(offset)
有一个返回值used;
used
含义说明:设置后的有效数据长度或当前有效数据长度;
数值类型:number;
取值范围:0 ≤ used ≤ buff:len();
注意事项:获取模式:返回当前有效数据长度;
示例
示例 1:基础读取与设置
-- 创建 10 字节缓冲区;
local buff = zbuff.create(10)
-- 写入 3 字节;
buff:write("ABC")
-- 读取当前有效数据量;
local used1 = buff:used()
-- 输出: 3
log.info("初始有效数据", used1)
-- 设置有效数据量为 6 字节;
local used2 = buff:used(6)
-- 输出: 6(未超缓冲区长度);
log.info("设置后有效数据", used2)
示例 2:越界设置与自动修正
-- 尝试设置超出缓冲区长度的值(15 > 10);
local used3 = buff:used(15)
-- 输出: 10(自动修正为缓冲区长度);
log.info("越界设置结果", used3)
-- 验证数据完整性;
buff:seek(0)
-- 读取全部有效数据;
local data = buff:read(10)
-- 输出: "41424300000000000000",即"ABC" + 7 字节未初始化数据;
log.info("读取内容", data:toHex())
示例 3:seek() 对 used() 的影响
-- 重置指针到位置 3;
buff:seek(3)
-- 输出: 3(与指针位置同步);
log.info("seek后有效数据", buff:used())
-- 写入新数据(从指针位置开始);
buff:write("DE")
-- 输出: 5(指针从 3 移动到 5);
log.info("写入后有效数据", buff:used())
4.22 buff:del(offset,length)
功能
删除zbuff 0~used范围内的一段数据,注意只是改变了used的值,并不是真的在ram里去清除掉数据;
注意事项
1.此方法用于删除 zbuff 缓冲区中的部分数据;
2.如果指定的偏移(offset)或长度(length)无效,可能无法删除任何数据;
3.执行删除操作后,缓冲区的读写指针(seek position)位置不会自动改变,需要注意其可能指向已失效的位置;
参数
offset
参数含义:要删除的数据的起始位置偏移量;
数据类型:number;
取值范围:整数;
是否必选:是;
注意事项:如果 offset 超过缓冲区的已使用长度(used),则不会删除任何数据;
参数示例:-- 从位置1开始删除4个字节数据;
buff:del(1,4)
length
参数含义:要删除的字节数;
数据类型:number;
取值范围:非负整数;
是否必选:是;
注意事项:如果 length 为 0,则不会删除任何数据;
如果 offset + length 超过了缓冲区的已使用长度(used),则只会删除从 offset 开始到缓冲区末尾的数据;
参数示例:-- 从位置used-1开始删除4个字节数据;
-- 但是这肯定会超过used,所以del_len会调整为1,实际上就是删掉了最后一个字节
buff:del(-1,4)
返回值
无
示例
示例 1:基本删除(验证 used 变化)
-- 创建含数据的缓冲区 ;
local buff = zbuff.create(10)
-- 写入 9 字节,used=9;
buff:write("123456789")
-- 删除位置 1 开始的 4 字节,即删除 "2345";
buff:del(1, 4)
-- 输出: 5 (9-4);
log.info("删除后 used", buff:used())
-- 读取剩余数据 ;
buff:seek(0)
-- 输出: "16789"(物理内存仍存 "2345",但逻辑不可见);
log.info("剩余数据", buff:read(10))
示例 2:负数索引与长度截断
-- 从倒数第 1 字节开始删除(实际起始位置=9);
-- 要求删 4 字节,但可用空间仅 1 字节;
buff:del(-1, 4)
-- 输出: 9(仅删除最后 1 字节);
log.info("删除后 used", buff:used())
4.23 buff:query(offset,length,isbigend,issigned,isfloat)
功能
从 zbuff 缓冲区中提取指定范围的原始数据,如果是1,2,4,8字节,且填写了isbigend参数,则根据isbigend,issigned,isfloat转换成浮点或者整形。该操作不改变指针位置,且支持端序、符号和浮点类型的灵活配置;
注意事项
-
此方法用于从缓冲区中灵活提取和解析二进制数据;
-
支持多种数据类型:整数(8/16/32位)、浮点数(32/64位);
-
字节序(大端/小端)会影响多字节数据的解析结果;
-
偏移量和长度参数必须有效,否则可能返回 nil 或错误数据;
参数
offset
参数含义:数据查询的起始位置偏移量;
数据类型:number;
取值范围:非负整数;
是否必选:是;
注意事项:必须为非负整数,且小于缓冲区长度;
参数示例:-- 读取开头的五个字节数据;
local s = buff:query(0,5)
length
参数含义:要查询的数据字节长度;
数据类型:number;
取值范围:非负整数;
是否必选:是;
注意事项:必须为非负整数,且小于缓冲区长度;
参数示例:-- 读取开头的五个字节数据;
local s = buff:query(0,5)
isbigend
参数含义:是否使用大端序(Big-Endian)格式解析数据。若为 nil,则不进行转换,直接返回字节流字符串,
false为小端格式,true为大端格式;
数据类型:boolean;
取值范围:true(大端序)、false(小端序)、nil(不转换);
是否必选:否;
注意事项:仅当显式指定(非 nil)且数据长度为 1、2、4 或 8 字节时,才触发类型转换。默认行为为 nil(不转换);
参数示例:-- 从偏移量0读取4字节,并按大端序转换为32位无符号整数;
local s = buff:query(0, 4, true, false, false)
issigned
参数含义:是否将数据解析为有符号整型;
数据类型:boolean;
取值范围:true(有符号)、false(无符号)。默认为 false;
是否必选:否;
注意事项:仅当数据被转换为整型时生效。浮点型数据忽略此参数
参数示例:--从偏移量0读取4字节,并按大端序转换为32位无符号整数;
local s = buff:query(0, 4, true, false, false)
isfloat
参数含义:是否将数据解析为浮点型;
数据类型:boolean;
取值范围:true(浮点型)、false(整型)。默认为 false。
是否必选:否;
注意事项:若为 true,数据被转换为浮点数(float 或 double);否则转换为整型;
参数示例:--从偏移量0读取4字节,并按大端序转换为32位无符号整数;
local s = buff:query(0, 4, true, false, false)
返回值
local data = buff:query(offset,length,isbigend,issigned,isfloat)
有一个返回值data
data
含义说明:读出来的数据;
数值类型:string/number;
取值范围:无特殊范围;
注意事项:data读出来的数据,转换规则:
isbigend=nil:返回原始字节字符串,需要通过toHex()进行转换;
isbigend≠nil 且 length∈{1,2,4,8}**:返回解析后的数值;
示例
-- 1. 写入二进制数据到zbuff缓冲区;
-- 功能:向zbuff的当前指针位置写入6个字节的十六进制数据(0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC);
-- 注意:写入后指针会自动向后移动6字节;
-- 参数:可变长度number类型(每个值代表1字节,范围0x00-0xFF);
-- 无显式返回值(实际返回写入字节数6);
buff:write(0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC)
-- 2. 查询完整缓冲区数据(原始字节流);
-- 功能:从偏移量0开始读取6字节原始数据(不转换格式);
-- 返回值:字符串类型,包含6字节原始二进制数据;
-- 返回: "\x12\x34\x56\x78\x9A\xBC";
local data = buff:query(0, 6)
-- 通过data:toHex()转换为十六进制字符串显示;
-- 输出: "123456789ABC";
log.info("query查询", "全部数据:", data:toHex())
-- 3. 带格式的数据查询与转换;
-- 功能:从偏移量0读取4字节,并按大端序转换为32位无符号整数;
-- 参数说明:
-- 0:起始偏移量;
-- 4:读取长度(需为1/2/4/8字节才触发转换);
-- true:大端序(false为小端序);
-- false:无符号整数(true为有符号);
-- false:非浮点数;
-- 返回值:number类型;
local part_data = buff:query(0, 4, true, false, false)
-- 转换逻辑:
-- 原始字节: 0x12, 0x34, 0x56, 0x78;
-- 大端序组合: 0x12345678 → 十进制305419896;
-- 输出: 305419896;
log.info("query查询", "大端序格式:", part_data)
4.24 buff:set(start, num, len)
功能
对 zbuff 缓冲区进行批量内存填充(类似 C 的 memset
),支持指定起始位置、填充值和长度。此操作不改变读写指针位置,且自动处理边界越界问题;
注意事项
有越界保护,如果设置的len超出zbuff的范围,会自动截断;
参数
start
参数含义:设置操作的起始位置;
数据类型:number;
取值范围:非负整数,且小于zbuff的长度。如果start大于zbuff的长度,则操作不会执行;
是否必选:否,如果不填,默认为0;
注意事项:如果start为负数,则会被视为0;
参数示例:--等同于 memset(buff, 0, sizeof(buff)),全部初始化为0;
buff:set()
num
参数含义:要设置的字节值;
数据类型:number;
取值范围:0-255(一个字节的范围);
是否必选:否,如果不填,默认为0;
注意事项:如果num超出0-255的范围,则会被截断(取低8位);
参数示例:--等同于 memset(buff, 0x55, sizeof(buff)),全部填充0x55;
buff:set(0, 0x55)
len
参数含义:要设置的字节数;
数据类型:number;
取值范围:非负整数,且不超过从start开始到zbuff末尾的剩余长度;
是否必选:否,如果不填,则默认为从start开始到zbuff末尾的剩余长度;
注意事项:如果len超出zbuff的剩余长度,则自动调整为剩余长度;
参数示例:--等用于 memset(&buff[4], 0xaa, 12),从0-12字节,填充0xaa;
buff:set(4, 0xaa, 12)
返回值
无
示例
示例 1:全缓冲区清零
-- 全部填充为 0(等效 memset(buff, 0, 8));
buff:set()
示例 2:部分填充特定值
-- 从位置 2 开始填充 4 字节为 0xAA ;
buff:set(2, 0xAA, 4)
示例 3:越界与截断验证
-- 尝试越界填充(起始位置 10 > 缓冲区长度 8);
buff:set(10, 0xFF, 5) -- 实际填充长度=0(无操作);
-- 长度超出边界(起始位置 6,长度 5 → 实际填充 2 字节);
buff:set(6, 0x55, 5)
示例 4:特殊值截断
-- 使用超范围值 0x123,当调用 buff:set(0, 0x123) 时,0x123 的二进制表示为 0001 0010 0011(共 12 位)。由于 zbuff 的 set() 方法以单字节(8 位) 为单位填充内存,超出 8 位的高位部分会被自动丢弃,仅保留低 8 位:0x123 的低 8 位为 0010 0011 → 十六进制 0x23。因此,实际填充值为 0x23,而非原始输入的 0x123;
-- 全缓冲区填充 0x23
-- 输出应为: "2323232323232323";
buff:set(0, 0x123)
4.25 buff:isEqual(start, buff2, start2, len)
功能
用于比较两个 zbuff 对象中指定区域的字节数据是否相等,类似于标准 C 库的 memcmp
操作。该函数会对比源 zbuff 和目标 zbuff 中指定偏移位置和长度的数据,并返回比较结果;
注意事项
暂无;
参数
start
参数含义:源 zbuff 中比较数据的起始偏移位置(以字节为单位);
数据类型:number;
取值范围:必须 ≥0,若为负数会被自动调整为从 used() 末尾向前计算(例如 -1 表示 used() - 1);
是否必选:可选,不填时默认为 0(从 zbuff 开头开始比较);
注意事项:起始位置超出 zbuff 长度时,函数会返回不相等结果(false 和错误位置码);
参数示例:--等同于memcmp(&buff[1], &buff2[2], 10);
--从第一个buff的第一字节和第二buff的第二字节,开始比较10个字节;
local result, offset = buff:isEqual(1, buff2, 2, 10)
buff2
参数含义:目标 zbuff 对象,即要与源 zbuff 比较数据的另一个 zbuff 实例;
数据类型:userdata(zbuff 对象);
取值范围:必须是有效的 zbuff 对象(通过 zbuff.create 创建),否则会导致 Lua 运行时错误;
是否必选:必须传入此参数;
注意事项:目标 zbuff 必须已初始化且包含有效数据;空对象或未创建对象会触发异常;
参数示例:--等同于memcmp(&buff[1], &buff2[2], 10);
--从第一个buff的第一字节和第二buff的第二字节,开始比较10个字节;
local result, offset = buff:isEqual(1, buff2, 2, 10)
start2
参数含义:目标 zbuff(buff2)中比较数据的起始偏移位置(以字节为单位);
数据类型:number;
取值范围:必须 ≥0,若为负数会被自动调整为从 buff2:used() 末尾向前计算;
是否必选:可选,不填时默认为 0(从目标 zbuff 开头开始比较);
注意事项:起始位置超出目标 zbuff 长度时,函数会返回不相等结果;
参数示例:--等同于memcmp(&buff[1], &buff2[2], 10);
--从第一个buff的第一字节和第二buff的第二字节,开始比较10个字节;
local result, offset = buff:isEqual(1, buff2, 2, 10)
len
参数含义:需要比较的数据长度(以字节为单位);
数据类型:number;
取值范围:必须 ≥0,长度为 0 时视为所有数据相等(直接返回 true 和 0);
是否必选:必须传入此参数;
注意事项:若 len 大于源或目标 zbuff 的可用数据范围(used() - start 或 buff2:used() - start2);
函数会自动缩小 len 至最小可用范围;
参数示例:--等同于memcmp(&buff[1], &buff2[2], 10);
--从第一个buff的第一字节和第二buff的第二字节,开始比较10个字节;
local result, offset = buff:isEqual(1, buff2, 2, 10)
返回值
local equal, offset = buff:isEqual(start, buff2, start2, len)
存在两个返回值,equal和offset;
equa
含义说明:true 表示两个 zbuff 指定区域的数据完全相等;false 表示数据不相等;
数据类型:boolean;
取值范围:true 或 false;
注意事项:返回 true 仅当所有字节数据一致;任何差异(包括长度不足)均返回 false;
offset
含义说明:详细比较结果的位置码。若数据相等,返回 0;若数据不相等,返回第一个不匹配字节在源 zbuff 中的全局偏移位置(从 0 开始索引);
数据类型:number;
取值范围:相等时为 0;不相等时为 ≥0的整数(表示第一个差异位置);
注意事项:位置码基于源 zbuff 的绝对偏移量计算,不受 start 参数影响。例如返回 3 表示源 zbuff 的第 4 个字节与目标不一致;
示例
示例 1:基本相等性验证
-- 创建两个相同内容的缓冲区;
local buff1 = zbuff.create(8)
-- 全填充 0x12;
buff1:set(0, 0x12, 8)
local buff2 = zbuff.create(8)
buff2:set(0, 0x12, 8)
-- 比较全部内容(起始位置均为0,长度8);
local equal, offset = buff1:isEqual(0, buff2, 0, 8)
-- 输出: true, 0 ;
log.info("完全相等", equal, offset)
示例 2:部分数据不匹配
-- 修改 buff2 的中间字节;
-- 位置3写入 0x34(原为0x12);
buff2[3] = 0x34
-- 比较前4字节
local equal, offset = buff1:isEqual(0, buff2, 0, 4)
-- 输出: false, 3 ;
log.info("部分不相等","结果:", equal,"差异位置:", offset)
4.26 buff:toBase64(dst)
功能
将当前zbuff数据转base64,输出到下一个zbuff中;
注意事项
1.目标 zbuff 空间要求:目标 zbuff 对象 dst
的长度必须大于等于源数据长度的 1.35 倍(即 dst:len() >= buff:used() * 1.35
)。若空间不足,转换会失败;
2.为什么不支持自动扩容:如果支持扩容,可能会变成 开始编码——发现空间不够——暂停编码,重新分配内存——复制已有数据到新缓冲区——继续编码——可能再次空间不够,重复步骤2-5——这样会导致编码过程被多次打断,效率低下;
3.数据范围:仅转换源 zbuff 的有效数据部分(0
到 buff:used()
范围内的数据),不包括未使用的预留空间;
4.指针位置:转换操作不会改变源或目标 zbuff 的当前指针位置;
5.输出格式:生成的 Base64 是连续字符串(不含换行符),符合 RFC 4648 标准;
参数
dst
参数含义: 目标zbuff对象,用于存储转换后的Base64字符串;
数据类型:zbuff对象;
取值范围: 必须是一个已经创建的zbuff对象,且其长度必须大于等于当前zbuff对象有效数据长度(即buff:used())乘以1.35;
是否必选: 是;
参数示例:-- 创建足够大的目标缓冲区;
local dst = zbuff.create(buff:used() * 2)
-- 进行Base64编码;
local len = buff:toBase64(dst)
返回值
local len = buff:toBase64(dst)
有一个返回值len;
len
含义说明: 转换后的Base64字符串的长度(字节数);
数据类型: number;
取值范围: 大于等于0的整数;
注意事项:暂无;
示例
local buff = zbuff.create(12)
--写入"Hello"的ASCII码;
buff:write(0x48, 0x65, 0x6C, 0x6C, 0x6F)
-- 创建足够大的目标缓冲区;
local dst = zbuff.create(buff:used() * 2)
-- 进行Base64编码;
local len = buff:toBase64(dst)
--输出结果 Base64编码 长度: 8 结果: SGVsbG8=;
log.info("Base64编码", "长度:", len, "结果:", dst:toStr(0, len))
原始字节:0x48, 0x65, 0x6C, 0x6C, 0x6F → 二进制分组:
010010 000110 010101 101100 → "S" (18), "G" (6), "V" (21)
011011 000110 111100 → "s" (27), "b" (6), "G" (32), "8" (60)
五、产品支持说明
支持 LuatOS 开发的所有产品都支持 zbuff 核心库。