48 lines
1.5 KiB
JavaScript
48 lines
1.5 KiB
JavaScript
async function loadLZMAPrefixCompressor(prefixFilename) {
|
|
class PrefixCompressor {
|
|
constructor(prefix, compress, decompress, bytesToIgnore) {
|
|
this.prefix = prefix;
|
|
this.prefixCompressed = compress(prefix);
|
|
this.bytesToIgnore = bytesToIgnore;
|
|
this.baseCompress = compress;
|
|
this.baseDecompress = decompress;
|
|
}
|
|
|
|
compress(str) {
|
|
const c = this.baseCompress(this.prefix + str);
|
|
for (var i = this.bytesToIgnore;
|
|
i < this.prefixCompressed.length
|
|
&& this.prefixCompressed[i] == c[i];
|
|
i++) { }
|
|
const omittedBytes = this.prefixCompressed.length - i;
|
|
const res = c.subarray(i - 1);
|
|
res[0] = omittedBytes;
|
|
return res;
|
|
}
|
|
|
|
decompress(arr) {
|
|
const omittedBytes = arr[0];
|
|
const prefixBytes = this.prefixCompressed.length-omittedBytes;
|
|
const c = new Uint8Array(prefixBytes + arr.length-1);
|
|
c.set(this.prefixCompressed.subarray(0, prefixBytes));
|
|
c.set(arr.subarray(1), prefixBytes);
|
|
const d = this.baseDecompress(c);
|
|
return d.substring(this.prefix.length);
|
|
}
|
|
}
|
|
async function loadDictionary() {
|
|
const response = await fetch(prefixFilename);
|
|
return await response.text();
|
|
}
|
|
const prefix = await loadDictionary();
|
|
|
|
return new PrefixCompressor(prefix, str => {
|
|
const res = new Uint8Array(LZMA.compress(str, 9));
|
|
// Clear uncompressed size as it will be invalid.
|
|
for (var i = 5; i < 13; i++) res[i] = 255;
|
|
return res;
|
|
}, arr => {
|
|
return LZMA.decompress(arr).toString();
|
|
}, 12);
|
|
}
|