Files
Aislo/tools/est-test/export-options.cjs

58 lines
2.0 KiB
JavaScript

const { Values } = require("./import-estx.cjs");
// Preserve every unedited property byte and the surrounding memory-table records.
function updateOptions(buffer, changes, encode) {
const pieces = [];
let cursor = 0,
offset = 0;
const remaining = new Map(Object.entries(changes));
while ((offset = buffer.indexOf("TPF0", offset)) >= 0) {
const length = offset >= 4 ? buffer.readUInt32LE(offset - 4) : 0;
if (length < 6 || offset + length > buffer.length) {
offset += 4;
continue;
}
const reader = new Values(buffer.subarray(offset, offset + length));
const className = reader.short();
reader.short();
const changesForClass = remaining.get(className);
if (!changesForClass) {
offset += length;
continue;
}
const edits = [];
while (reader.buffer[reader.position] !== 0) {
const name = reader.short(),
start = reader.position;
reader.value();
if (Object.hasOwn(changesForClass, name)) {
edits.push([start, reader.position, encode(changesForClass[name])]);
delete changesForClass[name];
}
}
const end = reader.position;
for (const [name, value] of Object.entries(changesForClass)) {
const key = Buffer.from(name, "ascii");
edits.push([end, end, Buffer.concat([Buffer.from([key.length]), key, encode(value)])]);
}
const parts = [];
let position = 0;
for (const [start, stop, data] of edits) {
parts.push(reader.buffer.subarray(position, start), data);
position = stop;
}
parts.push(reader.buffer.subarray(position));
const object = Buffer.concat(parts),
size = Buffer.alloc(4);
size.writeUInt32LE(object.length);
pieces.push(buffer.subarray(cursor, offset - 4), size, object);
cursor = offset + length;
offset = cursor;
remaining.delete(className);
}
if (remaining.size) throw Error(`ESTX 옵션 객체 없음: ${[...remaining.keys()].join(", ")}`);
pieces.push(buffer.subarray(cursor));
return Buffer.concat(pieces);
}
module.exports = { updateOptions };