zlib-1.2.11.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. 'use strict';
  2. let ret;
  3. async function initialize() {
  4. if (ret) return ret;
  5. const COMPRESSION_LEVEL = 7;
  6. const NO_ZLIB_HEADER = -1;
  7. const CHUNK_SIZE = 32 * 1024;
  8. const map = {};
  9. const memory = new WebAssembly.Memory({
  10. initial: 1,
  11. maximum: 1024, // 64MB
  12. });
  13. const env = {
  14. memory,
  15. writeToJs(ptr, size) {
  16. const o = map[ptr];
  17. o.onData(new Uint8Array(memory.buffer, dstPtr, size));
  18. },
  19. _abort: errno => { console.error(`Error: ${errno}`) },
  20. _grow: () => { },
  21. };
  22. let ins;
  23. if (typeof fetch === 'undefined') {
  24. const buff = fs.readFileSync('zlib-1.2.11.wasm');
  25. const module = await WebAssembly.compile(buff);
  26. ins = await WebAssembly.instantiate(module, { env });
  27. } else {
  28. ins = await WebAssembly.instantiateStreaming(fetch('zlib-1.2.11.wasm'));
  29. }
  30. const srcPtr = ins.exports._malloc(CHUNK_SIZE);
  31. const dstPtr = ins.exports._malloc(CHUNK_SIZE);
  32. class RawDef {
  33. constructor() {
  34. this.zstreamPtr = ins.exports._createDeflateContext(COMPRESSION_LEVEL, NO_ZLIB_HEADER);
  35. map[this.zstreamPtr] = this;
  36. this.offset = 0;
  37. this.buff = new Uint8Array(CHUNK_SIZE);
  38. }
  39. deflate(chunk, flush) {
  40. const src = new Uint8Array(memory.buffer, srcPtr, chunk.length);
  41. src.set(chunk);
  42. ins.exports._deflate(this.zstreamPtr, srcPtr, dstPtr, chunk.length, CHUNK_SIZE, flush);
  43. }
  44. onData(chunk) {
  45. if (this.buff.length < this.offset + chunk.length) {
  46. const buff = this.buff;
  47. this.buff = new Uint8Array(this.buff.length * 2);
  48. this.buff.set(buff);
  49. }
  50. this.buff.set(chunk, this.offset);
  51. this.offset += chunk.length;
  52. }
  53. destroy() {
  54. ins.exports._freeDeflateContext(this.zstreamPtr);
  55. delete map[this.zstreamPtr];
  56. this.buff = null;
  57. }
  58. getBuffer() {
  59. const res = new Uint8Array(this.offset);
  60. for (let i = 0; i < this.offset; ++i) {
  61. res[i] = this.buff[i];
  62. }
  63. return res;
  64. }
  65. }
  66. class RawInf {
  67. constructor() {
  68. this.zstreamPtr = ins.exports._createInflateContext(NO_ZLIB_HEADER);
  69. map[this.zstreamPtr] = this;
  70. this.offset = 0;
  71. this.buff = new Uint8Array(CHUNK_SIZE);
  72. }
  73. inflate(chunk) {
  74. const src = new Uint8Array(memory.buffer, srcPtr, chunk.length);
  75. src.set(chunk);
  76. ins.exports._inflate(this.zstreamPtr, srcPtr, dstPtr, chunk.length, CHUNK_SIZE);
  77. }
  78. onData(chunk) {
  79. if (this.buff.length < this.offset + chunk.length) {
  80. const buff = this.buff;
  81. this.buff = new Uint8Array(this.buff.length * 2);
  82. this.buff.set(buff);
  83. }
  84. this.buff.set(chunk, this.offset);
  85. this.offset += chunk.length;
  86. }
  87. destroy() {
  88. ins.exports._freeInflateContext(this.zstreamPtr);
  89. delete map[this.zstreamPtr];
  90. this.buff = null;
  91. }
  92. getBuffer() {
  93. const res = new Uint8Array(this.offset);
  94. for (let i = 0; i < this.offset; ++i) {
  95. res[i] = this.buff[i];
  96. }
  97. return res;
  98. }
  99. }
  100. ret = {
  101. inflate(rawDeflateBuffer) {
  102. const rawInf = new RawInf();
  103. for (let offset = 0; offset < rawDeflateBuffer.length; offset += CHUNK_SIZE) {
  104. const end = Math.min(offset + CHUNK_SIZE, rawDeflateBuffer.length);
  105. const chunk = rawDeflateBuffer.subarray(offset, end);
  106. rawInf.inflate(chunk);
  107. }
  108. const ret = rawInf.getBuffer();
  109. rawInf.destroy();
  110. return ret;
  111. },
  112. deflate(rawInflateBuffer) {
  113. const rawDef = new RawDef();
  114. for (let offset = 0; offset < rawInflateBuffer.length; offset += CHUNK_SIZE) {
  115. const end = Math.min(offset + CHUNK_SIZE, rawInflateBuffer.length);
  116. const chunk = rawInflateBuffer.subarray(offset, end);
  117. rawDef.deflate(chunk, rawInflateBuffer.length <= offset + CHUNK_SIZE);
  118. }
  119. const ret = rawDef.getBuffer();
  120. rawDef.destroy();
  121. return ret;
  122. },
  123. }
  124. return ret;
  125. }
  126. global.zlib = initialize();