UNPKG

@iwater/mdict-ts

Version:

mdict (*.mdx, *.mdd) file reader

111 lines (110 loc) 3.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Scan = void 0; const lzo1x_1 = require("../lib/lzo1x"); const pako_1 = require("pako"); const util_1 = require("./util"); class Scan { constructor(attrs) { attrs.Encoding = attrs.Encoding || 'UTF-16'; this.searchTextLen = (dv, offset) => { let mark = offset; if (attrs.Encoding === 'UTF-16') { while (this.dv.getUint16(offset)) { offset += this.bpu; } return offset - mark; } else { while (dv.getUint8(offset++)) { } return offset - mark - 1; } }; this.decoder = new util_1.textDecoder(attrs.Encoding || 'UTF-16LE'); this.bpu = (attrs.Encoding === 'UTF-16') ? 2 : 1; this.readShort = () => this.readUint8(); this.readNum = () => this.readInt(); if (parseInt(attrs.GeneratedByEngineVersion, 10) >= 2.0) { this.v2 = true; this.tail = this.bpu; this.readNum = () => { this.forward(4); return this.readInt(); }; this.readShort = () => this.readUint16(); this.checksumV2 = () => this.checksum(); } else { this.tail = 0; } } init(buf) { this.offset = 0; this.buf = buf; this.dv = new util_1.dataView(buf); return this; } forward(len) { this.offset += len; return this; } readInt() { return [this.dv.getUint32(this.offset), this.forward(4)][0]; } readUint16() { return [this.dv.getUint16(this.offset), this.forward(2)][0]; } readUint8() { return [this.dv.getUint8(this.offset), this.forward(1)][0]; } readText() { let len = this.searchTextLen(this.dv, this.offset); return [this.decoder.decode(util_1.newUint8Array(this.buf, this.offset, len)), this.forward(len + this.bpu)][0]; } readTextSized(len) { len *= this.bpu; return [this.decoder.decode(util_1.newUint8Array(this.buf, this.offset, len)), this.forward(len + this.tail)][0]; } checksum() { this.forward(4); } readBlock(len, expectedBufSize, decryptor) { let comp_type = this.dv.getUint8(this.offset); if (comp_type === 0) { if (this.v2) this.forward(8); return this; } else { let tmp; this.offset += 8; len -= 8; if (util_1.isBrowser) { tmp = new Uint8Array(this.buf, this.offset, len); } else { tmp = new Uint8Array(len); this.buf.copy(tmp, 0, this.offset, this.offset + len); } if (decryptor) { let passkey = new Uint8Array(8); if (util_1.isBrowser) { passkey.set(new Uint8Array(this.buf, this.offset - 4, 4)); } else { this.buf.copy(passkey, 0, this.offset - 4, this.offset); } passkey.set([0x95, 0x36, 0x00, 0x00], 4); tmp = decryptor(tmp, passkey); } tmp = comp_type === 2 ? pako_1.inflate(tmp) : lzo1x_1.lzo.decompress(tmp); this.forward(len); return this.init(util_1.isBrowser ? tmp.buffer : Buffer.from(tmp)); } } readRaw(len) { return this.buf.slice(this.offset, this.offset + len); } } exports.Scan = Scan;