跳到主要内容

VfpPackageReader:容器与区段

VfpPackageReader 是纯数据 Reader:不创建 ArkGraphics Scene、不上传 Mesh,也不修改输入。通过 VoxelKit.createVfpReader() 创建。

解析与 CRC 校验

parse()

parse(bytes: ArrayBuffer): VfpDocument

验证 Header、Footer、DIR0 的版本、位置、目录 CRC、条目边界、codec/flags/reserved 合法性,返回目录对象。parse() 不会遍历每个载荷 CRC,也不会恢复 VOXO。

validate()

validate(bytes: ArrayBuffer): VfpDocument

先执行 parse(),再校验所有已存储区段的 CRC32。适合入库前排除截断、损坏文件;它仍不是权威体素校验,权威校验应调用 validateAuthoritative()

const reader = VoxelKit.createVfpReader();
try {
const document = reader.validate(bytes);
console.info('VFP ' + document.majorVersion + '.' + document.minorVersion);
} catch (error) {
console.error('container invalid');
}

VfpDocument 查询方法

方法签名结果
findSection(tag: string, chunkId: number = -1): VfpSection | undefined找到第一个匹配目录项。
entries(tag: string): Array<VfpSection>找到同一 tag 的所有条目,例如所有 VOX0
sectionTags(): Array<string>返回目录顺序的 tag 列表。

VfpDocument 字段 majorVersionminorVersionfileSizesourceHashdirectoryOffsetdirectoryLengthgenerationsections 都是只读解析结果。sourceHash 是 Header 声明值,只有权威校验成功时才可信。

精确提取

extractSection()

extractSection(bytes: ArrayBuffer, section: VfpSection): ArrayBuffer

重新解析目录,确认传入条目属于当前文件,再校验该区段 CRC,返回一个独立的字节副本。不要把来自另一份 VFP 的 VfpSection 传入。

extractByTag()extractTextByTag()

extractByTag(bytes: ArrayBuffer, tag: string, chunkId: number = -1): ArrayBuffer
extractTextByTag(bytes: ArrayBuffer, tag: string, chunkId: number = -1): string
readManifestText(bytes: ArrayBuffer): string

chunkId=-1 表示全局区段。readManifestText() 等价于读取 META 的 UTF-8 文本。对于不存在的 tag、CRC 不匹配、无效 UTF-8,方法会抛出错误。

const manifestText = reader.readManifestText(bytes);
const firstVoxelChunk = reader.extractByTag(bytes, 'VOX0', 0);
console.info(manifestText + firstVoxelChunk.byteLength);

META 用于展示与配置提示,不能取代 validateAuthoritative()

VfpSection 字段

字段类型含义
indexnumberDIR0 中的条目索引。
tagstring四字符区段标识。
codecnumber0 为 RAW8,1 为 RLE8。
flagsnumber当前版本必须为 0。
chunkIdnumber全局段为 -1,分块段为其 Chunk ID。
offset/length/rawLengthnumber存储位置、存储长度、恢复长度。
crc32number已存储载荷的 CRC32。

不要直接按 offset 切原始字节后跳过 CRC;统一使用提取 API。