@phi-ag/rvt
Version:
Parse Revit file format
75 lines (74 loc) • 2.65 kB
JavaScript
import * as array from "../utils/array.js";
import { readDate } from "./utils.js";
export var EntryColor;
(function (EntryColor) {
EntryColor[EntryColor["Red"] = 0] = "Red";
EntryColor[EntryColor["Black"] = 1] = "Black";
})(EntryColor || (EntryColor = {}));
export var EntryType;
(function (EntryType) {
EntryType[EntryType["Unknown"] = 0] = "Unknown";
EntryType[EntryType["Storage"] = 1] = "Storage";
EntryType[EntryType["Stream"] = 2] = "Stream";
EntryType[EntryType["RootStorage"] = 5] = "RootStorage";
})(EntryType || (EntryType = {}));
const decoder = new TextDecoder("utf-16le");
const parseEntry = (data) => {
const view = new DataView(data.buffer, data.byteOffset);
const maxNameLength = 64;
const nameLength = view.getUint16(maxNameLength, true);
const name = decoder.decode(data.subarray(0, nameLength - 2));
const type = data[66];
if (!(type in EntryType))
throw Error(`Unexpected entry type (${type})`);
const color = data[67];
if (!(color in EntryColor))
throw Error(`Unexpected entry color (${color})`);
const left = view.getInt32(68, true);
const right = view.getInt32(72, true);
const child = view.getInt32(76, true);
const clsid = data.slice(80, 80 + 16);
const state = view.getInt32(96, true);
const hasCreated = !array.isZero(data.subarray(100, 108));
const created = hasCreated ? readDate(view, 100) : undefined;
const hasModified = !array.isZero(data.subarray(108, 116));
const modified = hasModified ? readDate(view, 108) : undefined;
const start = view.getInt32(116, true);
const size = view.getInt32(120, true);
return {
name,
type,
color,
left,
right,
child,
clsid,
state,
created,
modified,
start,
size
};
};
const parseDirectorySector = (entryCount, sector) => {
const entries = [];
for (let i = 0; i < entryCount; i++) {
const start = i * 128;
const entry = parseEntry(sector.subarray(start, start + 128));
if (entry.type !== 0)
entries.push(entry);
}
return entries;
};
export const parseDirectory = (header, sectors) => {
const entryCount = header.version === 3 ? 4 : 32;
const entries = [];
for (let i = 0; i < header.directorySectorCount; i++) {
const start = i * header.sectorSize;
const end = start + header.sectorSize;
const sectorEntries = parseDirectorySector(entryCount, sectors.subarray(start, end));
for (const entry of sectorEntries)
entries.push(entry);
}
return entries;
};