跳转至

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缓冲区/创建帧缓冲区;

注意事项

  1. 创建失败返回nil,需检查返回值;

  2. 指定data参数时会填充初始数据;

  3. 可创建普通缓冲区或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,...)

功能

从当前指针位置写入数据(支持多参数),指针自动后移;

注意事项

  1. 写入后指针自动后移;

  2. 支持多参数写入;

参数

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读数据:从当前指针读取指定长度的二进制数据,指针自动后移;

注意事项

  1. 读取后指针自动后移;

  2. 读取长度不能超过缓冲区剩余空间,超过会被截断;

参数

length

参数含义:读取长度;
数据类型:number
取值范围:>0的整数;
是否必选:是;
注意事项:超过剩余空间会截断;
参数示例:-- 类file的读写操作
         local str = buff:read(3)

返回值

local str = buff:read(length)

有一个返回值str;

str

含义说明:读取的数据;
数值类型:string
取值范围:长度为0length的字符串
注意事项:暂无;

示例

-- 写入 'A'(0x41)、'B'(0x42)、'C'(0x43);
buff:write(0x410x420x43)  
-- 指针复位 准备开始读取;
buff:seek(0) 
local str = buff:read(3) 
-- 输出 "414243";
log.info("Hex数据:", data:toHex())  

4.4 buff:clear(num)

功能

zbuff清空数据(与当前指针位置无关;执行后指针位置不变)全缓冲区填充指定值;

注意事项

  1. 清空操作不影响缓冲区大小;

  2. 指针位置保持不变;

  3. 默认填充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移动读写指针位置(与当前指针位置有关;执行后指针会被设置到指定位置);

注意事项

  1. 指针位置范围:0 ~ buff:len()-1;

  2. 超出范围的偏移会自动调整到边界值;

  3. 查询模式不改变指针位置;

  4. 修改模式会改变当前指针位置;

参数

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,...)

功能

将一系列数据按照格式字符转化,并写入(从当前指针位置开始;执行后指针会向后移动);

注意事项

  1. 从当前指针位置开始打包;

  2. 打包后指针自动向后移动;

  3. 支持多种数据类型和字节序控制;

  4. 格式字符串控制打包方式;

参数

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)

功能

将一系列数据按照格式字符读取出来(从当前指针位置开始;执行后指针会向后移动)

注意事项

  1. 从当前指针位置开始解包;

  2. 解包后指针自动向后移动;

  3. 格式字符串控制解包方式;

  4. 缓冲区数据不足时可能返回部分结果;

参数

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)

功能

读取一个指定类型的数据(从当前指针位置开始;执行后指针会向后移动);

注意事项

  1. 从当前指针位置开始读取;

  2. 读取后指针自动向后移动;

  3. 使用系统默认字节序;

  4. 缓冲区数据不足时返回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. 从当前指针位置开始写入;

  2. 写入后指针自动向后移动1字节;

  3. 缓冲区空间不足时写入失败;

  4. 数值超出范围时会自动截断;

参数

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)

功能

按起始位置和长度取出数据(与当前指针位置无关;执行后指针位置不变);

注意事项

  1. 不改变缓冲区指针位置;

  2. 支持部分数据提取(可指定起始位置和长度);

参数

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对象的长度(与当前指针位置无关;执行后指针位置不变);

注意事项

  1. 该接口返回缓冲区创建时设置的固定长度,与缓冲区内容无关;

  2. 返回值始终等于创建缓冲区时指定的长度;

  3. 不会因读写操作改变返回值;

  4. 缓冲区对象自动扩容后,使用buff:len()获取的长度仍为创建时设置的长度;

参数

返回值

local length = buff:len()

有一个返回值 length;

length

含义说明:缓冲区的总容量(字节数);
数值类型:number
取值范围:≥0的整数;
注意事项:返回值是创建时设置的固定值,不会随读写操作改变;
         若缓冲区未创建或已释放,可能返回0nil(取决于具体实现);
返回值示例:-- 创建不同大小的缓冲区;
           -- 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位色深(,颜色值范围是0x00000xFFFF
是否必选:否,默认是黑色,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)

功能

在帧缓冲区中绘制矩形,支持 空心边框 或 实心填充 两种模式。与当前指针位置无关;执行后指针位置不变);

注意事项

  1. 需先通过 setFrameBuffer 初始化帧缓冲区;

  2. 坐标范围必须在帧缓冲区尺寸内;

参数

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)

功能

在帧缓冲区中绘制圆形或圆环,支持 空心边框 或 实心填充 两种模式。(与当前指针位置无关;执行后指针位置不变);

注意事项

  1. 需先通过 setFrameBuffer 初始化帧缓冲区;

  2. 使用中点圆算法绘制;

  3. 坐标范围必须在帧缓冲区尺寸内;

参数

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

注意事项

  1. 新大小 n 必须大于 0,否则调整失败;

  2. 扩容调整后原数据保留,新增部分填充为 0;

  3. 缩小缓冲区时,超出新尺寸的数据会被丢弃;

参数

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效果,当原有空间不足时动态扩大空间;

注意事项

  1. 此方法用于高效地将数据复制到 zbuff 中,类似于 C 语言的 memcpy;

  2. 当目标位置超出当前缓冲区大小时,会自动扩容缓冲区以适应数据;

  3. 复制操作会更新缓冲区的已使用位置指针 (used);

  4. 支持多种数据源类型:字符串、数值、其他 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())           

示例 3seek()  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转换成浮点或者整形。该操作不改变指针位置,且支持端序、符号和浮点类型的灵活配置;

注意事项

  1. 此方法用于从缓冲区中灵活提取和解析二进制数据;

  2. 支持多种数据类型:整数(8/16/32位)、浮点数(32/64位);

  3. 字节序(大端/小端)会影响多字节数据的解析结果;

  4. 偏移量和长度参数必须有效,否则可能返回 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)且数据长度为 124  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()进行转换;
         isbigendnil  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 实例;
数据类型:userdatazbuff 对象);
取值范围:必须是有效的 zbuff 对象(通过 zbuff.create 创建),否则会导致 Lua 运行时错误;
是否必选:必须传入此参数;
注意事项:目标 zbuff 必须已初始化且包含有效数据;空对象或未创建对象会触发异常;
参数示例:--等同于memcmp(&buff[1], &buff2[2], 10);
         --从第一个buff的第一字节和第二buff的第二字节,开始比较10个字节;
         local result, offset = buff:isEqual(1, buff2, 2, 10 

start2

参数含义:目标 zbuffbuff2)中比较数据的起始偏移位置(以字节为单位);
数据类型: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 的有效数据部分(0buff: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 核心库。