扩展库 / bson

bson

数据格式
v3.0.0 C 混编 0 依赖 ABI 1

MongoDB BSON 二进制序列化编解码 — var 直转架构,无需 Builder/Iterator 中间层。table 字面量直接编码为 BSON,解码后直接用字符串键索引、整数下标访问数组、xtime 自动互操作。

典型场景

MongoDB 数据交换 二进制持久化 网络协议序列化 日志结构化存储 配置快照

快速开始

quick_start.xl
import bson

func main(...) as int
    // 一行编码:var table → BSON 二进制
    var bin = bson.encode({"name": "xlang", "ver": 6, "tags": ["fast", "safe"]})

    // 一行解码:BSON → var,直接索引
    var doc = bson.decode(bin)
    println(doc["name"])       // xlang
    println(doc["tags"][0])    // fast

    // 文件 I/O
    bson.save("data.bson", doc)
    var loaded = bson.load("data.bson")
    return 0
end

核心特性

类型映射表

xlang varBSON 类型说明
stringString (0x02)UTF-8 文本
int (≤32bit)Int32 (0x10)自动判断范围
int (>32bit)Int64 (0x12)自动判断范围
floatDouble (0x01)64-bit IEEE 754
boolBoolean (0x08)true/false
nullNull (0x0A)空值
xtimeDate (0x09)毫秒精度
tableDocument (0x03)嵌套文档
array / listArray (0x04)有序序列

包信息

字段值
包名bson
版本3.0.0
实现C 混编 (TCC 内嵌编译)
内核cloudwu/lua-bson (MIT)
依赖无
ABI1

核心 API

bson.encode(var doc) as var

将 var table 编码为 BSON 二进制。自动推断值类型:int→Int32/Int64, float→Double, xtime→Date, table→Document, array/list→Array。

bson.decode(var data) as var

将 BSON 二进制解码为 var table。Document→table, Array→array, Date→xtime, String→string。

bson.decodeAll(var data) as var

解码拼接的 BSON 流(多个文档连续存放),返回 array of table。适用于 MongoDB 导出文件。

bson.concat(var a, var b) as var

二进制安全拼接两个 BSON var。用于构造多文档流(var 的 + 运算符对含 null 字节的二进制不安全)。

bson.load(string path) as var

从文件加载 BSON 并解码为 var table。

bson.save(string path, var doc) as int

将 var table 编码为 BSON 并写入文件,返回写入字节数。

工具函数

bson.objectId() as string

生成 24 字符十六进制 ObjectId(兼容 MongoDB 格式:4字节时间戳 + 5字节机器标识 + 3字节计数器)。

bson.oidTime(string hex24) as int

从 ObjectId 提取创建时间,返回 xtime 秒数。可用 time(oidTime(...)) 转为 xtime 类型。

bson.toHex(var data) as string

将 BSON 二进制转为十六进制字符串(调试用)。

bson.docLength(var data) as int

读取 BSON 文档头部声明的字节长度(不解析内容)。

教学范例

覆盖全部 API 的逐步教学代码:

bson.xl
import bson

func main(...) as int
    // ═══ 1. 基本编解码 ═══
    var doc = {"name": "xlang", "version": 6, "pi": 3.14159, "active": true}
    var bin = bson.encode(doc)
    println("编码长度: ", bson.docLength(bin))

    var decoded = bson.decode(bin)
    println("name = ", decoded["name"])
    println("version = ", decoded["version"])

    // ═══ 2. 嵌套文档 ═══
    var nested = {"type": "user", "profile": {"city": "Beijing", "zip": 100000}}
    var n = bson.decode(bson.encode(nested))
    println("city = ", n["profile"]["city"])

    // ═══ 3. 数组 ═══
    var withArr = {"title": "demo", "tags": ["dev", "fun", "xlang"]}
    var a = bson.decode(bson.encode(withArr))
    println("tag[0] = ", a["tags"][0])
    println("tags.length = ", a["tags"].length)

    // ═══ 4. null 和 int64 ═══
    var mixed = {"nothing": null, "big": 9876543210, "small": 42}
    var m = bson.decode(bson.encode(mixed))
    println("big = ", m["big"])

    // ═══ 5. ObjectId ═══
    string oid1 = bson.objectId()
    println("OID: ", oid1)
    int oidSecs = bson.oidTime(oid1)
    println("OID 年份: ", time.year(time(oidSecs)))

    // ═══ 6. Hex 调试 ═══
    string hexStr = bson.toHex(bson.encode({"x": 1}))
    println("hex: ", hexStr)

    // ═══ 7. 文件 I/O ═══
    int written = bson.save("data.bson", {"saved": true, "count": 7})
    var loaded = bson.load("data.bson")
    println("loaded.count = ", loaded["count"])

    // ═══ 8. 多文档流 ═══
    var stream = bson.concat(bson.encode({"id": 1}), bson.encode({"id": 2}))
    var docs = bson.decodeAll(stream)
    println("文档数: ", docs.length)

    println("bson example: PASS")
    return 0
end

运行范例

终端
cd release
xl.exe run examples\extlibs\bson.xl

测试覆盖

测试文件:extlibs/bson/test/bson_test.xl,覆盖全部公开 API:

完整测试代码

bson_test.xl
import bson

func main(...) as int
    print("=== bson var 直转测试 ===")

    // 1. 基本往返
    var doc = {"name": "xlang", "version": 6, "pi": 3.14159, "active": true}
    var bin = bson.encode(doc)
    print("编码长度: " + string(bson.docLength(bin)))
    var decoded = bson.decode(bin)
    print("name = " + string(decoded["name"]))
    print("version = " + string(decoded["version"]))

    // 2. 嵌套文档
    var nested = {"type": "user", "profile": {"city": "Beijing", "zip": 100000}}
    var n = bson.decode(bson.encode(nested))
    print("city = " + string(n["profile"]["city"]))

    // 3. 数组
    var withArr = {"title": "test", "tags": ["dev", "fun", "xlang"]}
    var a = bson.decode(bson.encode(withArr))
    print("tag0 = " + string(a["tags"][0]))
    print("len = " + string(a["tags"].length))

    // 4. null / int64
    var mixed = {"nothing": null, "big": 9876543210, "small": 42}
    var m = bson.decode(bson.encode(mixed))
    print("big = " + string(m["big"]))

    // 5. ObjectId
    string oid1 = bson.objectId()
    print("OID: " + oid1)
    int oidT = bson.oidTime(oid1)
    print("OID 年份: " + string(time.year(time(oidT))))

    // 6. Hex
    string hexStr = bson.toHex(bson.encode({"x": 1}))
    print("hex: " + hexStr)

    // 7. 文件 I/O
    int written = bson.save("build/bson_test_tmp.bson", {"saved": true, "count": 7})
    var loaded = bson.load("build/bson_test_tmp.bson")
    print("loaded.count = " + string(loaded["count"]))

    // 8. 多文档流
    var stream = bson.concat(bson.encode({"id": 1, "msg": "hello"}),
                             bson.encode({"id": 2, "msg": "world"}))
    var docs = bson.decodeAll(stream)
    print("文档数: " + string(docs.length))
    print("doc[0].msg = " + string(docs[0]["msg"]))

    print("=== 测试完成 ===")
    return 0
end

运行测试

终端
cd release
xl.exe run extlibs\bson\test\bson_test.xl
← 返回扩展库列表