ts-ebml-esm
Version:
ebml decoder and encoder
143 lines (142 loc) • 4.66 kB
JavaScript
import { toBigIntBE as r } from "bigint-buffer";
import { c as _, r as i, a as c } from "./tools-CVDSnz1X.js";
import f from "matroska-schema";
const { byEbmlID: d } = f;
class m {
constructor() {
this._buffer = Buffer.alloc(0), this._tag_stack = [], this._state = 1, this._cursor = 0, this._total = 0, this._schema = d, this._result = [];
}
decode(t) {
this.readChunk(t);
const e = this._result;
return this._result = [], e;
}
readChunk(t) {
for (this._buffer = _([this._buffer, Buffer.from(t)]); this._cursor < this._buffer.length && !(this._state === 1 && !this.readTag() || this._state === 2 && !this.readSize() || this._state === 3 && !this.readContent()); )
;
}
getSchemaInfo(t) {
return this._schema[t] != null ? this._schema[t] : {
name: "unknown",
level: -1,
type: "unknown",
description: "unknown"
};
}
/**
* parsing vint-ed tag
* @return - return false when waiting for more data
*/
readTag() {
if (this._cursor >= this._buffer.length)
return !1;
const t = i(this._buffer, this._cursor);
if (t == null)
return !1;
const s = this._buffer.subarray(this._cursor, this._cursor + t.length).reduce(
(h, u, l, o) => h + u * Math.pow(16, 2 * (o.length - 1 - l)),
0
), a = this.getSchemaInfo(s), n = {
EBML_ID: s.toString(16),
schema: a,
type: a.type,
name: a.name,
level: a.level,
tagStart: this._total,
tagEnd: this._total + t.length,
sizeStart: this._total + t.length,
sizeEnd: null,
dataStart: null,
dataEnd: null,
dataSize: null,
data: null
};
return this._tag_stack.push(n), this._cursor += t.length, this._total += t.length, this._state = 2, !0;
}
/**
* Reads the size of the vint-ed current tag content
* @return - return false when waiting for more data
*/
readSize() {
if (this._cursor >= this._buffer.length)
return !1;
const t = i(this._buffer, this._cursor);
if (t == null)
return !1;
const e = this._tag_stack[this._tag_stack.length - 1];
return e == null ? !1 : (e.sizeEnd = e.sizeStart + t.length, e.dataStart = e.sizeEnd, e.dataSize = t.value, t.value === -1 ? (e.dataEnd = -1, e.type === "m" && (e.unknownSize = !0)) : e.dataEnd = e.sizeEnd + t.value, this._cursor += t.length, this._total += t.length, this._state = 3, !0);
}
readContent() {
const t = this._tag_stack[this._tag_stack.length - 1];
if (t == null)
return !1;
if (t.type === "m") {
if (t.isEnd = !1, this._result.push(t), this._state = 1, t.dataSize === 0) {
const s = Object.assign({}, t, { isEnd: !0 });
this._result.push(s), this._tag_stack.pop();
}
return !0;
}
if (this._buffer.length < this._cursor + t.dataSize)
return !1;
const e = this._buffer.subarray(
this._cursor,
this._cursor + t.dataSize
);
switch (this._buffer = this._buffer.subarray(this._cursor + t.dataSize), t.data = e, t.type) {
// case "m": {
// // Master-Element - contains other EBML sub-elements of the next lower level
// throw new Error("never");
// }
case "u": {
e.length > 6 ? t.value = Number(r(e)) : t.value = e.readUIntBE(0, e.length);
break;
}
case "i": {
t.value = e.readIntBE(0, e.length);
break;
}
case "f": {
t.dataSize === 4 ? t.value = e.readFloatBE(0) : t.dataSize === 8 ? t.value = e.readDoubleBE(0) : (console.warn(
`cannot read ${t.dataSize} octets float. failback to 0`
), t.value = 0);
break;
}
case "s": {
t.value = e.toString("ascii");
break;
}
case "8": {
t.value = e.toString("utf8");
break;
}
case "b": {
t.value = e;
break;
}
case "d": {
t.value = c(Number(r(e)));
break;
}
}
if (t.value === null)
throw new Error("unknown tag type:" + t.type);
for (this._result.push(t), this._total += t.dataSize, this._state = 1, this._cursor = 0, this._tag_stack.pop(); this._tag_stack.length > 0; ) {
const s = this._tag_stack[this._tag_stack.length - 1];
if (s == null)
return !1;
if (s.dataEnd < 0)
return this._tag_stack.pop(), !0;
if (this._total < s.dataEnd)
break;
if (s.type !== "m")
throw new Error("parent element is not master element");
const a = Object.assign({}, s, { isEnd: !0 });
this._result.push(a), this._tag_stack.pop();
}
return !0;
}
}
export {
m as default
};