扩展库 / bson

bson

在 BSON 文档与 XLang 字典之间转换;C 端可直接操作 XRT xvalue。

版本 3.0.0 · C / xlang · 无扩展库依赖

当前冻结发布版的语言字典进入 encode(var) 仍报“encode requires a table”,下方字典编码例子受共享 M1 阻断。2026-10-29 Windows 前36阶段满足预期,含新数值边界、15个真实原型和五个独立程序,第37阶段仍失败;外部 bytes 解码成功不代替完整双向能力。最新双平台证据以包 README 和发布验收矩阵为准。

快速开始

import bson

var wire = bson.encode({"name": "xlang", "count": 7})
var document = bson.decode(wire)
println(document["name"])
println(bson.docLength(wire))

根值必须是字典。原始 BSON 使用 bytes,不使用字符串承载二进制;解码入口只接受 bytes。

接口与边界

入口用途
encode(doc) / decode(data)字典与单个 BSON 文档互转。
concat(a, b) / decodeAll(data)拼接及读取连续文档流;concat 只校验外层 framing,不完整解析,不可信输入需先 decode。
load(path) / save(path, doc)通过 XRT 文件接口读取和原子保存 BSON;读取时执行 64 MiB 限额,写入失败不截断旧文件。
objectId() / oidTime(hex24)生成 24 位十六进制 ID;提取时间并返回 XLang time。
toHex(data) / docLength(data)诊断十六进制和读取文档长度。

支持嵌套字典、连续数组/列表、UTF-8 字符串、bytes(Binary subtype 0)、int32/int64、double、bool、null 和 BSON Date。二进制字段可原样往返。ObjectId 解码为十六进制字符串,再编码不会保留 ObjectId 类型。其余 BSON 特殊类型不在公开模型内。重复键、非连续数组索引、无效 UTF-8、截断及尾随数据报错。单次数据上限 64 MiB;toHex 的输出翻倍,输入最多 32 MiB,超限在分配前拒绝。文档层数上限 64(根文档计一层);整份文档的字段/数组项合计最多 100 万,连续流 decodeAll 对全部文档累计计数。编解码、concat 和 toHex 的资源超限对应 C XERR_RANGE / XLang RangeError,畸形格式仍报值错误。docLength 只检查外层头部长度、总字节数和结束字节;检查不通过返回 0,正文是否有效仍须由 decode 验证。

BSON Date 仅有毫秒精度;微秒时间不能整除 1000 时拒绝编码,不会静默丢精度。超出 XRT 时间范围的 BSON Date 也拒绝解码。

路径和 ObjectId 文本不允许内嵌 NUL;错误不会按截断后的名称读写文件。生成的 ObjectId 使用时间戳及安全随机字节,不承诺顺序递增。

C 对照

#define XRT_MODULE_ALL
#include "xrt.h"
#include "bson_native.h"

int main(void)
{
    xvalue* document = xrtValueObject();
    xvalue* wire = xbson_encode(document);
    xvalue* restored = xbson_decode(wire);
    int ok = restored && xrtValueType(restored) == XVALUE_OBJECT;
    xrtValueRelease(restored);
    xrtValueRelease(wire);
    xrtValueRelease(document);
    return ok ? 0 : 1;
}

C 动态值结果由调用方 xrtValueRelease;失败返回 null 值并设置 XRT 错误。xbson_to_hex 与 xbson_gen_oid 的结果用 xrtFree 释放。双语对照范例在 release/extlibs/bson/examples/,覆盖单文档、连续文档流、HEX、ObjectId 与显式路径的保存/载入;输出有独立预期,保存文件逐字节对照。从发布目录运行 ./xl run extlibs/bson/examples/bson_c.c 即可执行 C 范例。此单文件范例包含原生实现,正式包构建仍独立编译。

数值载荷与错误边界

Double、Int32、Int64、Date 必须完整读取后才创建结果值。截断时不再先创建零值又丢弃,防止这次无效分配失败覆盖已知格式错误。正常格式、类型、毫秒精度、ABI 与所有权不变,依据 BSON 1.1 规范。

新的 C 定向检查包含1008个截断/错误后故障组合、72合法对照及72条逐点 OOM/立即恢复路径,覆盖嵌套数组/文档、直接和动态值入口以及前置合法文档的连续流,并观察工厂调用及存活分配。XLang另有56个截断用例和合法 Int64 的 MemoryError/恢复检查;不是完整 BSON fuzz。

examples/numeric_fields.xl 与 numeric_fields_c.c 读取同一份固定标准字节,展示 Int32、Int64、Double 与负毫秒 Date;五行固定输出由门禁对照。不借助本库编码器构造该输入,也不删除语言字典编码的必过正例。

验证状态

powershell -NoProfile -ExecutionPolicy Bypass -File release/extlibs/bson/test/check.ps1
bash release/extlibs/bson/test/check.sh

从仓库根目录执行。Linux C 路径使用 ASan/UBSan 与泄漏检查;所有子进程有限时,运行前后核对输入指纹,失败保留独占目录、命令及真实输出。CC工具缺失明确失败,不静默跳过。包内详情源已更新,不代表外部官网已经部署。下方旧日期结果是历史证据,不能推翻当前 M1。

2026-10-21 保存链路新增 C/XLang 逐点分配故障回归:编码或原子写入失败保留内存错误及已有文件,清除故障后可保存并读回。Windows 严格 GCC、C/XLang 和核心 AOT 快测与 Linux C ASan/UBSan、XLang 联合门禁通过;完整 AOT 共享阻断未变。

2026-10-26 当前 Windows 发布版默认门禁先通过严格 C、原生边界和 C 范例,但语言字典传入 encode(var) 时报告 bson: encode requires a table (var dict);Windows/Linux 最小复现均失败。当前首要阻断是共享 foreign var 字典投影,完整语言与 AOT 尚未验收,不签收发布级。旧 AOT 缺符号属于历史发布物状态。公开 C 头直接使用 XRT xvalue,整数结果为 int64_t;包内固定畸形文档与分配故障测试的范围见 README。

NUL 路径负例使用独占系统临时目录,不再覆盖或删除固定 build/test 文件。2026-10-20 Windows 聚焦门禁及 Linux C ASan/UBSan、XLang 门禁复跑通过;完整带输出 AOT 的共享阻断不变。

2026-10-21:C 边界测试的原子保存失败与超大文件限额用例改用门禁传入的独占工作目录,不再写删固定 build/test/bson_guard 文件。Windows -SkipAot 的严格 C、XLang、双语范例和核心 AOT,以及 Linux C ASan/UBSan、XLang 联合门禁通过;旧固定目录保留。完整带输出 AOT 仍受共享主线缺符号阻断,不签收整包发布级。