zlib-1.3.1.js 5.1 KB

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